summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle McMartin <kyle@redhat.com>2011-06-17 13:23:12 -0400
committerKyle McMartin <kyle@redhat.com>2011-06-17 13:23:12 -0400
commita71a059a2042e9f0a3309883ae76dd29caeeab66 (patch)
treee6aa4ca1ac75ca33d45d82015e1ae897623ea0a6
parent7918b0cd6c5f47d393401069a9ffb72b1e021880 (diff)
downloadkernel-a71a059a2042e9f0a3309883ae76dd29caeeab66.tar.gz
kernel-a71a059a2042e9f0a3309883ae76dd29caeeab66.tar.xz
kernel-a71a059a2042e9f0a3309883ae76dd29caeeab66.zip
drop firewire patches
-rw-r--r--kernel.spec9
-rw-r--r--linux-2.6-firewire-git-pending.patch4
-rw-r--r--linux-2.6-firewire-git-update.patch3682
3 files changed, 1 insertions, 3694 deletions
diff --git a/kernel.spec b/kernel.spec
index e8310b0bd..786183845 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -670,10 +670,6 @@ Patch1827: drm-i915-gen4-has-non-power-of-two-strides.patch
Patch1900: linux-2.6-intel-iommu-igfx.patch
-# linux1394 git patches
-Patch2200: linux-2.6-firewire-git-update.patch
-Patch2201: linux-2.6-firewire-git-pending.patch
-
# Quiet boot fixes
# silence the ACPI blacklist code
Patch2802: linux-2.6-silence-acpi-blacklist.patch
@@ -1259,10 +1255,6 @@ ApplyPatch linux-2.6-intel-iommu-igfx.patch
# where intelObj->mt == NULL)
#ApplyPatch drm-i915-gen4-has-non-power-of-two-strides.patch
-# linux1394 git patches
-#ApplyPatch linux-2.6-firewire-git-update.patch
-#ApplyOptionalPatch linux-2.6-firewire-git-pending.patch
-
# silence the ACPI blacklist code
ApplyPatch linux-2.6-silence-acpi-blacklist.patch
@@ -1905,6 +1897,7 @@ fi
- linux-2.6-defaults-pci_use_crs.patch: ditto.
- linux-2.6-selinux-mprotect-checks.patch: upstream a while ago.
- drop some more unapplied crud.
+- We haven't applied firewire patches in a dogs age.
* Fri Jun 17 2011 Kyle McMartin <kmcmartin@redhat.com> 3.0-0.rc3.git5.1
- Try updating to a git snapshot for the first time in 3.0-rc,
diff --git a/linux-2.6-firewire-git-pending.patch b/linux-2.6-firewire-git-pending.patch
deleted file mode 100644
index e05471f1b..000000000
--- a/linux-2.6-firewire-git-pending.patch
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-# Patches under review and/or pending inclusion in the linux1394-git
-# tree (and/or in by the time your read this), which we want...
-#
diff --git a/linux-2.6-firewire-git-update.patch b/linux-2.6-firewire-git-update.patch
deleted file mode 100644
index 685808133..000000000
--- a/linux-2.6-firewire-git-update.patch
+++ /dev/null
@@ -1,3682 +0,0 @@
-linux1394-2.6.git tree vs. linus v2.6.29-rc3-git1 on 20090130 by jarod
-
----
- firewire-git/drivers/firewire/fw-card.c | 68 -
- firewire-git/drivers/firewire/fw-cdev.c | 1014 +++++++++++++++++--------
- firewire-git/drivers/firewire/fw-device.c | 43 -
- firewire-git/drivers/firewire/fw-device.h | 7
- firewire-git/drivers/firewire/fw-iso.c | 225 ++++-
- firewire-git/drivers/firewire/fw-ohci.c | 236 ++---
- firewire-git/drivers/firewire/fw-sbp2.c | 57 -
- firewire-git/drivers/firewire/fw-topology.c | 28
- firewire-git/drivers/firewire/fw-topology.h | 19
- firewire-git/drivers/firewire/fw-transaction.c | 151 +--
- firewire-git/drivers/firewire/fw-transaction.h | 125 ---
- include/linux/firewire-cdev.h | 170 +++-
- 12 files changed, 1359 insertions(+), 784 deletions(-)
-
-diff -Naurp linux-2.6-git/drivers/firewire/fw-card.c firewire-git/drivers/firewire/fw-card.c
---- linux-2.6-git/drivers/firewire/fw-card.c 2009-01-30 13:39:02.989651512 -0500
-+++ firewire-git/drivers/firewire/fw-card.c 2009-01-30 13:35:51.859771884 -0500
-@@ -63,8 +63,7 @@ static int descriptor_count;
- #define BIB_CMC ((1) << 30)
- #define BIB_IMC ((1) << 31)
-
--static u32 *
--generate_config_rom(struct fw_card *card, size_t *config_rom_length)
-+static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
- {
- struct fw_descriptor *desc;
- static u32 config_rom[256];
-@@ -128,8 +127,7 @@ generate_config_rom(struct fw_card *card
- return config_rom;
- }
-
--static void
--update_config_roms(void)
-+static void update_config_roms(void)
- {
- struct fw_card *card;
- u32 *config_rom;
-@@ -141,8 +139,7 @@ update_config_roms(void)
- }
- }
-
--int
--fw_core_add_descriptor(struct fw_descriptor *desc)
-+int fw_core_add_descriptor(struct fw_descriptor *desc)
- {
- size_t i;
-
-@@ -171,8 +168,7 @@ fw_core_add_descriptor(struct fw_descrip
- return 0;
- }
-
--void
--fw_core_remove_descriptor(struct fw_descriptor *desc)
-+void fw_core_remove_descriptor(struct fw_descriptor *desc)
- {
- mutex_lock(&card_mutex);
-
-@@ -189,8 +185,7 @@ static const char gap_count_table[] = {
- 63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40
- };
-
--void
--fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
-+void fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
- {
- int scheduled;
-
-@@ -200,8 +195,7 @@ fw_schedule_bm_work(struct fw_card *card
- fw_card_put(card);
- }
-
--static void
--fw_card_bm_work(struct work_struct *work)
-+static void fw_card_bm_work(struct work_struct *work)
- {
- struct fw_card *card = container_of(work, struct fw_card, work.work);
- struct fw_device *root_device;
-@@ -371,17 +365,16 @@ fw_card_bm_work(struct work_struct *work
- fw_card_put(card);
- }
-
--static void
--flush_timer_callback(unsigned long data)
-+static void flush_timer_callback(unsigned long data)
- {
- struct fw_card *card = (struct fw_card *)data;
-
- fw_flush_transactions(card);
- }
-
--void
--fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
-- struct device *device)
-+void fw_card_initialize(struct fw_card *card,
-+ const struct fw_card_driver *driver,
-+ struct device *device)
- {
- static atomic_t index = ATOMIC_INIT(-1);
-
-@@ -406,9 +399,8 @@ fw_card_initialize(struct fw_card *card,
- }
- EXPORT_SYMBOL(fw_card_initialize);
-
--int
--fw_card_add(struct fw_card *card,
-- u32 max_receive, u32 link_speed, u64 guid)
-+int fw_card_add(struct fw_card *card,
-+ u32 max_receive, u32 link_speed, u64 guid)
- {
- u32 *config_rom;
- size_t length;
-@@ -435,23 +427,20 @@ EXPORT_SYMBOL(fw_card_add);
- * dummy driver just fails all IO.
- */
-
--static int
--dummy_enable(struct fw_card *card, u32 *config_rom, size_t length)
-+static int dummy_enable(struct fw_card *card, u32 *config_rom, size_t length)
- {
- BUG();
- return -1;
- }
-
--static int
--dummy_update_phy_reg(struct fw_card *card, int address,
-- int clear_bits, int set_bits)
-+static int dummy_update_phy_reg(struct fw_card *card, int address,
-+ int clear_bits, int set_bits)
- {
- return -ENODEV;
- }
-
--static int
--dummy_set_config_rom(struct fw_card *card,
-- u32 *config_rom, size_t length)
-+static int dummy_set_config_rom(struct fw_card *card,
-+ u32 *config_rom, size_t length)
- {
- /*
- * We take the card out of card_list before setting the dummy
-@@ -461,27 +450,23 @@ dummy_set_config_rom(struct fw_card *car
- return -1;
- }
-
--static void
--dummy_send_request(struct fw_card *card, struct fw_packet *packet)
-+static void dummy_send_request(struct fw_card *card, struct fw_packet *packet)
- {
- packet->callback(packet, card, -ENODEV);
- }
-
--static void
--dummy_send_response(struct fw_card *card, struct fw_packet *packet)
-+static void dummy_send_response(struct fw_card *card, struct fw_packet *packet)
- {
- packet->callback(packet, card, -ENODEV);
- }
-
--static int
--dummy_cancel_packet(struct fw_card *card, struct fw_packet *packet)
-+static int dummy_cancel_packet(struct fw_card *card, struct fw_packet *packet)
- {
- return -ENOENT;
- }
-
--static int
--dummy_enable_phys_dma(struct fw_card *card,
-- int node_id, int generation)
-+static int dummy_enable_phys_dma(struct fw_card *card,
-+ int node_id, int generation)
- {
- return -ENODEV;
- }
-@@ -496,16 +481,14 @@ static struct fw_card_driver dummy_drive
- .enable_phys_dma = dummy_enable_phys_dma,
- };
-
--void
--fw_card_release(struct kref *kref)
-+void fw_card_release(struct kref *kref)
- {
- struct fw_card *card = container_of(kref, struct fw_card, kref);
-
- complete(&card->done);
- }
-
--void
--fw_core_remove_card(struct fw_card *card)
-+void fw_core_remove_card(struct fw_card *card)
- {
- card->driver->update_phy_reg(card, 4,
- PHY_LINK_ACTIVE | PHY_CONTENDER, 0);
-@@ -529,8 +512,7 @@ fw_core_remove_card(struct fw_card *card
- }
- EXPORT_SYMBOL(fw_core_remove_card);
-
--int
--fw_core_initiate_bus_reset(struct fw_card *card, int short_reset)
-+int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset)
- {
- int reg = short_reset ? 5 : 1;
- int bit = short_reset ? PHY_BUS_SHORT_RESET : PHY_BUS_RESET;
-diff -Naurp linux-2.6-git/drivers/firewire/fw-cdev.c firewire-git/drivers/firewire/fw-cdev.c
---- linux-2.6-git/drivers/firewire/fw-cdev.c 2008-11-04 11:19:19.000000000 -0500
-+++ firewire-git/drivers/firewire/fw-cdev.c 2009-01-30 13:35:51.860646788 -0500
-@@ -18,87 +18,162 @@
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
--#include <linux/module.h>
--#include <linux/kernel.h>
--#include <linux/wait.h>
--#include <linux/errno.h>
-+#include <linux/compat.h>
-+#include <linux/delay.h>
- #include <linux/device.h>
--#include <linux/vmalloc.h>
-+#include <linux/errno.h>
-+#include <linux/firewire-cdev.h>
-+#include <linux/idr.h>
-+#include <linux/jiffies.h>
-+#include <linux/kernel.h>
-+#include <linux/kref.h>
-+#include <linux/mm.h>
-+#include <linux/module.h>
-+#include <linux/mutex.h>
- #include <linux/poll.h>
- #include <linux/preempt.h>
-+#include <linux/spinlock.h>
- #include <linux/time.h>
--#include <linux/delay.h>
--#include <linux/mm.h>
--#include <linux/idr.h>
--#include <linux/compat.h>
--#include <linux/firewire-cdev.h>
-+#include <linux/vmalloc.h>
-+#include <linux/wait.h>
-+#include <linux/workqueue.h>
-+
- #include <asm/system.h>
- #include <asm/uaccess.h>
--#include "fw-transaction.h"
--#include "fw-topology.h"
-+
- #include "fw-device.h"
-+#include "fw-topology.h"
-+#include "fw-transaction.h"
-+
-+struct client {
-+ u32 version;
-+ struct fw_device *device;
-+
-+ spinlock_t lock;
-+ bool in_shutdown;
-+ struct idr resource_idr;
-+ struct list_head event_list;
-+ wait_queue_head_t wait;
-+ u64 bus_reset_closure;
-+
-+ struct fw_iso_context *iso_context;
-+ u64 iso_closure;
-+ struct fw_iso_buffer buffer;
-+ unsigned long vm_start;
-
--struct client;
--struct client_resource {
- struct list_head link;
-- void (*release)(struct client *client, struct client_resource *r);
-- u32 handle;
-+ struct kref kref;
-+};
-+
-+static inline void client_get(struct client *client)
-+{
-+ kref_get(&client->kref);
-+}
-+
-+static void client_release(struct kref *kref)
-+{
-+ struct client *client = container_of(kref, struct client, kref);
-+
-+ fw_device_put(client->device);
-+ kfree(client);
-+}
-+
-+static void client_put(struct client *client)
-+{
-+ kref_put(&client->kref, client_release);
-+}
-+
-+struct client_resource;
-+typedef void (*client_resource_release_fn_t)(struct client *,
-+ struct client_resource *);
-+struct client_resource {
-+ client_resource_release_fn_t release;
-+ int handle;
-+};
-+
-+struct address_handler_resource {
-+ struct client_resource resource;
-+ struct fw_address_handler handler;
-+ __u64 closure;
-+ struct client *client;
-+};
-+
-+struct outbound_transaction_resource {
-+ struct client_resource resource;
-+ struct fw_transaction transaction;
-+};
-+
-+struct inbound_transaction_resource {
-+ struct client_resource resource;
-+ struct fw_request *request;
-+ void *data;
-+ size_t length;
- };
-
-+struct descriptor_resource {
-+ struct client_resource resource;
-+ struct fw_descriptor descriptor;
-+ u32 data[0];
-+};
-+
-+struct iso_resource {
-+ struct client_resource resource;
-+ struct client *client;
-+ /* Schedule work and access todo only with client->lock held. */
-+ struct delayed_work work;
-+ enum {ISO_RES_ALLOC, ISO_RES_REALLOC, ISO_RES_DEALLOC,
-+ ISO_RES_ALLOC_ONCE, ISO_RES_DEALLOC_ONCE,} todo;
-+ int generation;
-+ u64 channels;
-+ s32 bandwidth;
-+ struct iso_resource_event *e_alloc, *e_dealloc;
-+};
-+
-+static void schedule_iso_resource(struct iso_resource *);
-+static void release_iso_resource(struct client *, struct client_resource *);
-+
- /*
- * dequeue_event() just kfree()'s the event, so the event has to be
-- * the first field in the struct.
-+ * the first field in a struct XYZ_event.
- */
--
- struct event {
- struct { void *data; size_t size; } v[2];
- struct list_head link;
- };
-
--struct bus_reset {
-+struct bus_reset_event {
- struct event event;
- struct fw_cdev_event_bus_reset reset;
- };
-
--struct response {
-+struct outbound_transaction_event {
- struct event event;
-- struct fw_transaction transaction;
- struct client *client;
-- struct client_resource resource;
-+ struct outbound_transaction_resource r;
- struct fw_cdev_event_response response;
- };
-
--struct iso_interrupt {
-+struct inbound_transaction_event {
- struct event event;
-- struct fw_cdev_event_iso_interrupt interrupt;
-+ struct fw_cdev_event_request request;
- };
-
--struct client {
-- u32 version;
-- struct fw_device *device;
-- spinlock_t lock;
-- u32 resource_handle;
-- struct list_head resource_list;
-- struct list_head event_list;
-- wait_queue_head_t wait;
-- u64 bus_reset_closure;
--
-- struct fw_iso_context *iso_context;
-- u64 iso_closure;
-- struct fw_iso_buffer buffer;
-- unsigned long vm_start;
-+struct iso_interrupt_event {
-+ struct event event;
-+ struct fw_cdev_event_iso_interrupt interrupt;
-+};
-
-- struct list_head link;
-+struct iso_resource_event {
-+ struct event event;
-+ struct fw_cdev_event_iso_resource resource;
- };
-
--static inline void __user *
--u64_to_uptr(__u64 value)
-+static inline void __user *u64_to_uptr(__u64 value)
- {
- return (void __user *)(unsigned long)value;
- }
-
--static inline __u64
--uptr_to_u64(void __user *ptr)
-+static inline __u64 uptr_to_u64(void __user *ptr)
- {
- return (__u64)(unsigned long)ptr;
- }
-@@ -107,7 +182,6 @@ static int fw_device_op_open(struct inod
- {
- struct fw_device *device;
- struct client *client;
-- unsigned long flags;
-
- device = fw_device_get_by_devt(inode->i_rdev);
- if (device == NULL)
-@@ -125,16 +199,17 @@ static int fw_device_op_open(struct inod
- }
-
- client->device = device;
-- INIT_LIST_HEAD(&client->event_list);
-- INIT_LIST_HEAD(&client->resource_list);
- spin_lock_init(&client->lock);
-+ idr_init(&client->resource_idr);
-+ INIT_LIST_HEAD(&client->event_list);
- init_waitqueue_head(&client->wait);
-+ kref_init(&client->kref);
-
- file->private_data = client;
-
-- spin_lock_irqsave(&device->card->lock, flags);
-+ mutex_lock(&device->client_list_mutex);
- list_add_tail(&client->link, &device->client_list);
-- spin_unlock_irqrestore(&device->card->lock, flags);
-+ mutex_unlock(&device->client_list_mutex);
-
- return 0;
- }
-@@ -150,68 +225,69 @@ static void queue_event(struct client *c
- event->v[1].size = size1;
-
- spin_lock_irqsave(&client->lock, flags);
-- list_add_tail(&event->link, &client->event_list);
-+ if (client->in_shutdown)
-+ kfree(event);
-+ else
-+ list_add_tail(&event->link, &client->event_list);
- spin_unlock_irqrestore(&client->lock, flags);
-
- wake_up_interruptible(&client->wait);
- }
-
--static int
--dequeue_event(struct client *client, char __user *buffer, size_t count)
-+static int dequeue_event(struct client *client,
-+ char __user *buffer, size_t count)
- {
-- unsigned long flags;
- struct event *event;
- size_t size, total;
-- int i, retval;
-+ int i, ret;
-
-- retval = wait_event_interruptible(client->wait,
-- !list_empty(&client->event_list) ||
-- fw_device_is_shutdown(client->device));
-- if (retval < 0)
-- return retval;
-+ ret = wait_event_interruptible(client->wait,
-+ !list_empty(&client->event_list) ||
-+ fw_device_is_shutdown(client->device));
-+ if (ret < 0)
-+ return ret;
-
- if (list_empty(&client->event_list) &&
- fw_device_is_shutdown(client->device))
- return -ENODEV;
-
-- spin_lock_irqsave(&client->lock, flags);
-- event = container_of(client->event_list.next, struct event, link);
-+ spin_lock_irq(&client->lock);
-+ event = list_first_entry(&client->event_list, struct event, link);
- list_del(&event->link);
-- spin_unlock_irqrestore(&client->lock, flags);
-+ spin_unlock_irq(&client->lock);
-
- total = 0;
- for (i = 0; i < ARRAY_SIZE(event->v) && total < count; i++) {
- size = min(event->v[i].size, count - total);
- if (copy_to_user(buffer + total, event->v[i].data, size)) {
-- retval = -EFAULT;
-+ ret = -EFAULT;
- goto out;
- }
- total += size;
- }
-- retval = total;
-+ ret = total;
-
- out:
- kfree(event);
-
-- return retval;
-+ return ret;
- }
-
--static ssize_t
--fw_device_op_read(struct file *file,
-- char __user *buffer, size_t count, loff_t *offset)
-+static ssize_t fw_device_op_read(struct file *file, char __user *buffer,
-+ size_t count, loff_t *offset)
- {
- struct client *client = file->private_data;
-
- return dequeue_event(client, buffer, count);
- }
-
--/* caller must hold card->lock so that node pointers can be dereferenced here */
--static void
--fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,
-- struct client *client)
-+static void fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,
-+ struct client *client)
- {
- struct fw_card *card = client->device->card;
-
-+ spin_lock_irq(&card->lock);
-+
- event->closure = client->bus_reset_closure;
- event->type = FW_CDEV_EVENT_BUS_RESET;
- event->generation = client->device->generation;
-@@ -220,39 +296,49 @@ fill_bus_reset_event(struct fw_cdev_even
- event->bm_node_id = 0; /* FIXME: We don't track the BM. */
- event->irm_node_id = card->irm_node->node_id;
- event->root_node_id = card->root_node->node_id;
-+
-+ spin_unlock_irq(&card->lock);
- }
-
--static void
--for_each_client(struct fw_device *device,
-- void (*callback)(struct client *client))
-+static void for_each_client(struct fw_device *device,
-+ void (*callback)(struct client *client))
- {
-- struct fw_card *card = device->card;
- struct client *c;
-- unsigned long flags;
--
-- spin_lock_irqsave(&card->lock, flags);
-
-+ mutex_lock(&device->client_list_mutex);
- list_for_each_entry(c, &device->client_list, link)
- callback(c);
-+ mutex_unlock(&device->client_list_mutex);
-+}
-+
-+static int schedule_reallocations(int id, void *p, void *data)
-+{
-+ struct client_resource *r = p;
-
-- spin_unlock_irqrestore(&card->lock, flags);
-+ if (r->release == release_iso_resource)
-+ schedule_iso_resource(container_of(r,
-+ struct iso_resource, resource));
-+ return 0;
- }
-
--static void
--queue_bus_reset_event(struct client *client)
-+static void queue_bus_reset_event(struct client *client)
- {
-- struct bus_reset *bus_reset;
-+ struct bus_reset_event *e;
-
-- bus_reset = kzalloc(sizeof(*bus_reset), GFP_ATOMIC);
-- if (bus_reset == NULL) {
-+ e = kzalloc(sizeof(*e), GFP_KERNEL);
-+ if (e == NULL) {
- fw_notify("Out of memory when allocating bus reset event\n");
- return;
- }
-
-- fill_bus_reset_event(&bus_reset->reset, client);
-+ fill_bus_reset_event(&e->reset, client);
-+
-+ queue_event(client, &e->event,
-+ &e->reset, sizeof(e->reset), NULL, 0);
-
-- queue_event(client, &bus_reset->event,
-- &bus_reset->reset, sizeof(bus_reset->reset), NULL, 0);
-+ spin_lock_irq(&client->lock);
-+ idr_for_each(&client->resource_idr, schedule_reallocations, client);
-+ spin_unlock_irq(&client->lock);
- }
-
- void fw_device_cdev_update(struct fw_device *device)
-@@ -274,11 +360,11 @@ static int ioctl_get_info(struct client
- {
- struct fw_cdev_get_info *get_info = buffer;
- struct fw_cdev_event_bus_reset bus_reset;
-- struct fw_card *card = client->device->card;
- unsigned long ret = 0;
-
- client->version = get_info->version;
- get_info->version = FW_CDEV_VERSION;
-+ get_info->card = client->device->card->index;
-
- down_read(&fw_device_rwsem);
-
-@@ -300,49 +386,61 @@ static int ioctl_get_info(struct client
- client->bus_reset_closure = get_info->bus_reset_closure;
- if (get_info->bus_reset != 0) {
- void __user *uptr = u64_to_uptr(get_info->bus_reset);
-- unsigned long flags;
-
-- spin_lock_irqsave(&card->lock, flags);
- fill_bus_reset_event(&bus_reset, client);
-- spin_unlock_irqrestore(&card->lock, flags);
--
- if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset)))
- return -EFAULT;
- }
-
-- get_info->card = card->index;
--
- return 0;
- }
-
--static void
--add_client_resource(struct client *client, struct client_resource *resource)
-+static int add_client_resource(struct client *client,
-+ struct client_resource *resource, gfp_t gfp_mask)
- {
- unsigned long flags;
-+ int ret;
-+
-+ retry:
-+ if (idr_pre_get(&client->resource_idr, gfp_mask | __GFP_ZERO) == 0)
-+ return -ENOMEM;
-
- spin_lock_irqsave(&client->lock, flags);
-- list_add_tail(&resource->link, &client->resource_list);
-- resource->handle = client->resource_handle++;
-+ if (client->in_shutdown)
-+ ret = -ECANCELED;
-+ else
-+ ret = idr_get_new(&client->resource_idr, resource,
-+ &resource->handle);
-+ if (ret >= 0) {
-+ client_get(client);
-+ if (resource->release == release_iso_resource)
-+ schedule_iso_resource(container_of(resource,
-+ struct iso_resource, resource));
-+ }
- spin_unlock_irqrestore(&client->lock, flags);
-+
-+ if (ret == -EAGAIN)
-+ goto retry;
-+
-+ return ret < 0 ? ret : 0;
- }
-
--static int
--release_client_resource(struct client *client, u32 handle,
-- struct client_resource **resource)
-+static int release_client_resource(struct client *client, u32 handle,
-+ client_resource_release_fn_t release,
-+ struct client_resource **resource)
- {
- struct client_resource *r;
-- unsigned long flags;
-
-- spin_lock_irqsave(&client->lock, flags);
-- list_for_each_entry(r, &client->resource_list, link) {
-- if (r->handle == handle) {
-- list_del(&r->link);
-- break;
-- }
-- }
-- spin_unlock_irqrestore(&client->lock, flags);
-+ spin_lock_irq(&client->lock);
-+ if (client->in_shutdown)
-+ r = NULL;
-+ else
-+ r = idr_find(&client->resource_idr, handle);
-+ if (r && r->release == release)
-+ idr_remove(&client->resource_idr, handle);
-+ spin_unlock_irq(&client->lock);
-
-- if (&r->link == &client->resource_list)
-+ if (!(r && r->release == release))
- return -EINVAL;
-
- if (resource)
-@@ -350,203 +448,242 @@ release_client_resource(struct client *c
- else
- r->release(client, r);
-
-+ client_put(client);
-+
- return 0;
- }
-
--static void
--release_transaction(struct client *client, struct client_resource *resource)
-+static void release_transaction(struct client *client,
-+ struct client_resource *resource)
- {
-- struct response *response =
-- container_of(resource, struct response, resource);
-+ struct outbound_transaction_resource *r = container_of(resource,
-+ struct outbound_transaction_resource, resource);
-
-- fw_cancel_transaction(client->device->card, &response->transaction);
-+ fw_cancel_transaction(client->device->card, &r->transaction);
- }
-
--static void
--complete_transaction(struct fw_card *card, int rcode,
-- void *payload, size_t length, void *data)
-+static void complete_transaction(struct fw_card *card, int rcode,
-+ void *payload, size_t length, void *data)
- {
-- struct response *response = data;
-- struct client *client = response->client;
-+ struct outbound_transaction_event *e = data;
-+ struct fw_cdev_event_response *rsp = &e->response;
-+ struct client *client = e->client;
- unsigned long flags;
-- struct fw_cdev_event_response *r = &response->response;
-
-- if (length < r->length)
-- r->length = length;
-+ if (length < rsp->length)
-+ rsp->length = length;
- if (rcode == RCODE_COMPLETE)
-- memcpy(r->data, payload, r->length);
-+ memcpy(rsp->data, payload, rsp->length);
-
- spin_lock_irqsave(&client->lock, flags);
-- list_del(&response->resource.link);
-+ /*
-+ * 1. If called while in shutdown, the idr tree must be left untouched.
-+ * The idr handle will be removed and the client reference will be
-+ * dropped later.
-+ * 2. If the call chain was release_client_resource ->
-+ * release_transaction -> complete_transaction (instead of a normal
-+ * conclusion of the transaction), i.e. if this resource was already
-+ * unregistered from the idr, the client reference will be dropped
-+ * by release_client_resource and we must not drop it here.
-+ */
-+ if (!client->in_shutdown &&
-+ idr_find(&client->resource_idr, e->r.resource.handle)) {
-+ idr_remove(&client->resource_idr, e->r.resource.handle);
-+ /* Drop the idr's reference */
-+ client_put(client);
-+ }
- spin_unlock_irqrestore(&client->lock, flags);
-
-- r->type = FW_CDEV_EVENT_RESPONSE;
-- r->rcode = rcode;
-+ rsp->type = FW_CDEV_EVENT_RESPONSE;
-+ rsp->rcode = rcode;
-
- /*
-- * In the case that sizeof(*r) doesn't align with the position of the
-+ * In the case that sizeof(*rsp) doesn't align with the position of the
- * data, and the read is short, preserve an extra copy of the data
- * to stay compatible with a pre-2.6.27 bug. Since the bug is harmless
- * for short reads and some apps depended on it, this is both safe
- * and prudent for compatibility.
- */
-- if (r->length <= sizeof(*r) - offsetof(typeof(*r), data))
-- queue_event(client, &response->event, r, sizeof(*r),
-- r->data, r->length);
-+ if (rsp->length <= sizeof(*rsp) - offsetof(typeof(*rsp), data))
-+ queue_event(client, &e->event, rsp, sizeof(*rsp),
-+ rsp->data, rsp->length);
- else
-- queue_event(client, &response->event, r, sizeof(*r) + r->length,
-+ queue_event(client, &e->event, rsp, sizeof(*rsp) + rsp->length,
- NULL, 0);
-+
-+ /* Drop the transaction callback's reference */
-+ client_put(client);
- }
-
--static int ioctl_send_request(struct client *client, void *buffer)
-+static int init_request(struct client *client,
-+ struct fw_cdev_send_request *request,
-+ int destination_id, int speed)
- {
-- struct fw_device *device = client->device;
-- struct fw_cdev_send_request *request = buffer;
-- struct response *response;
-+ struct outbound_transaction_event *e;
-+ int ret;
-
-- /* What is the biggest size we'll accept, really? */
-- if (request->length > 4096)
-- return -EINVAL;
-+ if (request->length > 4096 || request->length > 512 << speed)
-+ return -EIO;
-
-- response = kmalloc(sizeof(*response) + request->length, GFP_KERNEL);
-- if (response == NULL)
-+ e = kmalloc(sizeof(*e) + request->length, GFP_KERNEL);
-+ if (e == NULL)
- return -ENOMEM;
-
-- response->client = client;
-- response->response.length = request->length;
-- response->response.closure = request->closure;
-+ e->client = client;
-+ e->response.length = request->length;
-+ e->response.closure = request->closure;
-
- if (request->data &&
-- copy_from_user(response->response.data,
-+ copy_from_user(e->response.data,
- u64_to_uptr(request->data), request->length)) {
-- kfree(response);
-- return -EFAULT;
-+ ret = -EFAULT;
-+ goto failed;
- }
-
-- response->resource.release = release_transaction;
-- add_client_resource(client, &response->resource);
--
-- fw_send_request(device->card, &response->transaction,
-- request->tcode & 0x1f,
-- device->node->node_id,
-- request->generation,
-- device->max_speed,
-- request->offset,
-- response->response.data, request->length,
-- complete_transaction, response);
-+ e->r.resource.release = release_transaction;
-+ ret = add_client_resource(client, &e->r.resource, GFP_KERNEL);
-+ if (ret < 0)
-+ goto failed;
-+
-+ /* Get a reference for the transaction callback */
-+ client_get(client);
-+
-+ fw_send_request(client->device->card, &e->r.transaction,
-+ request->tcode & 0x1f, destination_id,
-+ request->generation, speed, request->offset,
-+ e->response.data, request->length,
-+ complete_transaction, e);
-
- if (request->data)
- return sizeof(request) + request->length;
- else
- return sizeof(request);
-+ failed:
-+ kfree(e);
-+
-+ return ret;
- }
-
--struct address_handler {
-- struct fw_address_handler handler;
-- __u64 closure;
-- struct client *client;
-- struct client_resource resource;
--};
-+static int ioctl_send_request(struct client *client, void *buffer)
-+{
-+ struct fw_cdev_send_request *request = buffer;
-
--struct request {
-- struct fw_request *request;
-- void *data;
-- size_t length;
-- struct client_resource resource;
--};
-+ switch (request->tcode) {
-+ case TCODE_WRITE_QUADLET_REQUEST:
-+ case TCODE_WRITE_BLOCK_REQUEST:
-+ case TCODE_READ_QUADLET_REQUEST:
-+ case TCODE_READ_BLOCK_REQUEST:
-+ case TCODE_LOCK_MASK_SWAP:
-+ case TCODE_LOCK_COMPARE_SWAP:
-+ case TCODE_LOCK_FETCH_ADD:
-+ case TCODE_LOCK_LITTLE_ADD:
-+ case TCODE_LOCK_BOUNDED_ADD:
-+ case TCODE_LOCK_WRAP_ADD:
-+ case TCODE_LOCK_VENDOR_DEPENDENT:
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-
--struct request_event {
-- struct event event;
-- struct fw_cdev_event_request request;
--};
-+ return init_request(client, request, client->device->node->node_id,
-+ client->device->max_speed);
-+}
-
--static void
--release_request(struct client *client, struct client_resource *resource)
-+static void release_request(struct client *client,
-+ struct client_resource *resource)
- {
-- struct request *request =
-- container_of(resource, struct request, resource);
-+ struct inbound_transaction_resource *r = container_of(resource,
-+ struct inbound_transaction_resource, resource);
-
-- fw_send_response(client->device->card, request->request,
-+ fw_send_response(client->device->card, r->request,
- RCODE_CONFLICT_ERROR);
-- kfree(request);
-+ kfree(r);
- }
-
--static void
--handle_request(struct fw_card *card, struct fw_request *r,
-- int tcode, int destination, int source,
-- int generation, int speed,
-- unsigned long long offset,
-- void *payload, size_t length, void *callback_data)
--{
-- struct address_handler *handler = callback_data;
-- struct request *request;
-- struct request_event *e;
-- struct client *client = handler->client;
-+static void handle_request(struct fw_card *card, struct fw_request *request,
-+ int tcode, int destination, int source,
-+ int generation, int speed,
-+ unsigned long long offset,
-+ void *payload, size_t length, void *callback_data)
-+{
-+ struct address_handler_resource *handler = callback_data;
-+ struct inbound_transaction_resource *r;
-+ struct inbound_transaction_event *e;
-+ int ret;
-
-- request = kmalloc(sizeof(*request), GFP_ATOMIC);
-+ r = kmalloc(sizeof(*r), GFP_ATOMIC);
- e = kmalloc(sizeof(*e), GFP_ATOMIC);
-- if (request == NULL || e == NULL) {
-- kfree(request);
-- kfree(e);
-- fw_send_response(card, r, RCODE_CONFLICT_ERROR);
-- return;
-- }
--
-- request->request = r;
-- request->data = payload;
-- request->length = length;
-+ if (r == NULL || e == NULL)
-+ goto failed;
-
-- request->resource.release = release_request;
-- add_client_resource(client, &request->resource);
-+ r->request = request;
-+ r->data = payload;
-+ r->length = length;
-+
-+ r->resource.release = release_request;
-+ ret = add_client_resource(handler->client, &r->resource, GFP_ATOMIC);
-+ if (ret < 0)
-+ goto failed;
-
- e->request.type = FW_CDEV_EVENT_REQUEST;
- e->request.tcode = tcode;
- e->request.offset = offset;
- e->request.length = length;
-- e->request.handle = request->resource.handle;
-+ e->request.handle = r->resource.handle;
- e->request.closure = handler->closure;
-
-- queue_event(client, &e->event,
-+ queue_event(handler->client, &e->event,
- &e->request, sizeof(e->request), payload, length);
-+ return;
-+
-+ failed:
-+ kfree(r);
-+ kfree(e);
-+ fw_send_response(card, request, RCODE_CONFLICT_ERROR);
- }
-
--static void
--release_address_handler(struct client *client,
-- struct client_resource *resource)
-+static void release_address_handler(struct client *client,
-+ struct client_resource *resource)
- {
-- struct address_handler *handler =
-- container_of(resource, struct address_handler, resource);
-+ struct address_handler_resource *r =
-+ container_of(resource, struct address_handler_resource, resource);
-
-- fw_core_remove_address_handler(&handler->handler);
-- kfree(handler);
-+ fw_core_remove_address_handler(&r->handler);
-+ kfree(r);
- }
-
- static int ioctl_allocate(struct client *client, void *buffer)
- {
- struct fw_cdev_allocate *request = buffer;
-- struct address_handler *handler;
-+ struct address_handler_resource *r;
- struct fw_address_region region;
-+ int ret;
-
-- handler = kmalloc(sizeof(*handler), GFP_KERNEL);
-- if (handler == NULL)
-+ r = kmalloc(sizeof(*r), GFP_KERNEL);
-+ if (r == NULL)
- return -ENOMEM;
-
- region.start = request->offset;
- region.end = request->offset + request->length;
-- handler->handler.length = request->length;
-- handler->handler.address_callback = handle_request;
-- handler->handler.callback_data = handler;
-- handler->closure = request->closure;
-- handler->client = client;
--
-- if (fw_core_add_address_handler(&handler->handler, &region) < 0) {
-- kfree(handler);
-- return -EBUSY;
-+ r->handler.length = request->length;
-+ r->handler.address_callback = handle_request;
-+ r->handler.callback_data = r;
-+ r->closure = request->closure;
-+ r->client = client;
-+
-+ ret = fw_core_add_address_handler(&r->handler, &region);
-+ if (ret < 0) {
-+ kfree(r);
-+ return ret;
- }
-
-- handler->resource.release = release_address_handler;
-- add_client_resource(client, &handler->resource);
-- request->handle = handler->resource.handle;
-+ r->resource.release = release_address_handler;
-+ ret = add_client_resource(client, &r->resource, GFP_KERNEL);
-+ if (ret < 0) {
-+ release_address_handler(client, &r->resource);
-+ return ret;
-+ }
-+ request->handle = r->resource.handle;
-
- return 0;
- }
-@@ -555,18 +692,22 @@ static int ioctl_deallocate(struct clien
- {
- struct fw_cdev_deallocate *request = buffer;
-
-- return release_client_resource(client, request->handle, NULL);
-+ return release_client_resource(client, request->handle,
-+ release_address_handler, NULL);
- }
-
- static int ioctl_send_response(struct client *client, void *buffer)
- {
- struct fw_cdev_send_response *request = buffer;
- struct client_resource *resource;
-- struct request *r;
-+ struct inbound_transaction_resource *r;
-
-- if (release_client_resource(client, request->handle, &resource) < 0)
-+ if (release_client_resource(client, request->handle,
-+ release_request, &resource) < 0)
- return -EINVAL;
-- r = container_of(resource, struct request, resource);
-+
-+ r = container_of(resource, struct inbound_transaction_resource,
-+ resource);
- if (request->length < r->length)
- r->length = request->length;
- if (copy_from_user(r->data, u64_to_uptr(request->data), r->length))
-@@ -588,85 +729,84 @@ static int ioctl_initiate_bus_reset(stru
- return fw_core_initiate_bus_reset(client->device->card, short_reset);
- }
-
--struct descriptor {
-- struct fw_descriptor d;
-- struct client_resource resource;
-- u32 data[0];
--};
--
- static void release_descriptor(struct client *client,
- struct client_resource *resource)
- {
-- struct descriptor *descriptor =
-- container_of(resource, struct descriptor, resource);
-+ struct descriptor_resource *r =
-+ container_of(resource, struct descriptor_resource, resource);
-
-- fw_core_remove_descriptor(&descriptor->d);
-- kfree(descriptor);
-+ fw_core_remove_descriptor(&r->descriptor);
-+ kfree(r);
- }
-
- static int ioctl_add_descriptor(struct client *client, void *buffer)
- {
- struct fw_cdev_add_descriptor *request = buffer;
-- struct descriptor *descriptor;
-- int retval;
-+ struct descriptor_resource *r;
-+ int ret;
-
- if (request->length > 256)
- return -EINVAL;
-
-- descriptor =
-- kmalloc(sizeof(*descriptor) + request->length * 4, GFP_KERNEL);
-- if (descriptor == NULL)
-+ r = kmalloc(sizeof(*r) + request->length * 4, GFP_KERNEL);
-+ if (r == NULL)
- return -ENOMEM;
-
-- if (copy_from_user(descriptor->data,
-+ if (copy_from_user(r->data,
- u64_to_uptr(request->data), request->length * 4)) {
-- kfree(descriptor);
-- return -EFAULT;
-+ ret = -EFAULT;
-+ goto failed;
- }
-
-- descriptor->d.length = request->length;
-- descriptor->d.immediate = request->immediate;
-- descriptor->d.key = request->key;
-- descriptor->d.data = descriptor->data;
--
-- retval = fw_core_add_descriptor(&descriptor->d);
-- if (retval < 0) {
-- kfree(descriptor);
-- return retval;
-+ r->descriptor.length = request->length;
-+ r->descriptor.immediate = request->immediate;
-+ r->descriptor.key = request->key;
-+ r->descriptor.data = r->data;
-+
-+ ret = fw_core_add_descriptor(&r->descriptor);
-+ if (ret < 0)
-+ goto failed;
-+
-+ r->resource.release = release_descriptor;
-+ ret = add_client_resource(client, &r->resource, GFP_KERNEL);
-+ if (ret < 0) {
-+ fw_core_remove_descriptor(&r->descriptor);
-+ goto failed;
- }
--
-- descriptor->resource.release = release_descriptor;
-- add_client_resource(client, &descriptor->resource);
-- request->handle = descriptor->resource.handle;
-+ request->handle = r->resource.handle;
-
- return 0;
-+ failed:
-+ kfree(r);
-+
-+ return ret;
- }
-
- static int ioctl_remove_descriptor(struct client *client, void *buffer)
- {
- struct fw_cdev_remove_descriptor *request = buffer;
-
-- return release_client_resource(client, request->handle, NULL);
-+ return release_client_resource(client, request->handle,
-+ release_descriptor, NULL);
- }
-
--static void
--iso_callback(struct fw_iso_context *context, u32 cycle,
-- size_t header_length, void *header, void *data)
-+static void iso_callback(struct fw_iso_context *context, u32 cycle,
-+ size_t header_length, void *header, void *data)
- {
- struct client *client = data;
-- struct iso_interrupt *irq;
-+ struct iso_interrupt_event *e;
-
-- irq = kzalloc(sizeof(*irq) + header_length, GFP_ATOMIC);
-- if (irq == NULL)
-+ e = kzalloc(sizeof(*e) + header_length, GFP_ATOMIC);
-+ if (e == NULL)
- return;
-
-- irq->interrupt.type = FW_CDEV_EVENT_ISO_INTERRUPT;
-- irq->interrupt.closure = client->iso_closure;
-- irq->interrupt.cycle = cycle;
-- irq->interrupt.header_length = header_length;
-- memcpy(irq->interrupt.header, header, header_length);
-- queue_event(client, &irq->event, &irq->interrupt,
-- sizeof(irq->interrupt) + header_length, NULL, 0);
-+ e->interrupt.type = FW_CDEV_EVENT_ISO_INTERRUPT;
-+ e->interrupt.closure = client->iso_closure;
-+ e->interrupt.cycle = cycle;
-+ e->interrupt.header_length = header_length;
-+ memcpy(e->interrupt.header, header, header_length);
-+ queue_event(client, &e->event, &e->interrupt,
-+ sizeof(e->interrupt) + header_length, NULL, 0);
- }
-
- static int ioctl_create_iso_context(struct client *client, void *buffer)
-@@ -871,6 +1011,237 @@ static int ioctl_get_cycle_timer(struct
- return 0;
- }
-
-+static void iso_resource_work(struct work_struct *work)
-+{
-+ struct iso_resource_event *e;
-+ struct iso_resource *r =
-+ container_of(work, struct iso_resource, work.work);
-+ struct client *client = r->client;
-+ int generation, channel, bandwidth, todo;
-+ bool skip, free, success;
-+
-+ spin_lock_irq(&client->lock);
-+ generation = client->device->generation;
-+ todo = r->todo;
-+ /* Allow 1000ms grace period for other reallocations. */
-+ if (todo == ISO_RES_ALLOC &&
-+ time_is_after_jiffies(client->device->card->reset_jiffies + HZ)) {
-+ if (schedule_delayed_work(&r->work, DIV_ROUND_UP(HZ, 3)))
-+ client_get(client);
-+ skip = true;
-+ } else {
-+ /* We could be called twice within the same generation. */
-+ skip = todo == ISO_RES_REALLOC &&
-+ r->generation == generation;
-+ }
-+ free = todo == ISO_RES_DEALLOC ||
-+ todo == ISO_RES_ALLOC_ONCE ||
-+ todo == ISO_RES_DEALLOC_ONCE;
-+ r->generation = generation;
-+ spin_unlock_irq(&client->lock);
-+
-+ if (skip)
-+ goto out;
-+
-+ bandwidth = r->bandwidth;
-+
-+ fw_iso_resource_manage(client->device->card, generation,
-+ r->channels, &channel, &bandwidth,
-+ todo == ISO_RES_ALLOC ||
-+ todo == ISO_RES_REALLOC ||
-+ todo == ISO_RES_ALLOC_ONCE);
-+ /*
-+ * Is this generation outdated already? As long as this resource sticks
-+ * in the idr, it will be scheduled again for a newer generation or at
-+ * shutdown.
-+ */
-+ if (channel == -EAGAIN &&
-+ (todo == ISO_RES_ALLOC || todo == ISO_RES_REALLOC))
-+ goto out;
-+
-+ success = channel >= 0 || bandwidth > 0;
-+
-+ spin_lock_irq(&client->lock);
-+ /*
-+ * Transit from allocation to reallocation, except if the client
-+ * requested deallocation in the meantime.
-+ */
-+ if (r->todo == ISO_RES_ALLOC)
-+ r->todo = ISO_RES_REALLOC;
-+ /*
-+ * Allocation or reallocation failure? Pull this resource out of the
-+ * idr and prepare for deletion, unless the client is shutting down.
-+ */
-+ if (r->todo == ISO_RES_REALLOC && !success &&
-+ !client->in_shutdown &&
-+ idr_find(&client->resource_idr, r->resource.handle)) {
-+ idr_remove(&client->resource_idr, r->resource.handle);
-+ client_put(client);
-+ free = true;
-+ }
-+ spin_unlock_irq(&client->lock);
-+
-+ if (todo == ISO_RES_ALLOC && channel >= 0)
-+ r->channels = 1ULL << channel;
-+
-+ if (todo == ISO_RES_REALLOC && success)
-+ goto out;
-+
-+ if (todo == ISO_RES_ALLOC || todo == ISO_RES_ALLOC_ONCE) {
-+ e = r->e_alloc;
-+ r->e_alloc = NULL;
-+ } else {
-+ e = r->e_dealloc;
-+ r->e_dealloc = NULL;
-+ }
-+ e->resource.handle = r->resource.handle;
-+ e->resource.channel = channel;
-+ e->resource.bandwidth = bandwidth;
-+
-+ queue_event(client, &e->event,
-+ &e->resource, sizeof(e->resource), NULL, 0);
-+
-+ if (free) {
-+ cancel_delayed_work(&r->work);
-+ kfree(r->e_alloc);
-+ kfree(r->e_dealloc);
-+ kfree(r);
-+ }
-+ out:
-+ client_put(client);
-+}
-+
-+static void schedule_iso_resource(struct iso_resource *r)
-+{
-+ client_get(r->client);
-+ if (!schedule_delayed_work(&r->work, 0))
-+ client_put(r->client);
-+}
-+
-+static void release_iso_resource(struct client *client,
-+ struct client_resource *resource)
-+{
-+ struct iso_resource *r =
-+ container_of(resource, struct iso_resource, resource);
-+
-+ spin_lock_irq(&client->lock);
-+ r->todo = ISO_RES_DEALLOC;
-+ schedule_iso_resource(r);
-+ spin_unlock_irq(&client->lock);
-+}
-+
-+static int init_iso_resource(struct client *client,
-+ struct fw_cdev_allocate_iso_resource *request, int todo)
-+{
-+ struct iso_resource_event *e1, *e2;
-+ struct iso_resource *r;
-+ int ret;
-+
-+ if ((request->channels == 0 && request->bandwidth == 0) ||
-+ request->bandwidth > BANDWIDTH_AVAILABLE_INITIAL ||
-+ request->bandwidth < 0)
-+ return -EINVAL;
-+
-+ r = kmalloc(sizeof(*r), GFP_KERNEL);
-+ e1 = kmalloc(sizeof(*e1), GFP_KERNEL);
-+ e2 = kmalloc(sizeof(*e2), GFP_KERNEL);
-+ if (r == NULL || e1 == NULL || e2 == NULL) {
-+ ret = -ENOMEM;
-+ goto fail;
-+ }
-+
-+ INIT_DELAYED_WORK(&r->work, iso_resource_work);
-+ r->client = client;
-+ r->todo = todo;
-+ r->generation = -1;
-+ r->channels = request->channels;
-+ r->bandwidth = request->bandwidth;
-+ r->e_alloc = e1;
-+ r->e_dealloc = e2;
-+
-+ e1->resource.closure = request->closure;
-+ e1->resource.type = FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED;
-+ e2->resource.closure = request->closure;
-+ e2->resource.type = FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED;
-+
-+ if (todo == ISO_RES_ALLOC) {
-+ r->resource.release = release_iso_resource;
-+ ret = add_client_resource(client, &r->resource, GFP_KERNEL);
-+ if (ret < 0)
-+ goto fail;
-+ } else {
-+ r->resource.release = NULL;
-+ r->resource.handle = -1;
-+ schedule_iso_resource(r);
-+ }
-+ request->handle = r->resource.handle;
-+
-+ return 0;
-+ fail:
-+ kfree(r);
-+ kfree(e1);
-+ kfree(e2);
-+
-+ return ret;
-+}
-+
-+static int ioctl_allocate_iso_resource(struct client *client, void *buffer)
-+{
-+ struct fw_cdev_allocate_iso_resource *request = buffer;
-+
-+ return init_iso_resource(client, request, ISO_RES_ALLOC);
-+}
-+
-+static int ioctl_deallocate_iso_resource(struct client *client, void *buffer)
-+{
-+ struct fw_cdev_deallocate *request = buffer;
-+
-+ return release_client_resource(client, request->handle,
-+ release_iso_resource, NULL);
-+}
-+
-+static int ioctl_allocate_iso_resource_once(struct client *client, void *buffer)
-+{
-+ struct fw_cdev_allocate_iso_resource *request = buffer;
-+
-+ return init_iso_resource(client, request, ISO_RES_ALLOC_ONCE);
-+}
-+
-+static int ioctl_deallocate_iso_resource_once(struct client *client, void *buffer)
-+{
-+ struct fw_cdev_allocate_iso_resource *request = buffer;
-+
-+ return init_iso_resource(client, request, ISO_RES_DEALLOC_ONCE);
-+}
-+
-+static int ioctl_get_speed(struct client *client, void *buffer)
-+{
-+ struct fw_cdev_get_speed *request = buffer;
-+
-+ request->max_speed = client->device->max_speed;
-+
-+ return 0;
-+}
-+
-+static int ioctl_send_broadcast_request(struct client *client, void *buffer)
-+{
-+ struct fw_cdev_send_request *request = buffer;
-+
-+ switch (request->tcode) {
-+ case TCODE_WRITE_QUADLET_REQUEST:
-+ case TCODE_WRITE_BLOCK_REQUEST:
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ /* Security policy: Only allow accesses to Units Space. */
-+ if (request->offset < CSR_REGISTER_BASE + CSR_CONFIG_ROM_END)
-+ return -EACCES;
-+
-+ return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100);
-+}
-+
- static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
- ioctl_get_info,
- ioctl_send_request,
-@@ -885,13 +1256,19 @@ static int (* const ioctl_handlers[])(st
- ioctl_start_iso,
- ioctl_stop_iso,
- ioctl_get_cycle_timer,
-+ ioctl_allocate_iso_resource,
-+ ioctl_deallocate_iso_resource,
-+ ioctl_allocate_iso_resource_once,
-+ ioctl_deallocate_iso_resource_once,
-+ ioctl_get_speed,
-+ ioctl_send_broadcast_request,
- };
-
--static int
--dispatch_ioctl(struct client *client, unsigned int cmd, void __user *arg)
-+static int dispatch_ioctl(struct client *client,
-+ unsigned int cmd, void __user *arg)
- {
- char buffer[256];
-- int retval;
-+ int ret;
-
- if (_IOC_TYPE(cmd) != '#' ||
- _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers))
-@@ -903,9 +1280,9 @@ dispatch_ioctl(struct client *client, un
- return -EFAULT;
- }
-
-- retval = ioctl_handlers[_IOC_NR(cmd)](client, buffer);
-- if (retval < 0)
-- return retval;
-+ ret = ioctl_handlers[_IOC_NR(cmd)](client, buffer);
-+ if (ret < 0)
-+ return ret;
-
- if (_IOC_DIR(cmd) & _IOC_READ) {
- if (_IOC_SIZE(cmd) > sizeof(buffer) ||
-@@ -913,12 +1290,11 @@ dispatch_ioctl(struct client *client, un
- return -EFAULT;
- }
-
-- return retval;
-+ return ret;
- }
-
--static long
--fw_device_op_ioctl(struct file *file,
-- unsigned int cmd, unsigned long arg)
-+static long fw_device_op_ioctl(struct file *file,
-+ unsigned int cmd, unsigned long arg)
- {
- struct client *client = file->private_data;
-
-@@ -929,9 +1305,8 @@ fw_device_op_ioctl(struct file *file,
- }
-
- #ifdef CONFIG_COMPAT
--static long
--fw_device_op_compat_ioctl(struct file *file,
-- unsigned int cmd, unsigned long arg)
-+static long fw_device_op_compat_ioctl(struct file *file,
-+ unsigned int cmd, unsigned long arg)
- {
- struct client *client = file->private_data;
-
-@@ -947,7 +1322,7 @@ static int fw_device_op_mmap(struct file
- struct client *client = file->private_data;
- enum dma_data_direction direction;
- unsigned long size;
-- int page_count, retval;
-+ int page_count, ret;
-
- if (fw_device_is_shutdown(client->device))
- return -ENODEV;
-@@ -973,48 +1348,57 @@ static int fw_device_op_mmap(struct file
- else
- direction = DMA_FROM_DEVICE;
-
-- retval = fw_iso_buffer_init(&client->buffer, client->device->card,
-- page_count, direction);
-- if (retval < 0)
-- return retval;
-+ ret = fw_iso_buffer_init(&client->buffer, client->device->card,
-+ page_count, direction);
-+ if (ret < 0)
-+ return ret;
-
-- retval = fw_iso_buffer_map(&client->buffer, vma);
-- if (retval < 0)
-+ ret = fw_iso_buffer_map(&client->buffer, vma);
-+ if (ret < 0)
- fw_iso_buffer_destroy(&client->buffer, client->device->card);
-
-- return retval;
-+ return ret;
-+}
-+
-+static int shutdown_resource(int id, void *p, void *data)
-+{
-+ struct client_resource *r = p;
-+ struct client *client = data;
-+
-+ r->release(client, r);
-+ client_put(client);
-+
-+ return 0;
- }
-
- static int fw_device_op_release(struct inode *inode, struct file *file)
- {
- struct client *client = file->private_data;
- struct event *e, *next_e;
-- struct client_resource *r, *next_r;
-- unsigned long flags;
-
-- if (client->buffer.pages)
-- fw_iso_buffer_destroy(&client->buffer, client->device->card);
-+ mutex_lock(&client->device->client_list_mutex);
-+ list_del(&client->link);
-+ mutex_unlock(&client->device->client_list_mutex);
-
- if (client->iso_context)
- fw_iso_context_destroy(client->iso_context);
-
-- list_for_each_entry_safe(r, next_r, &client->resource_list, link)
-- r->release(client, r);
-+ if (client->buffer.pages)
-+ fw_iso_buffer_destroy(&client->buffer, client->device->card);
-
-- /*
-- * FIXME: We should wait for the async tasklets to stop
-- * running before freeing the memory.
-- */
-+ /* Freeze client->resource_idr and client->event_list */
-+ spin_lock_irq(&client->lock);
-+ client->in_shutdown = true;
-+ spin_unlock_irq(&client->lock);
-+
-+ idr_for_each(&client->resource_idr, shutdown_resource, client);
-+ idr_remove_all(&client->resource_idr);
-+ idr_destroy(&client->resource_idr);
-
- list_for_each_entry_safe(e, next_e, &client->event_list, link)
- kfree(e);
-
-- spin_lock_irqsave(&client->device->card->lock, flags);
-- list_del(&client->link);
-- spin_unlock_irqrestore(&client->device->card->lock, flags);
--
-- fw_device_put(client->device);
-- kfree(client);
-+ client_put(client);
-
- return 0;
- }
-diff -Naurp linux-2.6-git/drivers/firewire/fw-device.c firewire-git/drivers/firewire/fw-device.c
---- linux-2.6-git/drivers/firewire/fw-device.c 2009-01-30 13:39:02.989651512 -0500
-+++ firewire-git/drivers/firewire/fw-device.c 2009-01-30 13:35:51.860646788 -0500
-@@ -27,8 +27,10 @@
- #include <linux/idr.h>
- #include <linux/jiffies.h>
- #include <linux/string.h>
-+#include <linux/mutex.h>
- #include <linux/rwsem.h>
- #include <linux/semaphore.h>
-+#include <linux/spinlock.h>
- #include <asm/system.h>
- #include <linux/ctype.h>
- #include "fw-transaction.h"
-@@ -132,8 +134,7 @@ static int get_modalias(struct fw_unit *
- vendor, model, specifier_id, version);
- }
-
--static int
--fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
-+static int fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
- {
- struct fw_unit *unit = fw_unit(dev);
- char modalias[64];
-@@ -191,8 +192,8 @@ struct config_rom_attribute {
- u32 key;
- };
-
--static ssize_t
--show_immediate(struct device *dev, struct device_attribute *dattr, char *buf)
-+static ssize_t show_immediate(struct device *dev,
-+ struct device_attribute *dattr, char *buf)
- {
- struct config_rom_attribute *attr =
- container_of(dattr, struct config_rom_attribute, attr);
-@@ -223,8 +224,8 @@ show_immediate(struct device *dev, struc
- #define IMMEDIATE_ATTR(name, key) \
- { __ATTR(name, S_IRUGO, show_immediate, NULL), key }
-
--static ssize_t
--show_text_leaf(struct device *dev, struct device_attribute *dattr, char *buf)
-+static ssize_t show_text_leaf(struct device *dev,
-+ struct device_attribute *dattr, char *buf)
- {
- struct config_rom_attribute *attr =
- container_of(dattr, struct config_rom_attribute, attr);
-@@ -293,10 +294,9 @@ static struct config_rom_attribute confi
- TEXT_LEAF_ATTR(hardware_version_name, CSR_HARDWARE_VERSION),
- };
-
--static void
--init_fw_attribute_group(struct device *dev,
-- struct device_attribute *attrs,
-- struct fw_attribute_group *group)
-+static void init_fw_attribute_group(struct device *dev,
-+ struct device_attribute *attrs,
-+ struct fw_attribute_group *group)
- {
- struct device_attribute *attr;
- int i, j;
-@@ -319,9 +319,8 @@ init_fw_attribute_group(struct device *d
- dev->groups = group->groups;
- }
-
--static ssize_t
--modalias_show(struct device *dev,
-- struct device_attribute *attr, char *buf)
-+static ssize_t modalias_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
- {
- struct fw_unit *unit = fw_unit(dev);
- int length;
-@@ -332,9 +331,8 @@ modalias_show(struct device *dev,
- return length + 1;
- }
-
--static ssize_t
--rom_index_show(struct device *dev,
-- struct device_attribute *attr, char *buf)
-+static ssize_t rom_index_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
- {
- struct fw_device *device = fw_device(dev->parent);
- struct fw_unit *unit = fw_unit(dev);
-@@ -349,8 +347,8 @@ static struct device_attribute fw_unit_a
- __ATTR_NULL,
- };
-
--static ssize_t
--config_rom_show(struct device *dev, struct device_attribute *attr, char *buf)
-+static ssize_t config_rom_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
- {
- struct fw_device *device = fw_device(dev);
- size_t length;
-@@ -363,8 +361,8 @@ config_rom_show(struct device *dev, stru
- return length;
- }
-
--static ssize_t
--guid_show(struct device *dev, struct device_attribute *attr, char *buf)
-+static ssize_t guid_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
- {
- struct fw_device *device = fw_device(dev);
- int ret;
-@@ -383,8 +381,8 @@ static struct device_attribute fw_device
- __ATTR_NULL,
- };
-
--static int
--read_rom(struct fw_device *device, int generation, int index, u32 *data)
-+static int read_rom(struct fw_device *device,
-+ int generation, int index, u32 *data)
- {
- int rcode;
-
-@@ -1004,6 +1002,7 @@ void fw_node_event(struct fw_card *card,
- device->node = fw_node_get(node);
- device->node_id = node->node_id;
- device->generation = card->generation;
-+ mutex_init(&device->client_list_mutex);
- INIT_LIST_HEAD(&device->client_list);
-
- /*
-diff -Naurp linux-2.6-git/drivers/firewire/fw-device.h firewire-git/drivers/firewire/fw-device.h
---- linux-2.6-git/drivers/firewire/fw-device.h 2009-01-30 13:39:02.989651512 -0500
-+++ firewire-git/drivers/firewire/fw-device.h 2009-01-30 13:35:51.860646788 -0500
-@@ -23,6 +23,7 @@
- #include <linux/cdev.h>
- #include <linux/idr.h>
- #include <linux/rwsem.h>
-+#include <linux/mutex.h>
- #include <asm/atomic.h>
-
- enum fw_device_state {
-@@ -64,7 +65,10 @@ struct fw_device {
- bool cmc;
- struct fw_card *card;
- struct device device;
-+
-+ struct mutex client_list_mutex;
- struct list_head client_list;
-+
- u32 *config_rom;
- size_t config_rom_length;
- int config_rom_retries;
-@@ -176,8 +180,7 @@ struct fw_driver {
- const struct fw_device_id *id_table;
- };
-
--static inline struct fw_driver *
--fw_driver(struct device_driver *drv)
-+static inline struct fw_driver *fw_driver(struct device_driver *drv)
- {
- return container_of(drv, struct fw_driver, driver);
- }
-diff -Naurp linux-2.6-git/drivers/firewire/fw-iso.c firewire-git/drivers/firewire/fw-iso.c
---- linux-2.6-git/drivers/firewire/fw-iso.c 2008-11-04 11:18:33.000000000 -0500
-+++ firewire-git/drivers/firewire/fw-iso.c 2009-01-30 13:35:51.860646788 -0500
-@@ -1,5 +1,7 @@
- /*
-- * Isochronous IO functionality
-+ * Isochronous I/O functionality:
-+ * - Isochronous DMA context management
-+ * - Isochronous bus resource management (channels, bandwidth), client side
- *
- * Copyright (C) 2006 Kristian Hoegsberg <krh@bitplanet.net>
- *
-@@ -18,21 +20,25 @@
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
--#include <linux/kernel.h>
--#include <linux/module.h>
- #include <linux/dma-mapping.h>
--#include <linux/vmalloc.h>
-+#include <linux/errno.h>
-+#include <linux/firewire-constants.h>
-+#include <linux/kernel.h>
- #include <linux/mm.h>
-+#include <linux/spinlock.h>
-+#include <linux/vmalloc.h>
-
--#include "fw-transaction.h"
- #include "fw-topology.h"
--#include "fw-device.h"
-+#include "fw-transaction.h"
-
--int
--fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card,
-- int page_count, enum dma_data_direction direction)
-+/*
-+ * Isochronous DMA context management
-+ */
-+
-+int fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card,
-+ int page_count, enum dma_data_direction direction)
- {
-- int i, j, retval = -ENOMEM;
-+ int i, j;
- dma_addr_t address;
-
- buffer->page_count = page_count;
-@@ -69,19 +75,19 @@ fw_iso_buffer_init(struct fw_iso_buffer
- kfree(buffer->pages);
- out:
- buffer->pages = NULL;
-- return retval;
-+ return -ENOMEM;
- }
-
- int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma)
- {
- unsigned long uaddr;
-- int i, retval;
-+ int i, ret;
-
- uaddr = vma->vm_start;
- for (i = 0; i < buffer->page_count; i++) {
-- retval = vm_insert_page(vma, uaddr, buffer->pages[i]);
-- if (retval)
-- return retval;
-+ ret = vm_insert_page(vma, uaddr, buffer->pages[i]);
-+ if (ret)
-+ return ret;
- uaddr += PAGE_SIZE;
- }
-
-@@ -105,14 +111,14 @@ void fw_iso_buffer_destroy(struct fw_iso
- buffer->pages = NULL;
- }
-
--struct fw_iso_context *
--fw_iso_context_create(struct fw_card *card, int type,
-- int channel, int speed, size_t header_size,
-- fw_iso_callback_t callback, void *callback_data)
-+struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
-+ int type, int channel, int speed, size_t header_size,
-+ fw_iso_callback_t callback, void *callback_data)
- {
- struct fw_iso_context *ctx;
-
-- ctx = card->driver->allocate_iso_context(card, type, header_size);
-+ ctx = card->driver->allocate_iso_context(card,
-+ type, channel, header_size);
- if (IS_ERR(ctx))
- return ctx;
-
-@@ -134,25 +140,186 @@ void fw_iso_context_destroy(struct fw_is
- card->driver->free_iso_context(ctx);
- }
-
--int
--fw_iso_context_start(struct fw_iso_context *ctx, int cycle, int sync, int tags)
-+int fw_iso_context_start(struct fw_iso_context *ctx,
-+ int cycle, int sync, int tags)
- {
- return ctx->card->driver->start_iso(ctx, cycle, sync, tags);
- }
-
--int
--fw_iso_context_queue(struct fw_iso_context *ctx,
-- struct fw_iso_packet *packet,
-- struct fw_iso_buffer *buffer,
-- unsigned long payload)
-+int fw_iso_context_queue(struct fw_iso_context *ctx,
-+ struct fw_iso_packet *packet,
-+ struct fw_iso_buffer *buffer,
-+ unsigned long payload)
- {
- struct fw_card *card = ctx->card;
-
- return card->driver->queue_iso(ctx, packet, buffer, payload);
- }
-
--int
--fw_iso_context_stop(struct fw_iso_context *ctx)
-+int fw_iso_context_stop(struct fw_iso_context *ctx)
- {
- return ctx->card->driver->stop_iso(ctx);
- }
-+
-+/*
-+ * Isochronous bus resource management (channels, bandwidth), client side
-+ */
-+
-+static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
-+ int bandwidth, bool allocate)
-+{
-+ __be32 data[2];
-+ int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0;
-+
-+ /*
-+ * On a 1394a IRM with low contention, try < 1 is enough.
-+ * On a 1394-1995 IRM, we need at least try < 2.
-+ * Let's just do try < 5.
-+ */
-+ for (try = 0; try < 5; try++) {
-+ new = allocate ? old - bandwidth : old + bandwidth;
-+ if (new < 0 || new > BANDWIDTH_AVAILABLE_INITIAL)
-+ break;
-+
-+ data[0] = cpu_to_be32(old);
-+ data[1] = cpu_to_be32(new);
-+ switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
-+ irm_id, generation, SCODE_100,
-+ CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE,
-+ data, sizeof(data))) {
-+ case RCODE_GENERATION:
-+ /* A generation change frees all bandwidth. */
-+ return allocate ? -EAGAIN : bandwidth;
-+
-+ case RCODE_COMPLETE:
-+ if (be32_to_cpup(data) == old)
-+ return bandwidth;
-+
-+ old = be32_to_cpup(data);
-+ /* Fall through. */
-+ }
-+ }
-+
-+ return -EIO;
-+}
-+
-+static int manage_channel(struct fw_card *card, int irm_id, int generation,
-+ u32 channels_mask, u64 offset, bool allocate)
-+{
-+ __be32 data[2], c, all, old;
-+ int i, retry = 5;
-+
-+ old = all = allocate ? cpu_to_be32(~0) : 0;
-+
-+ for (i = 0; i < 32; i++) {
-+ if (!(channels_mask & 1 << i))
-+ continue;
-+
-+ c = cpu_to_be32(1 << (31 - i));
-+ if ((old & c) != (all & c))
-+ continue;
-+
-+ data[0] = old;
-+ data[1] = old ^ c;
-+ switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
-+ irm_id, generation, SCODE_100,
-+ offset, data, sizeof(data))) {
-+ case RCODE_GENERATION:
-+ /* A generation change frees all channels. */
-+ return allocate ? -EAGAIN : i;
-+
-+ case RCODE_COMPLETE:
-+ if (data[0] == old)
-+ return i;
-+
-+ old = data[0];
-+
-+ /* Is the IRM 1394a-2000 compliant? */
-+ if ((data[0] & c) == (data[1] & c))
-+ continue;
-+
-+ /* 1394-1995 IRM, fall through to retry. */
-+ default:
-+ if (retry--)
-+ i--;
-+ }
-+ }
-+
-+ return -EIO;
-+}
-+
-+static void deallocate_channel(struct fw_card *card, int irm_id,
-+ int generation, int channel)
-+{
-+ u32 mask;
-+ u64 offset;
-+
-+ mask = channel < 32 ? 1 << channel : 1 << (channel - 32);
-+ offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI :
-+ CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO;
-+
-+ manage_channel(card, irm_id, generation, mask, offset, false);
-+}
-+
-+/**
-+ * fw_iso_resource_manage - Allocate or deallocate a channel and/or bandwidth
-+ *
-+ * In parameters: card, generation, channels_mask, bandwidth, allocate
-+ * Out parameters: channel, bandwidth
-+ * This function blocks (sleeps) during communication with the IRM.
-+ *
-+ * Allocates or deallocates at most one channel out of channels_mask.
-+ * channels_mask is a bitfield with MSB for channel 63 and LSB for channel 0.
-+ * (Note, the IRM's CHANNELS_AVAILABLE is a big-endian bitfield with MSB for
-+ * channel 0 and LSB for channel 63.)
-+ * Allocates or deallocates as many bandwidth allocation units as specified.
-+ *
-+ * Returns channel < 0 if no channel was allocated or deallocated.
-+ * Returns bandwidth = 0 if no bandwidth was allocated or deallocated.
-+ *
-+ * If generation is stale, deallocations succeed but allocations fail with
-+ * channel = -EAGAIN.
-+ *
-+ * If channel allocation fails, no bandwidth will be allocated either.
-+ * If bandwidth allocation fails, no channel will be allocated either.
-+ * But deallocations of channel and bandwidth are tried independently
-+ * of each other's success.
-+ */
-+void fw_iso_resource_manage(struct fw_card *card, int generation,
-+ u64 channels_mask, int *channel, int *bandwidth,
-+ bool allocate)
-+{
-+ u32 channels_hi = channels_mask; /* channels 31...0 */
-+ u32 channels_lo = channels_mask >> 32; /* channels 63...32 */
-+ int irm_id, ret, c = -EINVAL;
-+
-+ spin_lock_irq(&card->lock);
-+ irm_id = card->irm_node->node_id;
-+ spin_unlock_irq(&card->lock);
-+
-+ if (channels_hi)
-+ c = manage_channel(card, irm_id, generation, channels_hi,
-+ CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, allocate);
-+ if (channels_lo && c < 0) {
-+ c = manage_channel(card, irm_id, generation, channels_lo,
-+ CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, allocate);
-+ if (c >= 0)
-+ c += 32;
-+ }
-+ *channel = c;
-+
-+ if (allocate && channels_mask != 0 && c < 0)
-+ *bandwidth = 0;
-+
-+ if (*bandwidth == 0)
-+ return;
-+
-+ ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate);
-+ if (ret < 0)
-+ *bandwidth = 0;
-+
-+ if (allocate && ret < 0 && c >= 0) {
-+ deallocate_channel(card, irm_id, generation, c);
-+ *channel = ret;
-+ }
-+}
-diff -Naurp linux-2.6-git/drivers/firewire/fw-ohci.c firewire-git/drivers/firewire/fw-ohci.c
---- linux-2.6-git/drivers/firewire/fw-ohci.c 2009-01-30 13:39:02.990772025 -0500
-+++ firewire-git/drivers/firewire/fw-ohci.c 2009-01-30 13:35:51.861646907 -0500
-@@ -205,6 +205,7 @@ struct fw_ohci {
-
- u32 it_context_mask;
- struct iso_context *it_context_list;
-+ u64 ir_context_channels;
- u32 ir_context_mask;
- struct iso_context *ir_context_list;
- };
-@@ -441,9 +442,8 @@ static inline void flush_writes(const st
- reg_read(ohci, OHCI1394_Version);
- }
-
--static int
--ohci_update_phy_reg(struct fw_card *card, int addr,
-- int clear_bits, int set_bits)
-+static int ohci_update_phy_reg(struct fw_card *card, int addr,
-+ int clear_bits, int set_bits)
- {
- struct fw_ohci *ohci = fw_ohci(card);
- u32 val, old;
-@@ -658,8 +658,8 @@ static void ar_context_tasklet(unsigned
- }
- }
-
--static int
--ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, u32 regs)
-+static int ar_context_init(struct ar_context *ctx,
-+ struct fw_ohci *ohci, u32 regs)
- {
- struct ar_buffer ab;
-
-@@ -690,8 +690,7 @@ static void ar_context_run(struct ar_con
- flush_writes(ctx->ohci);
- }
-
--static struct descriptor *
--find_branch_descriptor(struct descriptor *d, int z)
-+static struct descriptor *find_branch_descriptor(struct descriptor *d, int z)
- {
- int b, key;
-
-@@ -751,8 +750,7 @@ static void context_tasklet(unsigned lon
- * Allocate a new buffer and add it to the list of free buffers for this
- * context. Must be called with ohci->lock held.
- */
--static int
--context_add_buffer(struct context *ctx)
-+static int context_add_buffer(struct context *ctx)
- {
- struct descriptor_buffer *desc;
- dma_addr_t uninitialized_var(bus_addr);
-@@ -781,9 +779,8 @@ context_add_buffer(struct context *ctx)
- return 0;
- }
-
--static int
--context_init(struct context *ctx, struct fw_ohci *ohci,
-- u32 regs, descriptor_callback_t callback)
-+static int context_init(struct context *ctx, struct fw_ohci *ohci,
-+ u32 regs, descriptor_callback_t callback)
- {
- ctx->ohci = ohci;
- ctx->regs = regs;
-@@ -814,8 +811,7 @@ context_init(struct context *ctx, struct
- return 0;
- }
-
--static void
--context_release(struct context *ctx)
-+static void context_release(struct context *ctx)
- {
- struct fw_card *card = &ctx->ohci->card;
- struct descriptor_buffer *desc, *tmp;
-@@ -827,8 +823,8 @@ context_release(struct context *ctx)
- }
-
- /* Must be called with ohci->lock held */
--static struct descriptor *
--context_get_descriptors(struct context *ctx, int z, dma_addr_t *d_bus)
-+static struct descriptor *context_get_descriptors(struct context *ctx,
-+ int z, dma_addr_t *d_bus)
- {
- struct descriptor *d = NULL;
- struct descriptor_buffer *desc = ctx->buffer_tail;
-@@ -912,8 +908,8 @@ struct driver_data {
- * Must always be called with the ochi->lock held to ensure proper
- * generation handling and locking around packet queue manipulation.
- */
--static int
--at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
-+static int at_context_queue_packet(struct context *ctx,
-+ struct fw_packet *packet)
- {
- struct fw_ohci *ohci = ctx->ohci;
- dma_addr_t d_bus, uninitialized_var(payload_bus);
-@@ -1095,8 +1091,8 @@ static int handle_at_packet(struct conte
- #define HEADER_GET_DATA_LENGTH(q) (((q) >> 16) & 0xffff)
- #define HEADER_GET_EXTENDED_TCODE(q) (((q) >> 0) & 0xffff)
-
--static void
--handle_local_rom(struct fw_ohci *ohci, struct fw_packet *packet, u32 csr)
-+static void handle_local_rom(struct fw_ohci *ohci,
-+ struct fw_packet *packet, u32 csr)
- {
- struct fw_packet response;
- int tcode, length, i;
-@@ -1122,8 +1118,8 @@ handle_local_rom(struct fw_ohci *ohci, s
- fw_core_handle_response(&ohci->card, &response);
- }
-
--static void
--handle_local_lock(struct fw_ohci *ohci, struct fw_packet *packet, u32 csr)
-+static void handle_local_lock(struct fw_ohci *ohci,
-+ struct fw_packet *packet, u32 csr)
- {
- struct fw_packet response;
- int tcode, length, ext_tcode, sel;
-@@ -1164,8 +1160,7 @@ handle_local_lock(struct fw_ohci *ohci,
- fw_core_handle_response(&ohci->card, &response);
- }
-
--static void
--handle_local_request(struct context *ctx, struct fw_packet *packet)
-+static void handle_local_request(struct context *ctx, struct fw_packet *packet)
- {
- u64 offset;
- u32 csr;
-@@ -1205,11 +1200,10 @@ handle_local_request(struct context *ctx
- }
- }
-
--static void
--at_context_transmit(struct context *ctx, struct fw_packet *packet)
-+static void at_context_transmit(struct context *ctx, struct fw_packet *packet)
- {
- unsigned long flags;
-- int retval;
-+ int ret;
-
- spin_lock_irqsave(&ctx->ohci->lock, flags);
-
-@@ -1220,10 +1214,10 @@ at_context_transmit(struct context *ctx,
- return;
- }
-
-- retval = at_context_queue_packet(ctx, packet);
-+ ret = at_context_queue_packet(ctx, packet);
- spin_unlock_irqrestore(&ctx->ohci->lock, flags);
-
-- if (retval < 0)
-+ if (ret < 0)
- packet->callback(packet, &ctx->ohci->card, packet->ack);
-
- }
-@@ -1590,12 +1584,12 @@ static int ohci_enable(struct fw_card *c
- return 0;
- }
-
--static int
--ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length)
-+static int ohci_set_config_rom(struct fw_card *card,
-+ u32 *config_rom, size_t length)
- {
- struct fw_ohci *ohci;
- unsigned long flags;
-- int retval = -EBUSY;
-+ int ret = -EBUSY;
- __be32 *next_config_rom;
- dma_addr_t uninitialized_var(next_config_rom_bus);
-
-@@ -1649,7 +1643,7 @@ ohci_set_config_rom(struct fw_card *card
-
- reg_write(ohci, OHCI1394_ConfigROMmap,
- ohci->next_config_rom_bus);
-- retval = 0;
-+ ret = 0;
- }
-
- spin_unlock_irqrestore(&ohci->lock, flags);
-@@ -1661,13 +1655,13 @@ ohci_set_config_rom(struct fw_card *card
- * controller could need to access it before the bus reset
- * takes effect.
- */
-- if (retval == 0)
-+ if (ret == 0)
- fw_core_initiate_bus_reset(&ohci->card, 1);
- else
- dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
- next_config_rom, next_config_rom_bus);
-
-- return retval;
-+ return ret;
- }
-
- static void ohci_send_request(struct fw_card *card, struct fw_packet *packet)
-@@ -1689,7 +1683,7 @@ static int ohci_cancel_packet(struct fw_
- struct fw_ohci *ohci = fw_ohci(card);
- struct context *ctx = &ohci->at_request_ctx;
- struct driver_data *driver_data = packet->driver_data;
-- int retval = -ENOENT;
-+ int ret = -ENOENT;
-
- tasklet_disable(&ctx->tasklet);
-
-@@ -1704,23 +1698,22 @@ static int ohci_cancel_packet(struct fw_
- driver_data->packet = NULL;
- packet->ack = RCODE_CANCELLED;
- packet->callback(packet, &ohci->card, packet->ack);
-- retval = 0;
--
-+ ret = 0;
- out:
- tasklet_enable(&ctx->tasklet);
-
-- return retval;
-+ return ret;
- }
-
--static int
--ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
-+static int ohci_enable_phys_dma(struct fw_card *card,
-+ int node_id, int generation)
- {
- #ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA
- return 0;
- #else
- struct fw_ohci *ohci = fw_ohci(card);
- unsigned long flags;
-- int n, retval = 0;
-+ int n, ret = 0;
-
- /*
- * FIXME: Make sure this bitmask is cleared when we clear the busReset
-@@ -1730,7 +1723,7 @@ ohci_enable_phys_dma(struct fw_card *car
- spin_lock_irqsave(&ohci->lock, flags);
-
- if (ohci->generation != generation) {
-- retval = -ESTALE;
-+ ret = -ESTALE;
- goto out;
- }
-
-@@ -1748,12 +1741,12 @@ ohci_enable_phys_dma(struct fw_card *car
- flush_writes(ohci);
- out:
- spin_unlock_irqrestore(&ohci->lock, flags);
-- return retval;
-+
-+ return ret;
- #endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */
- }
-
--static u64
--ohci_get_bus_time(struct fw_card *card)
-+static u64 ohci_get_bus_time(struct fw_card *card)
- {
- struct fw_ohci *ohci = fw_ohci(card);
- u32 cycle_time;
-@@ -1765,6 +1758,28 @@ ohci_get_bus_time(struct fw_card *card)
- return bus_time;
- }
-
-+static void copy_iso_headers(struct iso_context *ctx, void *p)
-+{
-+ int i = ctx->header_length;
-+
-+ if (i + ctx->base.header_size > PAGE_SIZE)
-+ return;
-+
-+ /*
-+ * The iso header is byteswapped to little endian by
-+ * the controller, but the remaining header quadlets
-+ * are big endian. We want to present all the headers
-+ * as big endian, so we have to swap the first quadlet.
-+ */
-+ if (ctx->base.header_size > 0)
-+ *(u32 *) (ctx->header + i) = __swab32(*(u32 *) (p + 4));
-+ if (ctx->base.header_size > 4)
-+ *(u32 *) (ctx->header + i + 4) = __swab32(*(u32 *) p);
-+ if (ctx->base.header_size > 8)
-+ memcpy(ctx->header + i + 8, p + 8, ctx->base.header_size - 8);
-+ ctx->header_length += ctx->base.header_size;
-+}
-+
- static int handle_ir_dualbuffer_packet(struct context *context,
- struct descriptor *d,
- struct descriptor *last)
-@@ -1775,7 +1790,6 @@ static int handle_ir_dualbuffer_packet(s
- __le32 *ir_header;
- size_t header_length;
- void *p, *end;
-- int i;
-
- if (db->first_res_count != 0 && db->second_res_count != 0) {
- if (ctx->excess_bytes <= le16_to_cpu(db->second_req_count)) {
-@@ -1788,25 +1802,14 @@ static int handle_ir_dualbuffer_packet(s
- header_length = le16_to_cpu(db->first_req_count) -
- le16_to_cpu(db->first_res_count);
-
-- i = ctx->header_length;
- p = db + 1;
- end = p + header_length;
-- while (p < end && i + ctx->base.header_size <= PAGE_SIZE) {
-- /*
-- * The iso header is byteswapped to little endian by
-- * the controller, but the remaining header quadlets
-- * are big endian. We want to present all the headers
-- * as big endian, so we have to swap the first
-- * quadlet.
-- */
-- *(u32 *) (ctx->header + i) = __swab32(*(u32 *) (p + 4));
-- memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
-- i += ctx->base.header_size;
-+ while (p < end) {
-+ copy_iso_headers(ctx, p);
- ctx->excess_bytes +=
- (le32_to_cpu(*(__le32 *)(p + 4)) >> 16) & 0xffff;
-- p += ctx->base.header_size + 4;
-+ p += max(ctx->base.header_size, (size_t)8);
- }
-- ctx->header_length = i;
-
- ctx->excess_bytes -= le16_to_cpu(db->second_req_count) -
- le16_to_cpu(db->second_res_count);
-@@ -1832,7 +1835,6 @@ static int handle_ir_packet_per_buffer(s
- struct descriptor *pd;
- __le32 *ir_header;
- void *p;
-- int i;
-
- for (pd = d; pd <= last; pd++) {
- if (pd->transfer_status)
-@@ -1842,21 +1844,8 @@ static int handle_ir_packet_per_buffer(s
- /* Descriptor(s) not done yet, stop iteration */
- return 0;
-
-- i = ctx->header_length;
-- p = last + 1;
--
-- if (ctx->base.header_size > 0 &&
-- i + ctx->base.header_size <= PAGE_SIZE) {
-- /*
-- * The iso header is byteswapped to little endian by
-- * the controller, but the remaining header quadlets
-- * are big endian. We want to present all the headers
-- * as big endian, so we have to swap the first quadlet.
-- */
-- *(u32 *) (ctx->header + i) = __swab32(*(u32 *) (p + 4));
-- memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
-- ctx->header_length += ctx->base.header_size;
-- }
-+ p = last + 1;
-+ copy_iso_headers(ctx, p);
-
- if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) {
- ir_header = (__le32 *) p;
-@@ -1888,21 +1877,24 @@ static int handle_it_packet(struct conte
- return 1;
- }
-
--static struct fw_iso_context *
--ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size)
-+static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
-+ int type, int channel, size_t header_size)
- {
- struct fw_ohci *ohci = fw_ohci(card);
- struct iso_context *ctx, *list;
- descriptor_callback_t callback;
-+ u64 *channels, dont_care = ~0ULL;
- u32 *mask, regs;
- unsigned long flags;
-- int index, retval = -ENOMEM;
-+ int index, ret = -ENOMEM;
-
- if (type == FW_ISO_CONTEXT_TRANSMIT) {
-+ channels = &dont_care;
- mask = &ohci->it_context_mask;
- list = ohci->it_context_list;
- callback = handle_it_packet;
- } else {
-+ channels = &ohci->ir_context_channels;
- mask = &ohci->ir_context_mask;
- list = ohci->ir_context_list;
- if (ohci->use_dualbuffer)
-@@ -1912,9 +1904,11 @@ ohci_allocate_iso_context(struct fw_card
- }
-
- spin_lock_irqsave(&ohci->lock, flags);
-- index = ffs(*mask) - 1;
-- if (index >= 0)
-+ index = *channels & 1ULL << channel ? ffs(*mask) - 1 : -1;
-+ if (index >= 0) {
-+ *channels &= ~(1ULL << channel);
- *mask &= ~(1 << index);
-+ }
- spin_unlock_irqrestore(&ohci->lock, flags);
-
- if (index < 0)
-@@ -1932,8 +1926,8 @@ ohci_allocate_iso_context(struct fw_card
- if (ctx->header == NULL)
- goto out;
-
-- retval = context_init(&ctx->context, ohci, regs, callback);
-- if (retval < 0)
-+ ret = context_init(&ctx->context, ohci, regs, callback);
-+ if (ret < 0)
- goto out_with_header;
-
- return &ctx->base;
-@@ -1945,7 +1939,7 @@ ohci_allocate_iso_context(struct fw_card
- *mask |= 1 << index;
- spin_unlock_irqrestore(&ohci->lock, flags);
-
-- return ERR_PTR(retval);
-+ return ERR_PTR(ret);
- }
-
- static int ohci_start_iso(struct fw_iso_context *base,
-@@ -2024,16 +2018,16 @@ static void ohci_free_iso_context(struct
- } else {
- index = ctx - ohci->ir_context_list;
- ohci->ir_context_mask |= 1 << index;
-+ ohci->ir_context_channels |= 1ULL << base->channel;
- }
-
- spin_unlock_irqrestore(&ohci->lock, flags);
- }
-
--static int
--ohci_queue_iso_transmit(struct fw_iso_context *base,
-- struct fw_iso_packet *packet,
-- struct fw_iso_buffer *buffer,
-- unsigned long payload)
-+static int ohci_queue_iso_transmit(struct fw_iso_context *base,
-+ struct fw_iso_packet *packet,
-+ struct fw_iso_buffer *buffer,
-+ unsigned long payload)
- {
- struct iso_context *ctx = container_of(base, struct iso_context, base);
- struct descriptor *d, *last, *pd;
-@@ -2128,11 +2122,10 @@ ohci_queue_iso_transmit(struct fw_iso_co
- return 0;
- }
-
--static int
--ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
-- struct fw_iso_packet *packet,
-- struct fw_iso_buffer *buffer,
-- unsigned long payload)
-+static int ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
-+ struct fw_iso_packet *packet,
-+ struct fw_iso_buffer *buffer,
-+ unsigned long payload)
- {
- struct iso_context *ctx = container_of(base, struct iso_context, base);
- struct db_descriptor *db = NULL;
-@@ -2151,11 +2144,11 @@ ohci_queue_iso_receive_dualbuffer(struct
- z = 2;
-
- /*
-- * The OHCI controller puts the status word in the header
-- * buffer too, so we need 4 extra bytes per packet.
-+ * The OHCI controller puts the isochronous header and trailer in the
-+ * buffer, so we need at least 8 bytes.
- */
- packet_count = p->header_length / ctx->base.header_size;
-- header_size = packet_count * (ctx->base.header_size + 4);
-+ header_size = packet_count * max(ctx->base.header_size, (size_t)8);
-
- /* Get header size in number of descriptors. */
- header_z = DIV_ROUND_UP(header_size, sizeof(*d));
-@@ -2173,7 +2166,8 @@ ohci_queue_iso_receive_dualbuffer(struct
- db = (struct db_descriptor *) d;
- db->control = cpu_to_le16(DESCRIPTOR_STATUS |
- DESCRIPTOR_BRANCH_ALWAYS);
-- db->first_size = cpu_to_le16(ctx->base.header_size + 4);
-+ db->first_size =
-+ cpu_to_le16(max(ctx->base.header_size, (size_t)8));
- if (p->skip && rest == p->payload_length) {
- db->control |= cpu_to_le16(DESCRIPTOR_WAIT);
- db->first_req_count = db->first_size;
-@@ -2208,11 +2202,10 @@ ohci_queue_iso_receive_dualbuffer(struct
- return 0;
- }
-
--static int
--ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base,
-- struct fw_iso_packet *packet,
-- struct fw_iso_buffer *buffer,
-- unsigned long payload)
-+static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base,
-+ struct fw_iso_packet *packet,
-+ struct fw_iso_buffer *buffer,
-+ unsigned long payload)
- {
- struct iso_context *ctx = container_of(base, struct iso_context, base);
- struct descriptor *d = NULL, *pd = NULL;
-@@ -2223,11 +2216,11 @@ ohci_queue_iso_receive_packet_per_buffer
- int page, offset, packet_count, header_size, payload_per_buffer;
-
- /*
-- * The OHCI controller puts the status word in the
-- * buffer too, so we need 4 extra bytes per packet.
-+ * The OHCI controller puts the isochronous header and trailer in the
-+ * buffer, so we need at least 8 bytes.
- */
- packet_count = p->header_length / ctx->base.header_size;
-- header_size = ctx->base.header_size + 4;
-+ header_size = max(ctx->base.header_size, (size_t)8);
-
- /* Get header size in number of descriptors. */
- header_z = DIV_ROUND_UP(header_size, sizeof(*d));
-@@ -2286,29 +2279,27 @@ ohci_queue_iso_receive_packet_per_buffer
- return 0;
- }
-
--static int
--ohci_queue_iso(struct fw_iso_context *base,
-- struct fw_iso_packet *packet,
-- struct fw_iso_buffer *buffer,
-- unsigned long payload)
-+static int ohci_queue_iso(struct fw_iso_context *base,
-+ struct fw_iso_packet *packet,
-+ struct fw_iso_buffer *buffer,
-+ unsigned long payload)
- {
- struct iso_context *ctx = container_of(base, struct iso_context, base);
- unsigned long flags;
-- int retval;
-+ int ret;
-
- spin_lock_irqsave(&ctx->context.ohci->lock, flags);
- if (base->type == FW_ISO_CONTEXT_TRANSMIT)
-- retval = ohci_queue_iso_transmit(base, packet, buffer, payload);
-+ ret = ohci_queue_iso_transmit(base, packet, buffer, payload);
- else if (ctx->context.ohci->use_dualbuffer)
-- retval = ohci_queue_iso_receive_dualbuffer(base, packet,
-- buffer, payload);
-+ ret = ohci_queue_iso_receive_dualbuffer(base, packet,
-+ buffer, payload);
- else
-- retval = ohci_queue_iso_receive_packet_per_buffer(base, packet,
-- buffer,
-- payload);
-+ ret = ohci_queue_iso_receive_packet_per_buffer(base, packet,
-+ buffer, payload);
- spin_unlock_irqrestore(&ctx->context.ohci->lock, flags);
-
-- return retval;
-+ return ret;
- }
-
- static const struct fw_card_driver ohci_driver = {
-@@ -2357,8 +2348,8 @@ static void ohci_pmac_off(struct pci_dev
- #define ohci_pmac_off(dev)
- #endif /* CONFIG_PPC_PMAC */
-
--static int __devinit
--pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
-+static int __devinit pci_probe(struct pci_dev *dev,
-+ const struct pci_device_id *ent)
- {
- struct fw_ohci *ohci;
- u32 bus_options, max_receive, link_speed, version;
-@@ -2440,6 +2431,7 @@ pci_probe(struct pci_dev *dev, const str
- ohci->it_context_list = kzalloc(size, GFP_KERNEL);
-
- reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0);
-+ ohci->ir_context_channels = ~0ULL;
- ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet);
- reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0);
- size = sizeof(struct iso_context) * hweight32(ohci->ir_context_mask);
-diff -Naurp linux-2.6-git/drivers/firewire/fw-sbp2.c firewire-git/drivers/firewire/fw-sbp2.c
---- linux-2.6-git/drivers/firewire/fw-sbp2.c 2009-01-30 13:39:02.991771976 -0500
-+++ firewire-git/drivers/firewire/fw-sbp2.c 2009-01-30 13:35:51.861646907 -0500
-@@ -392,20 +392,18 @@ static const struct {
- }
- };
-
--static void
--free_orb(struct kref *kref)
-+static void free_orb(struct kref *kref)
- {
- struct sbp2_orb *orb = container_of(kref, struct sbp2_orb, kref);
-
- kfree(orb);
- }
-
--static void
--sbp2_status_write(struct fw_card *card, struct fw_request *request,
-- int tcode, int destination, int source,
-- int generation, int speed,
-- unsigned long long offset,
-- void *payload, size_t length, void *callback_data)
-+static void sbp2_status_write(struct fw_card *card, struct fw_request *request,
-+ int tcode, int destination, int source,
-+ int generation, int speed,
-+ unsigned long long offset,
-+ void *payload, size_t length, void *callback_data)
- {
- struct sbp2_logical_unit *lu = callback_data;
- struct sbp2_orb *orb;
-@@ -451,9 +449,8 @@ sbp2_status_write(struct fw_card *card,
- fw_send_response(card, request, RCODE_COMPLETE);
- }
-
--static void
--complete_transaction(struct fw_card *card, int rcode,
-- void *payload, size_t length, void *data)
-+static void complete_transaction(struct fw_card *card, int rcode,
-+ void *payload, size_t length, void *data)
- {
- struct sbp2_orb *orb = data;
- unsigned long flags;
-@@ -482,9 +479,8 @@ complete_transaction(struct fw_card *car
- kref_put(&orb->kref, free_orb);
- }
-
--static void
--sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
-- int node_id, int generation, u64 offset)
-+static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
-+ int node_id, int generation, u64 offset)
- {
- struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
- unsigned long flags;
-@@ -531,8 +527,8 @@ static int sbp2_cancel_orbs(struct sbp2_
- return retval;
- }
-
--static void
--complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
-+static void complete_management_orb(struct sbp2_orb *base_orb,
-+ struct sbp2_status *status)
- {
- struct sbp2_management_orb *orb =
- container_of(base_orb, struct sbp2_management_orb, base);
-@@ -542,10 +538,9 @@ complete_management_orb(struct sbp2_orb
- complete(&orb->done);
- }
-
--static int
--sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
-- int generation, int function, int lun_or_login_id,
-- void *response)
-+static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
-+ int generation, int function,
-+ int lun_or_login_id, void *response)
- {
- struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
- struct sbp2_management_orb *orb;
-@@ -652,9 +647,8 @@ static void sbp2_agent_reset(struct sbp2
- &d, sizeof(d));
- }
-
--static void
--complete_agent_reset_write_no_wait(struct fw_card *card, int rcode,
-- void *payload, size_t length, void *data)
-+static void complete_agent_reset_write_no_wait(struct fw_card *card,
-+ int rcode, void *payload, size_t length, void *data)
- {
- kfree(data);
- }
-@@ -1299,8 +1293,7 @@ static void sbp2_unmap_scatterlist(struc
- sizeof(orb->page_table), DMA_TO_DEVICE);
- }
-
--static unsigned int
--sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data)
-+static unsigned int sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data)
- {
- int sam_status;
-
-@@ -1337,8 +1330,8 @@ sbp2_status_to_sense_data(u8 *sbp2_statu
- }
- }
-
--static void
--complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
-+static void complete_command_orb(struct sbp2_orb *base_orb,
-+ struct sbp2_status *status)
- {
- struct sbp2_command_orb *orb =
- container_of(base_orb, struct sbp2_command_orb, base);
-@@ -1384,9 +1377,8 @@ complete_command_orb(struct sbp2_orb *ba
- orb->done(orb->cmd);
- }
-
--static int
--sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
-- struct sbp2_logical_unit *lu)
-+static int sbp2_map_scatterlist(struct sbp2_command_orb *orb,
-+ struct fw_device *device, struct sbp2_logical_unit *lu)
- {
- struct scatterlist *sg = scsi_sglist(orb->cmd);
- int i, n;
-@@ -1584,9 +1576,8 @@ static int sbp2_scsi_abort(struct scsi_c
- * This is the concatenation of target port identifier and logical unit
- * identifier as per SAM-2...SAM-4 annex A.
- */
--static ssize_t
--sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr,
-- char *buf)
-+static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
- {
- struct scsi_device *sdev = to_scsi_device(dev);
- struct sbp2_logical_unit *lu;
-diff -Naurp linux-2.6-git/drivers/firewire/fw-topology.c firewire-git/drivers/firewire/fw-topology.c
---- linux-2.6-git/drivers/firewire/fw-topology.c 2009-01-30 13:39:02.991771976 -0500
-+++ firewire-git/drivers/firewire/fw-topology.c 2009-01-30 13:35:51.862647087 -0500
-@@ -314,9 +314,8 @@ typedef void (*fw_node_callback_t)(struc
- struct fw_node * node,
- struct fw_node * parent);
-
--static void
--for_each_fw_node(struct fw_card *card, struct fw_node *root,
-- fw_node_callback_t callback)
-+static void for_each_fw_node(struct fw_card *card, struct fw_node *root,
-+ fw_node_callback_t callback)
- {
- struct list_head list;
- struct fw_node *node, *next, *child, *parent;
-@@ -349,9 +348,8 @@ for_each_fw_node(struct fw_card *card, s
- fw_node_put(node);
- }
-
--static void
--report_lost_node(struct fw_card *card,
-- struct fw_node *node, struct fw_node *parent)
-+static void report_lost_node(struct fw_card *card,
-+ struct fw_node *node, struct fw_node *parent)
- {
- fw_node_event(card, node, FW_NODE_DESTROYED);
- fw_node_put(node);
-@@ -360,9 +358,8 @@ report_lost_node(struct fw_card *card,
- card->bm_retries = 0;
- }
-
--static void
--report_found_node(struct fw_card *card,
-- struct fw_node *node, struct fw_node *parent)
-+static void report_found_node(struct fw_card *card,
-+ struct fw_node *node, struct fw_node *parent)
- {
- int b_path = (node->phy_speed == SCODE_BETA);
-
-@@ -415,8 +412,7 @@ static void move_tree(struct fw_node *no
- * found, lost or updated. Update the nodes in the card topology tree
- * as we go.
- */
--static void
--update_tree(struct fw_card *card, struct fw_node *root)
-+static void update_tree(struct fw_card *card, struct fw_node *root)
- {
- struct list_head list0, list1;
- struct fw_node *node0, *node1, *next1;
-@@ -497,8 +493,8 @@ update_tree(struct fw_card *card, struct
- }
- }
-
--static void
--update_topology_map(struct fw_card *card, u32 *self_ids, int self_id_count)
-+static void update_topology_map(struct fw_card *card,
-+ u32 *self_ids, int self_id_count)
- {
- int node_count;
-
-@@ -510,10 +506,8 @@ update_topology_map(struct fw_card *card
- fw_compute_block_crc(card->topology_map);
- }
-
--void
--fw_core_handle_bus_reset(struct fw_card *card,
-- int node_id, int generation,
-- int self_id_count, u32 * self_ids)
-+void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation,
-+ int self_id_count, u32 *self_ids)
- {
- struct fw_node *local_node;
- unsigned long flags;
-diff -Naurp linux-2.6-git/drivers/firewire/fw-topology.h firewire-git/drivers/firewire/fw-topology.h
---- linux-2.6-git/drivers/firewire/fw-topology.h 2008-11-04 11:18:33.000000000 -0500
-+++ firewire-git/drivers/firewire/fw-topology.h 2009-01-30 13:35:51.862647087 -0500
-@@ -19,6 +19,11 @@
- #ifndef __fw_topology_h
- #define __fw_topology_h
-
-+#include <linux/list.h>
-+#include <linux/slab.h>
-+
-+#include <asm/atomic.h>
-+
- enum {
- FW_NODE_CREATED,
- FW_NODE_UPDATED,
-@@ -51,26 +56,22 @@ struct fw_node {
- struct fw_node *ports[0];
- };
-
--static inline struct fw_node *
--fw_node_get(struct fw_node *node)
-+static inline struct fw_node *fw_node_get(struct fw_node *node)
- {
- atomic_inc(&node->ref_count);
-
- return node;
- }
-
--static inline void
--fw_node_put(struct fw_node *node)
-+static inline void fw_node_put(struct fw_node *node)
- {
- if (atomic_dec_and_test(&node->ref_count))
- kfree(node);
- }
-
--void
--fw_destroy_nodes(struct fw_card *card);
--
--int
--fw_compute_block_crc(u32 *block);
-+struct fw_card;
-+void fw_destroy_nodes(struct fw_card *card);
-
-+int fw_compute_block_crc(u32 *block);
-
- #endif /* __fw_topology_h */
-diff -Naurp linux-2.6-git/drivers/firewire/fw-transaction.c firewire-git/drivers/firewire/fw-transaction.c
---- linux-2.6-git/drivers/firewire/fw-transaction.c 2009-01-30 13:39:02.991771976 -0500
-+++ firewire-git/drivers/firewire/fw-transaction.c 2009-01-30 13:35:51.862647087 -0500
-@@ -64,10 +64,9 @@
- #define PHY_CONFIG_ROOT_ID(node_id) ((((node_id) & 0x3f) << 24) | (1 << 23))
- #define PHY_IDENTIFIER(id) ((id) << 30)
-
--static int
--close_transaction(struct fw_transaction *transaction,
-- struct fw_card *card, int rcode,
-- u32 *payload, size_t length)
-+static int close_transaction(struct fw_transaction *transaction,
-+ struct fw_card *card, int rcode,
-+ u32 *payload, size_t length)
- {
- struct fw_transaction *t;
- unsigned long flags;
-@@ -94,9 +93,8 @@ close_transaction(struct fw_transaction
- * Only valid for transactions that are potentially pending (ie have
- * been sent).
- */
--int
--fw_cancel_transaction(struct fw_card *card,
-- struct fw_transaction *transaction)
-+int fw_cancel_transaction(struct fw_card *card,
-+ struct fw_transaction *transaction)
- {
- /*
- * Cancel the packet transmission if it's still queued. That
-@@ -116,9 +114,8 @@ fw_cancel_transaction(struct fw_card *ca
- }
- EXPORT_SYMBOL(fw_cancel_transaction);
-
--static void
--transmit_complete_callback(struct fw_packet *packet,
-- struct fw_card *card, int status)
-+static void transmit_complete_callback(struct fw_packet *packet,
-+ struct fw_card *card, int status)
- {
- struct fw_transaction *t =
- container_of(packet, struct fw_transaction, packet);
-@@ -151,8 +148,7 @@ transmit_complete_callback(struct fw_pac
- }
- }
-
--static void
--fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
-+static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
- int destination_id, int source_id, int generation, int speed,
- unsigned long long offset, void *payload, size_t length)
- {
-@@ -247,12 +243,10 @@ fw_fill_request(struct fw_packet *packet
- * @param callback_data pointer to arbitrary data, which will be
- * passed to the callback
- */
--void
--fw_send_request(struct fw_card *card, struct fw_transaction *t,
-- int tcode, int destination_id, int generation, int speed,
-- unsigned long long offset,
-- void *payload, size_t length,
-- fw_transaction_callback_t callback, void *callback_data)
-+void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
-+ int destination_id, int generation, int speed,
-+ unsigned long long offset, void *payload, size_t length,
-+ fw_transaction_callback_t callback, void *callback_data)
- {
- unsigned long flags;
- int tlabel;
-@@ -322,8 +316,8 @@ static void transaction_callback(struct
- * Returns the RCODE.
- */
- int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
-- int generation, int speed, unsigned long long offset,
-- void *data, size_t length)
-+ int generation, int speed, unsigned long long offset,
-+ void *data, size_t length)
- {
- struct transaction_callback_data d;
- struct fw_transaction t;
-@@ -399,9 +393,8 @@ void fw_flush_transactions(struct fw_car
- }
- }
-
--static struct fw_address_handler *
--lookup_overlapping_address_handler(struct list_head *list,
-- unsigned long long offset, size_t length)
-+static struct fw_address_handler *lookup_overlapping_address_handler(
-+ struct list_head *list, unsigned long long offset, size_t length)
- {
- struct fw_address_handler *handler;
-
-@@ -414,9 +407,8 @@ lookup_overlapping_address_handler(struc
- return NULL;
- }
-
--static struct fw_address_handler *
--lookup_enclosing_address_handler(struct list_head *list,
-- unsigned long long offset, size_t length)
-+static struct fw_address_handler *lookup_enclosing_address_handler(
-+ struct list_head *list, unsigned long long offset, size_t length)
- {
- struct fw_address_handler *handler;
-
-@@ -449,36 +441,44 @@ const struct fw_address_region fw_unit_s
- #endif /* 0 */
-
- /**
-- * Allocate a range of addresses in the node space of the OHCI
-- * controller. When a request is received that falls within the
-- * specified address range, the specified callback is invoked. The
-- * parameters passed to the callback give the details of the
-- * particular request.
-+ * fw_core_add_address_handler - register for incoming requests
-+ * @handler: callback
-+ * @region: region in the IEEE 1212 node space address range
-+ *
-+ * region->start, ->end, and handler->length have to be quadlet-aligned.
-+ *
-+ * When a request is received that falls within the specified address range,
-+ * the specified callback is invoked. The parameters passed to the callback
-+ * give the details of the particular request.
- *
- * Return value: 0 on success, non-zero otherwise.
- * The start offset of the handler's address region is determined by
- * fw_core_add_address_handler() and is returned in handler->offset.
-- * The offset is quadlet-aligned.
- */
--int
--fw_core_add_address_handler(struct fw_address_handler *handler,
-- const struct fw_address_region *region)
-+int fw_core_add_address_handler(struct fw_address_handler *handler,
-+ const struct fw_address_region *region)
- {
- struct fw_address_handler *other;
- unsigned long flags;
- int ret = -EBUSY;
-
-+ if (region->start & 0xffff000000000003ULL ||
-+ region->end & 0xffff000000000003ULL ||
-+ region->start >= region->end ||
-+ handler->length & 3 ||
-+ handler->length == 0)
-+ return -EINVAL;
-+
- spin_lock_irqsave(&address_handler_lock, flags);
-
-- handler->offset = roundup(region->start, 4);
-+ handler->offset = region->start;
- while (handler->offset + handler->length <= region->end) {
- other =
- lookup_overlapping_address_handler(&address_handler_list,
- handler->offset,
- handler->length);
- if (other != NULL) {
-- handler->offset =
-- roundup(other->offset + other->length, 4);
-+ handler->offset += other->length;
- } else {
- list_add_tail(&handler->link, &address_handler_list);
- ret = 0;
-@@ -493,12 +493,7 @@ fw_core_add_address_handler(struct fw_ad
- EXPORT_SYMBOL(fw_core_add_address_handler);
-
- /**
-- * Deallocate a range of addresses allocated with fw_allocate. This
-- * will call the associated callback one last time with a the special
-- * tcode TCODE_DEALLOCATE, to let the client destroy the registered
-- * callback data. For convenience, the callback parameters offset and
-- * length are set to the start and the length respectively for the
-- * deallocated region, payload is set to NULL.
-+ * fw_core_remove_address_handler - unregister an address handler
- */
- void fw_core_remove_address_handler(struct fw_address_handler *handler)
- {
-@@ -518,9 +513,8 @@ struct fw_request {
- u32 data[0];
- };
-
--static void
--free_response_callback(struct fw_packet *packet,
-- struct fw_card *card, int status)
-+static void free_response_callback(struct fw_packet *packet,
-+ struct fw_card *card, int status)
- {
- struct fw_request *request;
-
-@@ -528,9 +522,8 @@ free_response_callback(struct fw_packet
- kfree(request);
- }
-
--void
--fw_fill_response(struct fw_packet *response, u32 *request_header,
-- int rcode, void *payload, size_t length)
-+void fw_fill_response(struct fw_packet *response, u32 *request_header,
-+ int rcode, void *payload, size_t length)
- {
- int tcode, tlabel, extended_tcode, source, destination;
-
-@@ -588,8 +581,7 @@ fw_fill_response(struct fw_packet *respo
- }
- EXPORT_SYMBOL(fw_fill_response);
-
--static struct fw_request *
--allocate_request(struct fw_packet *p)
-+static struct fw_request *allocate_request(struct fw_packet *p)
- {
- struct fw_request *request;
- u32 *data, length;
-@@ -649,8 +641,8 @@ allocate_request(struct fw_packet *p)
- return request;
- }
-
--void
--fw_send_response(struct fw_card *card, struct fw_request *request, int rcode)
-+void fw_send_response(struct fw_card *card,
-+ struct fw_request *request, int rcode)
- {
- /* unified transaction or broadcast transaction: don't respond */
- if (request->ack != ACK_PENDING ||
-@@ -670,8 +662,7 @@ fw_send_response(struct fw_card *card, s
- }
- EXPORT_SYMBOL(fw_send_response);
-
--void
--fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
-+void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
- {
- struct fw_address_handler *handler;
- struct fw_request *request;
-@@ -719,8 +710,7 @@ fw_core_handle_request(struct fw_card *c
- }
- EXPORT_SYMBOL(fw_core_handle_request);
-
--void
--fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
-+void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
- {
- struct fw_transaction *t;
- unsigned long flags;
-@@ -793,12 +783,10 @@ static const struct fw_address_region to
- { .start = CSR_REGISTER_BASE | CSR_TOPOLOGY_MAP,
- .end = CSR_REGISTER_BASE | CSR_TOPOLOGY_MAP_END, };
-
--static void
--handle_topology_map(struct fw_card *card, struct fw_request *request,
-- int tcode, int destination, int source,
-- int generation, int speed,
-- unsigned long long offset,
-- void *payload, size_t length, void *callback_data)
-+static void handle_topology_map(struct fw_card *card, struct fw_request *request,
-+ int tcode, int destination, int source, int generation,
-+ int speed, unsigned long long offset,
-+ void *payload, size_t length, void *callback_data)
- {
- int i, start, end;
- __be32 *map;
-@@ -832,12 +820,10 @@ static const struct fw_address_region re
- { .start = CSR_REGISTER_BASE,
- .end = CSR_REGISTER_BASE | CSR_CONFIG_ROM, };
-
--static void
--handle_registers(struct fw_card *card, struct fw_request *request,
-- int tcode, int destination, int source,
-- int generation, int speed,
-- unsigned long long offset,
-- void *payload, size_t length, void *callback_data)
-+static void handle_registers(struct fw_card *card, struct fw_request *request,
-+ int tcode, int destination, int source, int generation,
-+ int speed, unsigned long long offset,
-+ void *payload, size_t length, void *callback_data)
- {
- int reg = offset & ~CSR_REGISTER_BASE;
- unsigned long long bus_time;
-@@ -939,11 +925,11 @@ static struct fw_descriptor model_id_des
-
- static int __init fw_core_init(void)
- {
-- int retval;
-+ int ret;
-
-- retval = bus_register(&fw_bus_type);
-- if (retval < 0)
-- return retval;
-+ ret = bus_register(&fw_bus_type);
-+ if (ret < 0)
-+ return ret;
-
- fw_cdev_major = register_chrdev(0, "firewire", &fw_device_ops);
- if (fw_cdev_major < 0) {
-@@ -951,19 +937,10 @@ static int __init fw_core_init(void)
- return fw_cdev_major;
- }
-
-- retval = fw_core_add_address_handler(&topology_map,
-- &topology_map_region);
-- BUG_ON(retval < 0);
--
-- retval = fw_core_add_address_handler(&registers,
-- &registers_region);
-- BUG_ON(retval < 0);
--
-- /* Add the vendor textual descriptor. */
-- retval = fw_core_add_descriptor(&vendor_id_descriptor);
-- BUG_ON(retval < 0);
-- retval = fw_core_add_descriptor(&model_id_descriptor);
-- BUG_ON(retval < 0);
-+ fw_core_add_address_handler(&topology_map, &topology_map_region);
-+ fw_core_add_address_handler(&registers, &registers_region);
-+ fw_core_add_descriptor(&vendor_id_descriptor);
-+ fw_core_add_descriptor(&model_id_descriptor);
-
- return 0;
- }
-diff -Naurp linux-2.6-git/drivers/firewire/fw-transaction.h firewire-git/drivers/firewire/fw-transaction.h
---- linux-2.6-git/drivers/firewire/fw-transaction.h 2009-01-30 13:39:02.992772636 -0500
-+++ firewire-git/drivers/firewire/fw-transaction.h 2009-01-30 13:35:51.862647087 -0500
-@@ -82,14 +82,14 @@
- #define CSR_SPEED_MAP 0x2000
- #define CSR_SPEED_MAP_END 0x3000
-
-+#define BANDWIDTH_AVAILABLE_INITIAL 4915
- #define BROADCAST_CHANNEL_INITIAL (1 << 31 | 31)
- #define BROADCAST_CHANNEL_VALID (1 << 30)
-
- #define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args)
- #define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args)
-
--static inline void
--fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
-+static inline void fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
- {
- u32 *dst = _dst;
- __be32 *src = _src;
-@@ -99,8 +99,7 @@ fw_memcpy_from_be32(void *_dst, void *_s
- dst[i] = be32_to_cpu(src[i]);
- }
-
--static inline void
--fw_memcpy_to_be32(void *_dst, void *_src, size_t size)
-+static inline void fw_memcpy_to_be32(void *_dst, void *_src, size_t size)
- {
- fw_memcpy_from_be32(_dst, _src, size);
- }
-@@ -125,8 +124,7 @@ typedef void (*fw_packet_callback_t)(str
- struct fw_card *card, int status);
-
- typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode,
-- void *data,
-- size_t length,
-+ void *data, size_t length,
- void *callback_data);
-
- /*
-@@ -141,12 +139,6 @@ typedef void (*fw_address_callback_t)(st
- void *data, size_t length,
- void *callback_data);
-
--typedef void (*fw_bus_reset_callback_t)(struct fw_card *handle,
-- int node_id, int generation,
-- u32 *self_ids,
-- int self_id_count,
-- void *callback_data);
--
- struct fw_packet {
- int speed;
- int generation;
-@@ -187,12 +179,6 @@ struct fw_transaction {
- void *callback_data;
- };
-
--static inline struct fw_packet *
--fw_packet(struct list_head *l)
--{
-- return list_entry(l, struct fw_packet, link);
--}
--
- struct fw_address_handler {
- u64 offset;
- size_t length;
-@@ -201,7 +187,6 @@ struct fw_address_handler {
- struct list_head link;
- };
-
--
- struct fw_address_region {
- u64 start;
- u64 end;
-@@ -315,10 +300,8 @@ struct fw_iso_packet {
- struct fw_iso_context;
-
- typedef void (*fw_iso_callback_t)(struct fw_iso_context *context,
-- u32 cycle,
-- size_t header_length,
-- void *header,
-- void *data);
-+ u32 cycle, size_t header_length,
-+ void *header, void *data);
-
- /*
- * An iso buffer is just a set of pages mapped for DMA in the
-@@ -344,36 +327,25 @@ struct fw_iso_context {
- void *callback_data;
- };
-
--int
--fw_iso_buffer_init(struct fw_iso_buffer *buffer,
-- struct fw_card *card,
-- int page_count,
-- enum dma_data_direction direction);
--int
--fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma);
--void
--fw_iso_buffer_destroy(struct fw_iso_buffer *buffer, struct fw_card *card);
--
--struct fw_iso_context *
--fw_iso_context_create(struct fw_card *card, int type,
-- int channel, int speed, size_t header_size,
-- fw_iso_callback_t callback, void *callback_data);
--
--void
--fw_iso_context_destroy(struct fw_iso_context *ctx);
--
--int
--fw_iso_context_queue(struct fw_iso_context *ctx,
-- struct fw_iso_packet *packet,
-- struct fw_iso_buffer *buffer,
-- unsigned long payload);
--
--int
--fw_iso_context_start(struct fw_iso_context *ctx,
-- int cycle, int sync, int tags);
-+int fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card,
-+ int page_count, enum dma_data_direction direction);
-+int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma);
-+void fw_iso_buffer_destroy(struct fw_iso_buffer *buffer, struct fw_card *card);
-+
-+struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
-+ int type, int channel, int speed, size_t header_size,
-+ fw_iso_callback_t callback, void *callback_data);
-+int fw_iso_context_queue(struct fw_iso_context *ctx,
-+ struct fw_iso_packet *packet,
-+ struct fw_iso_buffer *buffer,
-+ unsigned long payload);
-+int fw_iso_context_start(struct fw_iso_context *ctx,
-+ int cycle, int sync, int tags);
-+int fw_iso_context_stop(struct fw_iso_context *ctx);
-+void fw_iso_context_destroy(struct fw_iso_context *ctx);
-
--int
--fw_iso_context_stop(struct fw_iso_context *ctx);
-+void fw_iso_resource_manage(struct fw_card *card, int generation,
-+ u64 channels_mask, int *channel, int *bandwidth, bool allocate);
-
- struct fw_card_driver {
- /*
-@@ -415,7 +387,7 @@ struct fw_card_driver {
-
- struct fw_iso_context *
- (*allocate_iso_context)(struct fw_card *card,
-- int type, size_t header_size);
-+ int type, int channel, size_t header_size);
- void (*free_iso_context)(struct fw_iso_context *ctx);
-
- int (*start_iso)(struct fw_iso_context *ctx,
-@@ -429,24 +401,18 @@ struct fw_card_driver {
- int (*stop_iso)(struct fw_iso_context *ctx);
- };
-
--int
--fw_core_initiate_bus_reset(struct fw_card *card, int short_reset);
-+int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset);
-
--void
--fw_send_request(struct fw_card *card, struct fw_transaction *t,
-+void fw_send_request(struct fw_card *card, struct fw_transaction *t,
- int tcode, int destination_id, int generation, int speed,
- unsigned long long offset, void *data, size_t length,
- fw_transaction_callback_t callback, void *callback_data);
--
--int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
-- int generation, int speed, unsigned long long offset,
-- void *data, size_t length);
--
- int fw_cancel_transaction(struct fw_card *card,
- struct fw_transaction *transaction);
--
- void fw_flush_transactions(struct fw_card *card);
--
-+int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
-+ int generation, int speed, unsigned long long offset,
-+ void *data, size_t length);
- void fw_send_phy_config(struct fw_card *card,
- int node_id, int generation, int gap_count);
-
-@@ -454,29 +420,18 @@ void fw_send_phy_config(struct fw_card *
- * Called by the topology code to inform the device code of node
- * activity; found, lost, or updated nodes.
- */
--void
--fw_node_event(struct fw_card *card, struct fw_node *node, int event);
-+void fw_node_event(struct fw_card *card, struct fw_node *node, int event);
-
- /* API used by card level drivers */
-
--void
--fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
-- struct device *device);
--int
--fw_card_add(struct fw_card *card,
-- u32 max_receive, u32 link_speed, u64 guid);
--
--void
--fw_core_remove_card(struct fw_card *card);
--
--void
--fw_core_handle_bus_reset(struct fw_card *card,
-- int node_id, int generation,
-- int self_id_count, u32 *self_ids);
--void
--fw_core_handle_request(struct fw_card *card, struct fw_packet *request);
--
--void
--fw_core_handle_response(struct fw_card *card, struct fw_packet *packet);
-+void fw_card_initialize(struct fw_card *card,
-+ const struct fw_card_driver *driver, struct device *device);
-+int fw_card_add(struct fw_card *card,
-+ u32 max_receive, u32 link_speed, u64 guid);
-+void fw_core_remove_card(struct fw_card *card);
-+void fw_core_handle_bus_reset(struct fw_card *card, int node_id,
-+ int generation, int self_id_count, u32 *self_ids);
-+void fw_core_handle_request(struct fw_card *card, struct fw_packet *request);
-+void fw_core_handle_response(struct fw_card *card, struct fw_packet *packet);
-
- #endif /* __fw_transaction_h */
---- linux-2.6-git/include/linux/firewire-cdev.h 2008-11-04 11:19:21.000000000 -0500
-+++ firewire-git/include/linux/firewire-cdev.h 2009-01-30 13:35:54.327647015 -0500
-@@ -25,10 +25,12 @@
- #include <linux/types.h>
- #include <linux/firewire-constants.h>
-
--#define FW_CDEV_EVENT_BUS_RESET 0x00
--#define FW_CDEV_EVENT_RESPONSE 0x01
--#define FW_CDEV_EVENT_REQUEST 0x02
--#define FW_CDEV_EVENT_ISO_INTERRUPT 0x03
-+#define FW_CDEV_EVENT_BUS_RESET 0x00
-+#define FW_CDEV_EVENT_RESPONSE 0x01
-+#define FW_CDEV_EVENT_REQUEST 0x02
-+#define FW_CDEV_EVENT_ISO_INTERRUPT 0x03
-+#define FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED 0x04
-+#define FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED 0x05
-
- /**
- * struct fw_cdev_event_common - Common part of all fw_cdev_event_ types
-@@ -136,7 +138,24 @@ struct fw_cdev_event_request {
- * This event is sent when the controller has completed an &fw_cdev_iso_packet
- * with the %FW_CDEV_ISO_INTERRUPT bit set. In the receive case, the headers
- * stripped of all packets up until and including the interrupt packet are
-- * returned in the @header field.
-+ * returned in the @header field. The amount of header data per packet is as
-+ * specified at iso context creation by &fw_cdev_create_iso_context.header_size.
-+ *
-+ * In version 1 of this ABI, header data consisted of the 1394 isochronous
-+ * packet header, followed by quadlets from the packet payload if
-+ * &fw_cdev_create_iso_context.header_size > 4.
-+ *
-+ * In version 2 of this ABI, header data consist of the 1394 isochronous
-+ * packet header, followed by a timestamp quadlet if
-+ * &fw_cdev_create_iso_context.header_size > 4, followed by quadlets from the
-+ * packet payload if &fw_cdev_create_iso_context.header_size > 8.
-+ *
-+ * Behaviour of ver. 1 of this ABI is no longer available since ABI ver. 2.
-+ *
-+ * Format of 1394 iso packet header: 16 bits len, 2 bits tag, 6 bits channel,
-+ * 4 bits tcode, 4 bits sy, in big endian byte order. Format of timestamp:
-+ * 16 bits invalid, 3 bits cycleSeconds, 13 bits cycleCount, in big endian byte
-+ * order.
- */
- struct fw_cdev_event_iso_interrupt {
- __u64 closure;
-@@ -147,12 +166,44 @@ struct fw_cdev_event_iso_interrupt {
- };
-
- /**
-+ * struct fw_cdev_event_iso_resource - Iso resources were allocated or freed
-+ * @closure: See &fw_cdev_event_common;
-+ * set by %FW_CDEV_IOC_(DE)ALLOCATE_ISO_RESOURCE(_ONCE) ioctl
-+ * @type: %FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED or
-+ * %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED
-+ * @handle: Reference by which an allocated resource can be deallocated
-+ * @channel: Isochronous channel which was (de)allocated, if any
-+ * @bandwidth: Bandwidth allocation units which were (de)allocated, if any
-+ *
-+ * An %FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED event is sent after an isochronous
-+ * resource was allocated at the IRM. The client has to check @channel and
-+ * @bandwidth for whether the allocation actually succeeded.
-+ *
-+ * An %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED event is sent after an isochronous
-+ * resource was deallocated at the IRM. It is also sent when automatic
-+ * reallocation after a bus reset failed.
-+ *
-+ * @channel is <0 if no channel was (de)allocated or if reallocation failed.
-+ * @bandwidth is 0 if no bandwidth was (de)allocated or if reallocation failed.
-+ */
-+struct fw_cdev_event_iso_resource {
-+ __u64 closure;
-+ __u32 type;
-+ __u32 handle;
-+ __s32 channel;
-+ __s32 bandwidth;
-+};
-+
-+/**
- * union fw_cdev_event - Convenience union of fw_cdev_event_ types
- * @common: Valid for all types
- * @bus_reset: Valid if @common.type == %FW_CDEV_EVENT_BUS_RESET
- * @response: Valid if @common.type == %FW_CDEV_EVENT_RESPONSE
- * @request: Valid if @common.type == %FW_CDEV_EVENT_REQUEST
- * @iso_interrupt: Valid if @common.type == %FW_CDEV_EVENT_ISO_INTERRUPT
-+ * @iso_resource: Valid if @common.type ==
-+ * %FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED or
-+ * %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED
- *
- * Convenience union for userspace use. Events could be read(2) into an
- * appropriately aligned char buffer and then cast to this union for further
-@@ -163,13 +214,15 @@ struct fw_cdev_event_iso_interrupt {
- * not fit will be discarded so that the next read(2) will return a new event.
- */
- union fw_cdev_event {
-- struct fw_cdev_event_common common;
-- struct fw_cdev_event_bus_reset bus_reset;
-- struct fw_cdev_event_response response;
-- struct fw_cdev_event_request request;
-- struct fw_cdev_event_iso_interrupt iso_interrupt;
-+ struct fw_cdev_event_common common;
-+ struct fw_cdev_event_bus_reset bus_reset;
-+ struct fw_cdev_event_response response;
-+ struct fw_cdev_event_request request;
-+ struct fw_cdev_event_iso_interrupt iso_interrupt;
-+ struct fw_cdev_event_iso_resource iso_resource;
- };
-
-+/* available since kernel version 2.6.22 */
- #define FW_CDEV_IOC_GET_INFO _IOWR('#', 0x00, struct fw_cdev_get_info)
- #define FW_CDEV_IOC_SEND_REQUEST _IOW('#', 0x01, struct fw_cdev_send_request)
- #define FW_CDEV_IOC_ALLOCATE _IOWR('#', 0x02, struct fw_cdev_allocate)
-@@ -178,18 +231,29 @@ union fw_cdev_event {
- #define FW_CDEV_IOC_INITIATE_BUS_RESET _IOW('#', 0x05, struct fw_cdev_initiate_bus_reset)
- #define FW_CDEV_IOC_ADD_DESCRIPTOR _IOWR('#', 0x06, struct fw_cdev_add_descriptor)
- #define FW_CDEV_IOC_REMOVE_DESCRIPTOR _IOW('#', 0x07, struct fw_cdev_remove_descriptor)
--
- #define FW_CDEV_IOC_CREATE_ISO_CONTEXT _IOWR('#', 0x08, struct fw_cdev_create_iso_context)
- #define FW_CDEV_IOC_QUEUE_ISO _IOWR('#', 0x09, struct fw_cdev_queue_iso)
- #define FW_CDEV_IOC_START_ISO _IOW('#', 0x0a, struct fw_cdev_start_iso)
- #define FW_CDEV_IOC_STOP_ISO _IOW('#', 0x0b, struct fw_cdev_stop_iso)
-+
-+/* available since kernel version 2.6.24 */
- #define FW_CDEV_IOC_GET_CYCLE_TIMER _IOR('#', 0x0c, struct fw_cdev_get_cycle_timer)
-
--/* FW_CDEV_VERSION History
-- *
-- * 1 Feb 18, 2007: Initial version.
-+/* available since kernel version 2.6.30 */
-+#define FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE _IOWR('#', 0x0d, struct fw_cdev_allocate_iso_resource)
-+#define FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE _IOW('#', 0x0e, struct fw_cdev_deallocate)
-+#define FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE _IOW('#', 0x0f, struct fw_cdev_allocate_iso_resource)
-+#define FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE_ONCE _IOW('#', 0x10, struct fw_cdev_allocate_iso_resource)
-+#define FW_CDEV_IOC_GET_SPEED _IOR('#', 0x11, struct fw_cdev_get_speed)
-+#define FW_CDEV_IOC_SEND_BROADCAST_REQUEST _IOW('#', 0x12, struct fw_cdev_send_request)
-+
-+/*
-+ * FW_CDEV_VERSION History
-+ * 1 (2.6.22) - initial version
-+ * 2 (2.6.30) - changed &fw_cdev_event_iso_interrupt.header if
-+ * &fw_cdev_create_iso_context.header_size is 8 or more
- */
--#define FW_CDEV_VERSION 1
-+#define FW_CDEV_VERSION 2
-
- /**
- * struct fw_cdev_get_info - General purpose information ioctl
-@@ -201,7 +265,7 @@ union fw_cdev_event {
- * case, @rom_length is updated with the actual length of the
- * configuration ROM.
- * @rom: If non-zero, address of a buffer to be filled by a copy of the
-- * local node's configuration ROM
-+ * device's configuration ROM
- * @bus_reset: If non-zero, address of a buffer to be filled by a
- * &struct fw_cdev_event_bus_reset with the current state
- * of the bus. This does not cause a bus reset to happen.
-@@ -229,7 +293,7 @@ struct fw_cdev_get_info {
- * Send a request to the device. This ioctl implements all outgoing requests.
- * Both quadlet and block request specify the payload as a pointer to the data
- * in the @data field. Once the transaction completes, the kernel writes an
-- * &fw_cdev_event_request event back. The @closure field is passed back to
-+ * &fw_cdev_event_response event back. The @closure field is passed back to
- * user space in the response event.
- */
- struct fw_cdev_send_request {
-@@ -284,9 +348,9 @@ struct fw_cdev_allocate {
- };
-
- /**
-- * struct fw_cdev_deallocate - Free an address range allocation
-- * @handle: Handle to the address range, as returned by the kernel when the
-- * range was allocated
-+ * struct fw_cdev_deallocate - Free a CSR address range or isochronous resource
-+ * @handle: Handle to the address range or iso resource, as returned by the
-+ * kernel when the range or resource was allocated
- */
- struct fw_cdev_deallocate {
- __u32 handle;
-@@ -370,6 +434,9 @@ struct fw_cdev_remove_descriptor {
- *
- * If a context was successfully created, the kernel writes back a handle to the
- * context, which must be passed in for subsequent operations on that context.
-+ *
-+ * Note that the effect of a @header_size > 4 depends on
-+ * &fw_cdev_get_info.version, as documented at &fw_cdev_event_iso_interrupt.
- */
- struct fw_cdev_create_iso_context {
- __u32 type;
-@@ -473,10 +540,73 @@ struct fw_cdev_stop_iso {
- * The %FW_CDEV_IOC_GET_CYCLE_TIMER ioctl reads the isochronous cycle timer
- * and also the system clock. This allows to express the receive time of an
- * isochronous packet as a system time with microsecond accuracy.
-+ *
-+ * @cycle_timer consists of 7 bits cycleSeconds, 13 bits cycleCount, and
-+ * 12 bits cycleOffset, in host byte order.
- */
- struct fw_cdev_get_cycle_timer {
- __u64 local_time;
- __u32 cycle_timer;
- };
-
-+/**
-+ * struct fw_cdev_allocate_iso_resource - (De)allocate a channel or bandwidth
-+ * @closure: Passed back to userspace in correponding iso resource events
-+ * @channels: Isochronous channels of which one is to be (de)allocated
-+ * @bandwidth: Isochronous bandwidth units to be (de)allocated
-+ * @handle: Handle to the allocation, written by the kernel (only valid in
-+ * case of %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE ioctls)
-+ *
-+ * The %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE ioctl initiates allocation of an
-+ * isochronous channel and/or of isochronous bandwidth at the isochronous
-+ * resource manager (IRM). Only one of the channels specified in @channels is
-+ * allocated. An %FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED is sent after
-+ * communication with the IRM, indicating success or failure in the event data.
-+ * The kernel will automatically reallocate the resources after bus resets.
-+ * Should a reallocation fail, an %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED event
-+ * will be sent. The kernel will also automatically deallocate the resources
-+ * when the file descriptor is closed.
-+ *
-+ * The %FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE ioctl can be used to initiate
-+ * deallocation of resources which were allocated as described above.
-+ * An %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED event concludes this operation.
-+ *
-+ * The %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE ioctl is a variant of allocation
-+ * without automatic re- or deallocation.
-+ * An %FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED event concludes this operation,
-+ * indicating success or failure in its data.
-+ *
-+ * The %FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE_ONCE ioctl works like
-+ * %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE except that resources are freed
-+ * instead of allocated.
-+ * An %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED event concludes this operation.
-+ *
-+ * To summarize, %FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE allocates iso resources
-+ * for the lifetime of the fd or handle.
-+ * In contrast, %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE allocates iso resources
-+ * for the duration of a bus generation.
-+ *
-+ * @channels is a host-endian bitfield with the least significant bit
-+ * representing channel 0 and the most significant bit representing channel 63:
-+ * 1ULL << c for each channel c that is a candidate for (de)allocation.
-+ *
-+ * @bandwidth is expressed in bandwidth allocation units, i.e. the time to send
-+ * one quadlet of data (payload or header data) at speed S1600.
-+ */
-+struct fw_cdev_allocate_iso_resource {
-+ __u64 closure;
-+ __u64 channels;
-+ __u32 bandwidth;
-+ __u32 handle;
-+};
-+
-+/**
-+ * struct fw_cdev_get_speed - Query maximum speed to or from this device
-+ * @max_speed: Speed code; minimum of the device's link speed, the local node's
-+ * link speed, and all PHY port speeds between the two links
-+ */
-+struct fw_cdev_get_speed {
-+ __u32 max_speed;
-+};
-+
- #endif /* _LINUX_FIREWIRE_CDEV_H */