From f71f33b4f0d0739aacf5d49738a0533bbb2dfc13 Mon Sep 17 00:00:00 2001 From: Maximilian Attems Date: Thu, 3 Apr 2008 11:28:35 +0000 Subject: [PATCH] firewire add upstream git tree fedora is shipping it as it enhances the firewire logging, thus we want that already for 2.6.25. backport applies just cleanly without any changes. svn path=/dists/trunk/linux-2.6/; revision=11034 --- debian/changelog | 1 + .../patches/features/all/firewire-git.patch | 2773 +++++++++++++++++ debian/patches/series/1~experimental.1 | 1 + 3 files changed, 2775 insertions(+) create mode 100644 debian/patches/features/all/firewire-git.patch diff --git a/debian/changelog b/debian/changelog index ea465a258..c08d3156f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -36,6 +36,7 @@ linux-2.6 (2.6.25~rc8-1~experimental.1) UNRELEASED; urgency=low * control.source.in: Newer standard version without changes. * copyright: adapt to latest lintian recommendation. * input: Add 4 additional exports for modular speakup and braille support. + * firewire: Add firewire-git.patch for latest firewire tree features. [ Martin Michlmayr ] * [arm/armel] Add a kernel for Orion based devices, such as the QNAP diff --git a/debian/patches/features/all/firewire-git.patch b/debian/patches/features/all/firewire-git.patch new file mode 100644 index 000000000..c70763e1c --- /dev/null +++ b/debian/patches/features/all/firewire-git.patch @@ -0,0 +1,2773 @@ +git diff in linux1394-2.6.git vs. v2.6.25-rc8, April 02, 2008 + + Documentation/debugging-via-ohci1394.txt | 13 +- + drivers/firewire/Kconfig | 5 + + drivers/firewire/fw-card.c | 52 +---- + drivers/firewire/fw-cdev.c | 13 +- + drivers/firewire/fw-device.c | 263 +++++++++++++++++++----- + drivers/firewire/fw-device.h | 38 +++- + drivers/firewire/fw-iso.c | 5 - + drivers/firewire/fw-ohci.c | 338 ++++++++++++++++++++++++------ + drivers/firewire/fw-ohci.h | 1 + + drivers/firewire/fw-sbp2.c | 150 ++++++------- + drivers/firewire/fw-topology.c | 22 ++- + drivers/firewire/fw-topology.h | 11 +- + drivers/firewire/fw-transaction.c | 75 ++++---- + drivers/firewire/fw-transaction.h | 17 +- + drivers/ieee1394/csr.c | 6 +- + drivers/ieee1394/dv1394.c | 4 +- + drivers/ieee1394/highlevel.c | 6 +- + drivers/ieee1394/ieee1394_core.c | 2 +- + drivers/ieee1394/nodemgr.c | 6 +- + drivers/ieee1394/ohci1394.c | 229 ++++++++++---------- + drivers/ieee1394/pcilynx.c | 15 +- + drivers/ieee1394/raw1394.c | 2 - + drivers/ieee1394/sbp2.c | 11 +- + drivers/ieee1394/video1394.c | 4 +- + lib/Kconfig.debug | 10 + + 25 files changed, 835 insertions(+), 463 deletions(-) + +diff --git a/Documentation/debugging-via-ohci1394.txt b/Documentation/debugging-via-ohci1394.txt +index c360d4e..371ba27 100644 +--- a/Documentation/debugging-via-ohci1394.txt ++++ b/Documentation/debugging-via-ohci1394.txt +@@ -41,11 +41,14 @@ to a working state and enables physical DMA by default for all remote nodes. + This can be turned off by ohci1394's module parameter phys_dma=0. + + The alternative firewire-ohci driver in drivers/firewire uses filtered physical +-DMA, hence is not yet suitable for remote debugging. +- +-Because ohci1394 depends on the PCI enumeration to be completed, an +-initialization routine which runs pretty early (long before console_init() +-which makes the printk buffer appear on the console can be called) was written. ++DMA by default, which is more secure but not suitable for remote debugging. ++Compile the driver with CONFIG_FIREWIRE_OHCI_REMOTE_DMA to get unfiltered ++physical DMA. ++ ++Because ohci1394 and firewire-ohci depend on the PCI enumeration to be ++completed, an initialization routine which runs pretty early has been ++implemented for x86. This routine runs long before console_init() can be ++called, i.e. before the printk buffer appears on the console. + + To activate it, enable CONFIG_PROVIDE_OHCI1394_DMA_INIT (Kernel hacking menu: + Provide code for enabling DMA over FireWire early on boot) and pass the +diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig +index 25bdc2d..fb4d391 100644 +--- a/drivers/firewire/Kconfig ++++ b/drivers/firewire/Kconfig +@@ -54,6 +54,11 @@ config FIREWIRE_OHCI + directive, use "install modulename /bin/true" for the modules to be + blacklisted. + ++config FIREWIRE_OHCI_DEBUG ++ bool ++ depends on FIREWIRE_OHCI ++ default y ++ + config FIREWIRE_SBP2 + tristate "Support for storage devices (SBP-2 protocol driver)" + depends on FIREWIRE && SCSI +diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c +index a034627..102e809 100644 +--- a/drivers/firewire/fw-card.c ++++ b/drivers/firewire/fw-card.c +@@ -167,7 +167,6 @@ fw_core_add_descriptor(struct fw_descriptor *desc) + + return 0; + } +-EXPORT_SYMBOL(fw_core_add_descriptor); + + void + fw_core_remove_descriptor(struct fw_descriptor *desc) +@@ -182,7 +181,6 @@ fw_core_remove_descriptor(struct fw_descriptor *desc) + + mutex_unlock(&card_mutex); + } +-EXPORT_SYMBOL(fw_core_remove_descriptor); + + static const char gap_count_table[] = { + 63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40 +@@ -220,7 +218,7 @@ fw_card_bm_work(struct work_struct *work) + struct bm_data bmd; + unsigned long flags; + int root_id, new_root_id, irm_id, gap_count, generation, grace; +- int do_reset = 0; ++ bool do_reset = false; + + spin_lock_irqsave(&card->lock, flags); + local_node = card->local_node; +@@ -240,7 +238,7 @@ fw_card_bm_work(struct work_struct *work) + root_id = root_node->node_id; + grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10)); + +- if (card->bm_generation + 1 == generation || ++ if (is_next_generation(generation, card->bm_generation) || + (card->bm_generation != generation && grace)) { + /* + * This first step is to figure out who is IRM and +@@ -331,7 +329,7 @@ fw_card_bm_work(struct work_struct *work) + */ + spin_unlock_irqrestore(&card->lock, flags); + goto out; +- } else if (root_device->config_rom[2] & BIB_CMC) { ++ } else if (root_device->cmc) { + /* + * FIXME: I suppose we should set the cmstr bit in the + * STATE_CLEAR register of this node, as described in +@@ -360,14 +358,14 @@ fw_card_bm_work(struct work_struct *work) + gap_count = 63; + + /* +- * Finally, figure out if we should do a reset or not. If we've +- * done less that 5 resets with the same physical topology and we ++ * Finally, figure out if we should do a reset or not. If we have ++ * done less than 5 resets with the same physical topology and we + * have either a new root or a new gap count setting, let's do it. + */ + + if (card->bm_retries++ < 5 && + (card->gap_count != gap_count || new_root_id != root_id)) +- do_reset = 1; ++ do_reset = true; + + spin_unlock_irqrestore(&card->lock, flags); + +@@ -398,7 +396,6 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, + { + static atomic_t index = ATOMIC_INIT(-1); + +- kref_init(&card->kref); + atomic_set(&card->device_count, 0); + card->index = atomic_inc_return(&index); + card->driver = driver; +@@ -429,12 +426,6 @@ fw_card_add(struct fw_card *card, + card->link_speed = link_speed; + card->guid = guid; + +- /* +- * The subsystem grabs a reference when the card is added and +- * drops it when the driver calls fw_core_remove_card. +- */ +- fw_card_get(card); +- + mutex_lock(&card_mutex); + config_rom = generate_config_rom(card, &length); + list_add_tail(&card->link, &card_list); +@@ -540,40 +531,9 @@ fw_core_remove_card(struct fw_card *card) + cancel_delayed_work_sync(&card->work); + fw_flush_transactions(card); + del_timer_sync(&card->flush_timer); +- +- fw_card_put(card); + } + EXPORT_SYMBOL(fw_core_remove_card); + +-struct fw_card * +-fw_card_get(struct fw_card *card) +-{ +- kref_get(&card->kref); +- +- return card; +-} +-EXPORT_SYMBOL(fw_card_get); +- +-static void +-release_card(struct kref *kref) +-{ +- struct fw_card *card = container_of(kref, struct fw_card, kref); +- +- kfree(card); +-} +- +-/* +- * An assumption for fw_card_put() is that the card driver allocates +- * the fw_card struct with kalloc and that it has been shut down +- * before the last ref is dropped. +- */ +-void +-fw_card_put(struct fw_card *card) +-{ +- kref_put(&card->kref, release_card); +-} +-EXPORT_SYMBOL(fw_card_put); +- + int + fw_core_initiate_bus_reset(struct fw_card *card, int short_reset) + { +diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c +index 46bc197..4a54192 100644 +--- a/drivers/firewire/fw-cdev.c ++++ b/drivers/firewire/fw-cdev.c +@@ -269,21 +269,28 @@ static int ioctl_get_info(struct client *client, void *buffer) + { + struct fw_cdev_get_info *get_info = buffer; + struct fw_cdev_event_bus_reset bus_reset; ++ unsigned long ret = 0; + + client->version = get_info->version; + get_info->version = FW_CDEV_VERSION; + ++ down_read(&fw_device_rwsem); ++ + if (get_info->rom != 0) { + void __user *uptr = u64_to_uptr(get_info->rom); + size_t want = get_info->rom_length; + size_t have = client->device->config_rom_length * 4; + +- if (copy_to_user(uptr, client->device->config_rom, +- min(want, have))) +- return -EFAULT; ++ ret = copy_to_user(uptr, client->device->config_rom, ++ min(want, have)); + } + get_info->rom_length = client->device->config_rom_length * 4; + ++ up_read(&fw_device_rwsem); ++ ++ if (ret != 0) ++ return -EFAULT; ++ + 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); +diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c +index 870125a..2d01bc1 100644 +--- a/drivers/firewire/fw-device.c ++++ b/drivers/firewire/fw-device.c +@@ -25,7 +25,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +@@ -160,9 +160,9 @@ static void fw_device_release(struct device *dev) + * Take the card lock so we don't set this to NULL while a + * FW_NODE_UPDATED callback is being handled. + */ +- spin_lock_irqsave(&device->card->lock, flags); ++ spin_lock_irqsave(&card->lock, flags); + device->node->data = NULL; +- spin_unlock_irqrestore(&device->card->lock, flags); ++ spin_unlock_irqrestore(&card->lock, flags); + + fw_node_put(device->node); + kfree(device->config_rom); +@@ -195,7 +195,9 @@ show_immediate(struct device *dev, struct device_attribute *dattr, char *buf) + container_of(dattr, struct config_rom_attribute, attr); + struct fw_csr_iterator ci; + u32 *dir; +- int key, value; ++ int key, value, ret = -ENOENT; ++ ++ down_read(&fw_device_rwsem); + + if (is_fw_unit(dev)) + dir = fw_unit(dev)->directory; +@@ -204,11 +206,15 @@ show_immediate(struct device *dev, struct device_attribute *dattr, char *buf) + + fw_csr_iterator_init(&ci, dir); + while (fw_csr_iterator_next(&ci, &key, &value)) +- if (attr->key == key) +- return snprintf(buf, buf ? PAGE_SIZE : 0, +- "0x%06x\n", value); ++ if (attr->key == key) { ++ ret = snprintf(buf, buf ? PAGE_SIZE : 0, ++ "0x%06x\n", value); ++ break; ++ } ++ ++ up_read(&fw_device_rwsem); + +- return -ENOENT; ++ return ret; + } + + #define IMMEDIATE_ATTR(name, key) \ +@@ -221,9 +227,11 @@ show_text_leaf(struct device *dev, struct device_attribute *dattr, char *buf) + container_of(dattr, struct config_rom_attribute, attr); + struct fw_csr_iterator ci; + u32 *dir, *block = NULL, *p, *end; +- int length, key, value, last_key = 0; ++ int length, key, value, last_key = 0, ret = -ENOENT; + char *b; + ++ down_read(&fw_device_rwsem); ++ + if (is_fw_unit(dev)) + dir = fw_unit(dev)->directory; + else +@@ -238,18 +246,20 @@ show_text_leaf(struct device *dev, struct device_attribute *dattr, char *buf) + } + + if (block == NULL) +- return -ENOENT; ++ goto out; + + length = min(block[0] >> 16, 256U); + if (length < 3) +- return -ENOENT; ++ goto out; + + if (block[1] != 0 || block[2] != 0) + /* Unknown encoding. */ +- return -ENOENT; ++ goto out; + +- if (buf == NULL) +- return length * 4; ++ if (buf == NULL) { ++ ret = length * 4; ++ goto out; ++ } + + b = buf; + end = &block[length + 1]; +@@ -259,8 +269,11 @@ show_text_leaf(struct device *dev, struct device_attribute *dattr, char *buf) + /* Strip trailing whitespace and add newline. */ + while (b--, (isspace(*b) || *b == '\0') && b > buf); + strcpy(b + 1, "\n"); ++ ret = b + 2 - buf; ++ out: ++ up_read(&fw_device_rwsem); + +- return b + 2 - buf; ++ return ret; + } + + #define TEXT_LEAF_ATTR(name, key) \ +@@ -337,19 +350,28 @@ 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; + +- memcpy(buf, device->config_rom, device->config_rom_length * 4); ++ down_read(&fw_device_rwsem); ++ length = device->config_rom_length * 4; ++ memcpy(buf, device->config_rom, length); ++ up_read(&fw_device_rwsem); + +- return device->config_rom_length * 4; ++ return length; + } + + static ssize_t + guid_show(struct device *dev, struct device_attribute *attr, char *buf) + { + struct fw_device *device = fw_device(dev); ++ int ret; ++ ++ down_read(&fw_device_rwsem); ++ ret = snprintf(buf, PAGE_SIZE, "0x%08x%08x\n", ++ device->config_rom[3], device->config_rom[4]); ++ up_read(&fw_device_rwsem); + +- return snprintf(buf, PAGE_SIZE, "0x%08x%08x\n", +- device->config_rom[3], device->config_rom[4]); ++ return ret; + } + + static struct device_attribute fw_device_attributes[] = { +@@ -388,7 +410,7 @@ read_rom(struct fw_device *device, int generation, int index, u32 *data) + + init_completion(&callback_data.done); + +- offset = 0xfffff0000400ULL + index * 4; ++ offset = (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4; + fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST, + device->node_id, generation, device->max_speed, + offset, NULL, 4, complete_transaction, &callback_data); +@@ -400,6 +422,9 @@ read_rom(struct fw_device *device, int generation, int index, u32 *data) + return callback_data.rcode; + } + ++#define READ_BIB_ROM_SIZE 256 ++#define READ_BIB_STACK_SIZE 16 ++ + /* + * Read the bus info block, perform a speed probe, and read all of the rest of + * the config ROM. We do all this with a cached bus generation. If the bus +@@ -409,16 +434,23 @@ read_rom(struct fw_device *device, int generation, int index, u32 *data) + */ + static int read_bus_info_block(struct fw_device *device, int generation) + { +- static u32 rom[256]; +- u32 stack[16], sp, key; +- int i, end, length; ++ u32 *rom, *stack, *old_rom, *new_rom; ++ u32 sp, key; ++ int i, end, length, ret = -1; ++ ++ rom = kmalloc(sizeof(*rom) * READ_BIB_ROM_SIZE + ++ sizeof(*stack) * READ_BIB_STACK_SIZE, GFP_KERNEL); ++ if (rom == NULL) ++ return -ENOMEM; ++ ++ stack = &rom[READ_BIB_ROM_SIZE]; + + device->max_speed = SCODE_100; + + /* First read the bus info block. */ + for (i = 0; i < 5; i++) { + if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE) +- return -1; ++ goto out; + /* + * As per IEEE1212 7.2, during power-up, devices can + * reply with a 0 for the first quadlet of the config +@@ -428,7 +460,7 @@ static int read_bus_info_block(struct fw_device *device, int generation) + * retry mechanism will try again later. + */ + if (i == 0 && rom[i] == 0) +- return -1; ++ goto out; + } + + device->max_speed = device->node->max_speed; +@@ -478,26 +510,26 @@ static int read_bus_info_block(struct fw_device *device, int generation) + */ + key = stack[--sp]; + i = key & 0xffffff; +- if (i >= ARRAY_SIZE(rom)) ++ if (i >= READ_BIB_ROM_SIZE) + /* + * The reference points outside the standard + * config rom area, something's fishy. + */ +- return -1; ++ goto out; + + /* Read header quadlet for the block to get the length. */ + if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE) +- return -1; ++ goto out; + end = i + (rom[i] >> 16) + 1; + i++; +- if (end > ARRAY_SIZE(rom)) ++ if (end > READ_BIB_ROM_SIZE) + /* + * This block extends outside standard config + * area (and the array we're reading it + * into). That's broken, so ignore this + * device. + */ +- return -1; ++ goto out; + + /* + * Now read in the block. If this is a directory +@@ -507,9 +539,9 @@ static int read_bus_info_block(struct fw_device *device, int generation) + while (i < end) { + if (read_rom(device, generation, i, &rom[i]) != + RCODE_COMPLETE) +- return -1; ++ goto out; + if ((key >> 30) == 3 && (rom[i] >> 30) > 1 && +- sp < ARRAY_SIZE(stack)) ++ sp < READ_BIB_STACK_SIZE) + stack[sp++] = i + rom[i]; + i++; + } +@@ -517,13 +549,23 @@ static int read_bus_info_block(struct fw_device *device, int generation) + length = i; + } + +- device->config_rom = kmalloc(length * 4, GFP_KERNEL); +- if (device->config_rom == NULL) +- return -1; +- memcpy(device->config_rom, rom, length * 4); ++ old_rom = device->config_rom; ++ new_rom = kmemdup(rom, length * 4, GFP_KERNEL); ++ if (new_rom == NULL) ++ goto out; ++ ++ down_write(&fw_device_rwsem); ++ device->config_rom = new_rom; + device->config_rom_length = length; ++ up_write(&fw_device_rwsem); + +- return 0; ++ kfree(old_rom); ++ ret = 0; ++ device->cmc = rom[2] & 1 << 30; ++ out: ++ kfree(rom); ++ ++ return ret; + } + + static void fw_unit_release(struct device *dev) +@@ -592,7 +634,14 @@ static int shutdown_unit(struct device *device, void *data) + return 0; + } + +-static DECLARE_RWSEM(idr_rwsem); ++/* ++ * fw_device_rwsem acts as dual purpose mutex: ++ * - serializes accesses to fw_device_idr, ++ * - serializes accesses to fw_device.config_rom/.config_rom_length and ++ * fw_unit.directory, unless those accesses happen at safe occasions ++ */ ++DECLARE_RWSEM(fw_device_rwsem); ++ + static DEFINE_IDR(fw_device_idr); + int fw_cdev_major; + +@@ -600,11 +649,11 @@ struct fw_device *fw_device_get_by_devt(dev_t devt) + { + struct fw_device *device; + +- down_read(&idr_rwsem); ++ down_read(&fw_device_rwsem); + device = idr_find(&fw_device_idr, MINOR(devt)); + if (device) + fw_device_get(device); +- up_read(&idr_rwsem); ++ up_read(&fw_device_rwsem); + + return device; + } +@@ -619,9 +668,9 @@ static void fw_device_shutdown(struct work_struct *work) + device_for_each_child(&device->device, NULL, shutdown_unit); + device_unregister(&device->device); + +- down_write(&idr_rwsem); ++ down_write(&fw_device_rwsem); + idr_remove(&fw_device_idr, minor); +- up_write(&idr_rwsem); ++ up_write(&fw_device_rwsem); + fw_device_put(device); + } + +@@ -674,10 +723,10 @@ static void fw_device_init(struct work_struct *work) + err = -ENOMEM; + + fw_device_get(device); +- down_write(&idr_rwsem); ++ down_write(&fw_device_rwsem); + if (idr_pre_get(&fw_device_idr, GFP_KERNEL)) + err = idr_get_new(&fw_device_idr, device, &minor); +- up_write(&idr_rwsem); ++ up_write(&fw_device_rwsem); + + if (err < 0) + goto error; +@@ -711,7 +760,7 @@ static void fw_device_init(struct work_struct *work) + if (atomic_cmpxchg(&device->state, + FW_DEVICE_INITIALIZING, + FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) { +- fw_device_shutdown(&device->work.work); ++ fw_device_shutdown(work); + } else { + if (device->config_rom_retries) + fw_notify("created device %s: GUID %08x%08x, S%d00, " +@@ -725,6 +774,7 @@ static void fw_device_init(struct work_struct *work) + device->device.bus_id, + device->config_rom[3], device->config_rom[4], + 1 << device->max_speed); ++ device->config_rom_retries = 0; + } + + /* +@@ -739,9 +789,9 @@ static void fw_device_init(struct work_struct *work) + return; + + error_with_cdev: +- down_write(&idr_rwsem); ++ down_write(&fw_device_rwsem); + idr_remove(&fw_device_idr, minor); +- up_write(&idr_rwsem); ++ up_write(&fw_device_rwsem); + error: + fw_device_put(device); /* fw_device_idr's reference */ + +@@ -771,6 +821,106 @@ static void fw_device_update(struct work_struct *work) + device_for_each_child(&device->device, NULL, update_unit); + } + ++enum { ++ REREAD_BIB_ERROR, ++ REREAD_BIB_GONE, ++ REREAD_BIB_UNCHANGED, ++ REREAD_BIB_CHANGED, ++}; ++ ++/* Reread and compare bus info block and header of root directory */ ++static int reread_bus_info_block(struct fw_device *device, int generation) ++{ ++ u32 q; ++ int i; ++ ++ for (i = 0; i < 6; i++) { ++ if (read_rom(device, generation, i, &q) != RCODE_COMPLETE) ++ return REREAD_BIB_ERROR; ++ ++ if (i == 0 && q == 0) ++ return REREAD_BIB_GONE; ++ ++ if (i > device->config_rom_length || q != device->config_rom[i]) ++ return REREAD_BIB_CHANGED; ++ } ++ ++ return REREAD_BIB_UNCHANGED; ++} ++ ++static void fw_device_refresh(struct work_struct *work) ++{ ++ struct fw_device *device = ++ container_of(work, struct fw_device, work.work); ++ struct fw_card *card = device->card; ++ int node_id = device->node_id; ++ ++ switch (reread_bus_info_block(device, device->generation)) { ++ case REREAD_BIB_ERROR: ++ if (device->config_rom_retries < MAX_RETRIES / 2 && ++ atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { ++ device->config_rom_retries++; ++ schedule_delayed_work(&device->work, RETRY_DELAY / 2); ++ ++ return; ++ } ++ goto give_up; ++ ++ case REREAD_BIB_GONE: ++ goto gone; ++ ++ case REREAD_BIB_UNCHANGED: ++ if (atomic_cmpxchg(&device->state, ++ FW_DEVICE_INITIALIZING, ++ FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) ++ goto gone; ++ ++ fw_device_update(work); ++ device->config_rom_retries = 0; ++ goto out; ++ ++ case REREAD_BIB_CHANGED: ++ break; ++ } ++ ++ /* ++ * Something changed. We keep things simple and don't investigate ++ * further. We just destroy all previous units and create new ones. ++ */ ++ device_for_each_child(&device->device, NULL, shutdown_unit); ++ ++ if (read_bus_info_block(device, device->generation) < 0) { ++ if (device->config_rom_retries < MAX_RETRIES && ++ atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { ++ device->config_rom_retries++; ++ schedule_delayed_work(&device->work, RETRY_DELAY); ++ ++ return; ++ } ++ goto give_up; ++ } ++ ++ create_units(device); ++ ++ if (atomic_cmpxchg(&device->state, ++ FW_DEVICE_INITIALIZING, ++ FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) ++ goto gone; ++ ++ fw_notify("refreshed device %s\n", device->device.bus_id); ++ device->config_rom_retries = 0; ++ goto out; ++ ++ give_up: ++ fw_notify("giving up on refresh of device %s\n", device->device.bus_id); ++ gone: ++ atomic_set(&device->state, FW_DEVICE_SHUTDOWN); ++ fw_device_shutdown(work); ++ out: ++ if (node_id == card->root_node->node_id) ++ schedule_delayed_work(&card->work, 0); ++} ++ + void fw_node_event(struct fw_card *card, struct fw_node *node, int event) + { + struct fw_device *device; +@@ -780,7 +930,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) + case FW_NODE_LINK_ON: + if (!node->link_on) + break; +- ++ create: + device = kzalloc(sizeof(*device), GFP_ATOMIC); + if (device == NULL) + break; +@@ -819,6 +969,23 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) + schedule_delayed_work(&device->work, INITIAL_DELAY); + break; + ++ case FW_NODE_INITIATED_RESET: ++ device = node->data; ++ if (device == NULL) ++ goto create; ++ ++ device->node_id = node->node_id; ++ smp_wmb(); /* update node_id before generation */ ++ device->generation = card->generation; ++ if (atomic_cmpxchg(&device->state, ++ FW_DEVICE_RUNNING, ++ FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) { ++ PREPARE_DELAYED_WORK(&device->work, fw_device_refresh); ++ schedule_delayed_work(&device->work, ++ node == card->local_node ? 0 : INITIAL_DELAY); ++ } ++ break; ++ + case FW_NODE_UPDATED: + if (!node->link_on || node->data == NULL) + break; +diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h +index 78ecd39..5f131f5 100644 +--- a/drivers/firewire/fw-device.h ++++ b/drivers/firewire/fw-device.h +@@ -21,6 +21,7 @@ + + #include + #include ++#include + #include + + enum fw_device_state { +@@ -46,6 +47,11 @@ struct fw_attribute_group { + * fw_device.node_id is guaranteed to be current too. + * + * The same applies to fw_device.card->node_id vs. fw_device.generation. ++ * ++ * fw_device.config_rom and fw_device.config_rom_length may be accessed during ++ * the lifetime of any fw_unit belonging to the fw_device, before device_del() ++ * was called on the last fw_unit. Alternatively, they may be accessed while ++ * holding fw_device_rwsem. + */ + struct fw_device { + atomic_t state; +@@ -53,6 +59,7 @@ struct fw_device { + int node_id; + int generation; + unsigned max_speed; ++ bool cmc; + struct fw_card *card; + struct device device; + struct list_head link; +@@ -64,28 +71,24 @@ struct fw_device { + struct fw_attribute_group attribute_group; + }; + +-static inline struct fw_device * +-fw_device(struct device *dev) ++static inline struct fw_device *fw_device(struct device *dev) + { + return container_of(dev, struct fw_device, device); + } + +-static inline int +-fw_device_is_shutdown(struct fw_device *device) ++static inline int fw_device_is_shutdown(struct fw_device *device) + { + return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN; + } + +-static inline struct fw_device * +-fw_device_get(struct fw_device *device) ++static inline struct fw_device *fw_device_get(struct fw_device *device) + { + get_device(&device->device); + + return device; + } + +-static inline void +-fw_device_put(struct fw_device *device) ++static inline void fw_device_put(struct fw_device *device) + { + put_device(&device->device); + } +@@ -96,20 +99,35 @@ int fw_device_enable_phys_dma(struct fw_device *device); + void fw_device_cdev_update(struct fw_device *device); + void fw_device_cdev_remove(struct fw_device *device); + ++extern struct rw_semaphore fw_device_rwsem; + extern int fw_cdev_major; + ++/* ++ * fw_unit.directory must not be accessed after device_del(&fw_unit.device). ++ */ + struct fw_unit { + struct device device; + u32 *directory; + struct fw_attribute_group attribute_group; + }; + +-static inline struct fw_unit * +-fw_unit(struct device *dev) ++static inline struct fw_unit *fw_unit(struct device *dev) + { + return container_of(dev, struct fw_unit, device); + } + ++static inline struct fw_unit *fw_unit_get(struct fw_unit *unit) ++{ ++ get_device(&unit->device); ++ ++ return unit; ++} ++ ++static inline void fw_unit_put(struct fw_unit *unit) ++{ ++ put_device(&unit->device); ++} ++ + #define CSR_OFFSET 0x40 + #define CSR_LEAF 0x80 + #define CSR_DIRECTORY 0xc0 +diff --git a/drivers/firewire/fw-iso.c b/drivers/firewire/fw-iso.c +index 2b640e9..bcbe794 100644 +--- a/drivers/firewire/fw-iso.c ++++ b/drivers/firewire/fw-iso.c +@@ -126,7 +126,6 @@ fw_iso_context_create(struct fw_card *card, int type, + + return ctx; + } +-EXPORT_SYMBOL(fw_iso_context_create); + + void fw_iso_context_destroy(struct fw_iso_context *ctx) + { +@@ -134,14 +133,12 @@ void fw_iso_context_destroy(struct fw_iso_context *ctx) + + card->driver->free_iso_context(ctx); + } +-EXPORT_SYMBOL(fw_iso_context_destroy); + + 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); + } +-EXPORT_SYMBOL(fw_iso_context_start); + + int + fw_iso_context_queue(struct fw_iso_context *ctx, +@@ -153,11 +150,9 @@ fw_iso_context_queue(struct fw_iso_context *ctx, + + return card->driver->queue_iso(ctx, packet, buffer, payload); + } +-EXPORT_SYMBOL(fw_iso_context_queue); + + int + fw_iso_context_stop(struct fw_iso_context *ctx) + { + return ctx->card->driver->stop_iso(ctx); + } +-EXPORT_SYMBOL(fw_iso_context_stop); +diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c +index ca6d51e..3d4ef3f 100644 +--- a/drivers/firewire/fw-ohci.c ++++ b/drivers/firewire/fw-ohci.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -177,7 +178,7 @@ struct fw_ohci { + struct tasklet_struct bus_reset_tasklet; + int node_id; + int generation; +- int request_generation; ++ int request_generation; /* for timestamping incoming requests */ + u32 bus_seconds; + bool old_uninorth; + +@@ -237,6 +238,179 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) + + static char ohci_driver_name[] = KBUILD_MODNAME; + ++#ifdef CONFIG_FIREWIRE_OHCI_DEBUG ++ ++#define OHCI_PARAM_DEBUG_IRQS 1 ++#define OHCI_PARAM_DEBUG_SELFIDS 2 ++#define OHCI_PARAM_DEBUG_AT_AR 4 ++ ++static int param_debug; ++module_param_named(debug, param_debug, int, 0644); ++MODULE_PARM_DESC(debug, "Verbose logging (default = 0" ++ ", IRQs = " __stringify(OHCI_PARAM_DEBUG_IRQS) ++ ", self-IDs = " __stringify(OHCI_PARAM_DEBUG_SELFIDS) ++ ", AT/AR events = " __stringify(OHCI_PARAM_DEBUG_AT_AR) ++ ", or a combination, or all = -1)"); ++ ++static void log_irqs(u32 evt) ++{ ++ if (likely(!(param_debug & OHCI_PARAM_DEBUG_IRQS))) ++ return; ++ ++ printk(KERN_DEBUG KBUILD_MODNAME ": IRQ %08x%s%s%s%s%s%s%s%s%s%s%s\n", ++ evt, ++ evt & OHCI1394_selfIDComplete ? " selfID" : "", ++ evt & OHCI1394_RQPkt ? " AR_req" : "", ++ evt & OHCI1394_RSPkt ? " AR_resp" : "", ++ evt & OHCI1394_reqTxComplete ? " AT_req" : "", ++ evt & OHCI1394_respTxComplete ? " AT_resp" : "", ++ evt & OHCI1394_isochRx ? " IR" : "", ++ evt & OHCI1394_isochTx ? " IT" : "", ++ evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", ++ evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", ++ evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "", ++ evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt | ++ OHCI1394_RSPkt | OHCI1394_reqTxComplete | ++ OHCI1394_respTxComplete | OHCI1394_isochRx | ++ OHCI1394_isochTx | OHCI1394_postedWriteErr | ++ OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds) ++ ? " ?" : ""); ++} ++ ++static const char *speed[] = { ++ [0] = "S100", [1] = "S200", [2] = "S400", [3] = "beta", ++}; ++static const char *power[] = { ++ [0] = "+0W", [1] = "+15W", [2] = "+30W", [3] = "+45W", ++ [4] = "-3W", [5] = " ?W", [6] = "-3..-6W", [7] = "-3..-10W", ++}; ++static const char port[] = { '.', '-', 'p', 'c', }; ++ ++static char _p(u32 *s, int shift) ++{ ++ return port[*s >> shift & 3]; ++} ++ ++static void log_selfids(int generation, int self_id_count, u32 *s) ++{ ++ if (likely(!(param_debug & OHCI_PARAM_DEBUG_SELFIDS))) ++ return; ++ ++ printk(KERN_DEBUG KBUILD_MODNAME ": %d selfIDs, generation %d\n", ++ self_id_count, generation); ++ ++ for (; self_id_count--; ++s) ++ if ((*s & 1 << 23) == 0) ++ printk(KERN_DEBUG "selfID 0: %08x, phy %d [%c%c%c] " ++ "%s gc=%d %s %s%s%s\n", ++ *s, *s >> 24 & 63, _p(s, 6), _p(s, 4), _p(s, 2), ++ speed[*s >> 14 & 3], *s >> 16 & 63, ++ power[*s >> 8 & 7], *s >> 22 & 1 ? "L" : "", ++ *s >> 11 & 1 ? "c" : "", *s & 2 ? "i" : ""); ++ else ++ printk(KERN_DEBUG "selfID n: %08x, phy %d " ++ "[%c%c%c%c%c%c%c%c]\n", ++ *s, *s >> 24 & 63, ++ _p(s, 16), _p(s, 14), _p(s, 12), _p(s, 10), ++ _p(s, 8), _p(s, 6), _p(s, 4), _p(s, 2)); ++} ++ ++static const char *evts[] = { ++ [0x00] = "evt_no_status", [0x01] = "-reserved-", ++ [0x02] = "evt_long_packet", [0x03] = "evt_missing_ack", ++ [0x04] = "evt_underrun", [0x05] = "evt_overrun", ++ [0x06] = "evt_descriptor_read", [0x07] = "evt_data_read", ++ [0x08] = "evt_data_write", [0x09] = "evt_bus_reset", ++ [0x0a] = "evt_timeout", [0x0b] = "evt_tcode_err", ++ [0x0c] = "-reserved-", [0x0d] = "-reserved-", ++ [0x0e] = "evt_unknown", [0x0f] = "evt_flushed", ++ [0x10] = "-reserved-", [0x11] = "ack_complete", ++ [0x12] = "ack_pending ", [0x13] = "-reserved-", ++ [0x14] = "ack_busy_X", [0x15] = "ack_busy_A", ++ [0x16] = "ack_busy_B", [0x17] = "-reserved-", ++ [0x18] = "-reserved-", [0x19] = "-reserved-", ++ [0x1a] = "-reserved-", [0x1b] = "ack_tardy", ++ [0x1c] = "-reserved-", [0x1d] = "ack_data_error", ++ [0x1e] = "ack_type_error", [0x1f] = "-reserved-", ++ [0x20] = "pending/cancelled", ++}; ++static const char *tcodes[] = { ++ [0x0] = "QW req", [0x1] = "BW req", ++ [0x2] = "W resp", [0x3] = "-reserved-", ++ [0x4] = "QR req", [0x5] = "BR req", ++ [0x6] = "QR resp", [0x7] = "BR resp", ++ [0x8] = "cycle start", [0x9] = "Lk req", ++ [0xa] = "async stream packet", [0xb] = "Lk resp", ++ [0xc] = "-reserved-", [0xd] = "-reserved-", ++ [0xe] = "link internal", [0xf] = "-reserved-", ++}; ++static const char *phys[] = { ++ [0x0] = "phy config packet", [0x1] = "link-on packet", ++ [0x2] = "self-id packet", [0x3] = "-reserved-", ++}; ++ ++static void log_ar_at_event(char dir, int speed, u32 *header, int evt) ++{ ++ int tcode = header[0] >> 4 & 0xf; ++ char specific[12]; ++ ++ if (likely(!(param_debug & OHCI_PARAM_DEBUG_AT_AR))) ++ return; ++ ++ if (unlikely(evt >= ARRAY_SIZE(evts))) ++ evt = 0x1f; ++ ++ if (header[0] == ~header[1]) { ++ printk(KERN_DEBUG "A%c %s, %s, %08x\n", ++ dir, evts[evt], phys[header[0] >> 30 & 0x3], ++ header[0]); ++ return; ++ } ++ ++ switch (tcode) { ++ case 0x0: case 0x6: case 0x8: ++ snprintf(specific, sizeof(specific), " = %08x", ++ be32_to_cpu((__force __be32)header[3])); ++ break; ++ case 0x1: case 0x5: case 0x7: case 0x9: case 0xb: ++ snprintf(specific, sizeof(specific), " %x,%x", ++ header[3] >> 16, header[3] & 0xffff); ++ break; ++ default: ++ specific[0] = '\0'; ++ } ++ ++ switch (tcode) { ++ case 0xe: case 0xa: ++ printk(KERN_DEBUG "A%c %s, %s\n", ++ dir, evts[evt], tcodes[tcode]); ++ break; ++ case 0x0: case 0x1: case 0x4: case 0x5: case 0x9: ++ printk(KERN_DEBUG "A%c spd %x tl %02x, " ++ "%04x -> %04x, %s, " ++ "%s, %04x%08x%s\n", ++ dir, speed, header[0] >> 10 & 0x3f, ++ header[1] >> 16, header[0] >> 16, evts[evt], ++ tcodes[tcode], header[1] & 0xffff, header[2], specific); ++ break; ++ default: ++ printk(KERN_DEBUG "A%c spd %x tl %02x, " ++ "%04x -> %04x, %s, " ++ "%s%s\n", ++ dir, speed, header[0] >> 10 & 0x3f, ++ header[1] >> 16, header[0] >> 16, evts[evt], ++ tcodes[tcode], specific); ++ } ++} ++ ++#else ++ ++#define log_irqs(evt) ++#define log_selfids(generation, self_id_count, sid) ++#define log_ar_at_event(dir, speed, header, evt) ++ ++#endif /* CONFIG_FIREWIRE_OHCI_DEBUG */ ++ + static inline void reg_write(const struct fw_ohci *ohci, int offset, u32 data) + { + writel(data, ohci->registers + offset); +@@ -320,6 +494,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) + struct fw_ohci *ohci = ctx->ohci; + struct fw_packet p; + u32 status, length, tcode; ++ int evt; + + p.header[0] = cond_le32_to_cpu(buffer[0]); + p.header[1] = cond_le32_to_cpu(buffer[1]); +@@ -362,12 +537,15 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) + /* FIXME: What to do about evt_* errors? */ + length = (p.header_length + p.payload_length + 3) / 4; + status = cond_le32_to_cpu(buffer[length]); ++ evt = (status >> 16) & 0x1f; + +- p.ack = ((status >> 16) & 0x1f) - 16; ++ p.ack = evt - 16; + p.speed = (status >> 21) & 0x7; + p.timestamp = status & 0xffff; + p.generation = ohci->request_generation; + ++ log_ar_at_event('R', p.speed, p.header, evt); ++ + /* + * The OHCI bus reset handler synthesizes a phy packet with + * the new generation number when a bus reset happens (see +@@ -378,7 +556,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) + * request. + */ + +- if (p.ack + 16 == 0x09) ++ if (evt == OHCI1394_evt_bus_reset) + ohci->request_generation = (p.header[2] >> 16) & 0xff; + else if (ctx == &ohci->ar_request_ctx) + fw_core_handle_request(&ohci->card, &p); +@@ -817,6 +995,8 @@ static int handle_at_packet(struct context *context, + evt = le16_to_cpu(last->transfer_status) & 0x1f; + packet->timestamp = le16_to_cpu(last->res_count); + ++ log_ar_at_event('T', packet->speed, packet->header, evt); ++ + switch (evt) { + case OHCI1394_evt_timeout: + /* Async response transmit timed out. */ +@@ -1019,20 +1199,30 @@ static void bus_reset_tasklet(unsigned long data) + ohci->node_id = reg & (OHCI1394_NodeID_busNumber | + OHCI1394_NodeID_nodeNumber); + ++ reg = reg_read(ohci, OHCI1394_SelfIDCount); ++ if (reg & OHCI1394_SelfIDCount_selfIDError) { ++ fw_notify("inconsistent self IDs\n"); ++ return; ++ } + /* + * The count in the SelfIDCount register is the number of + * bytes in the self ID receive buffer. Since we also receive + * the inverted quadlets and a header quadlet, we shift one + * bit extra to get the actual number of self IDs. + */ +- +- self_id_count = (reg_read(ohci, OHCI1394_SelfIDCount) >> 3) & 0x3ff; ++ self_id_count = (reg >> 3) & 0x3ff; ++ if (self_id_count == 0) { ++ fw_notify("inconsistent self IDs\n"); ++ return; ++ } + generation = (cond_le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff; + rmb(); + + for (i = 1, j = 0; j < self_id_count; i += 2, j++) { +- if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1]) +- fw_error("inconsistent self IDs\n"); ++ if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1]) { ++ fw_notify("inconsistent self IDs\n"); ++ return; ++ } + ohci->self_id_buffer[j] = + cond_le32_to_cpu(ohci->self_id_cpu[i]); + } +@@ -1097,12 +1287,19 @@ static void bus_reset_tasklet(unsigned long data) + reg_write(ohci, OHCI1394_ConfigROMhdr, ohci->next_header); + } + ++#ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA ++ reg_write(ohci, OHCI1394_PhyReqFilterHiSet, ~0); ++ reg_write(ohci, OHCI1394_PhyReqFilterLoSet, ~0); ++#endif ++ + spin_unlock_irqrestore(&ohci->lock, flags); + + if (free_rom) + dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, + free_rom, free_rom_bus); + ++ log_selfids(generation, self_id_count, ohci->self_id_buffer); ++ + fw_core_handle_bus_reset(&ohci->card, ohci->node_id, generation, + self_id_count, ohci->self_id_buffer); + } +@@ -1119,6 +1316,7 @@ static irqreturn_t irq_handler(int irq, void *data) + return IRQ_NONE; + + reg_write(ohci, OHCI1394_IntEventClear, event); ++ log_irqs(event); + + if (event & OHCI1394_selfIDComplete) + tasklet_schedule(&ohci->bus_reset_tasklet); +@@ -1192,6 +1390,8 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) + { + struct fw_ohci *ohci = fw_ohci(card); + struct pci_dev *dev = to_pci_dev(card->device); ++ u32 lps; ++ int i; + + if (software_reset(ohci)) { + fw_error("Failed to reset ohci card.\n"); +@@ -1203,13 +1403,24 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) + * most of the registers. In fact, on some cards (ALI M5251), + * accessing registers in the SClk domain without LPS enabled + * will lock up the machine. Wait 50msec to make sure we have +- * full link enabled. ++ * full link enabled. However, with some cards (well, at least ++ * a JMicron PCIe card), we have to try again sometimes. + */ + reg_write(ohci, OHCI1394_HCControlSet, + OHCI1394_HCControl_LPS | + OHCI1394_HCControl_postedWriteEnable); + flush_writes(ohci); +- msleep(50); ++ ++ for (lps = 0, i = 0; !lps && i < 3; i++) { ++ msleep(50); ++ lps = reg_read(ohci, OHCI1394_HCControlSet) & ++ OHCI1394_HCControl_LPS; ++ } ++ ++ if (!lps) { ++ fw_error("Failed to set Link Power Status\n"); ++ return -EIO; ++ } + + reg_write(ohci, OHCI1394_HCControlClear, + OHCI1394_HCControl_noByteSwapData); +@@ -1421,6 +1632,7 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet) + if (packet->ack != 0) + goto out; + ++ log_ar_at_event('T', packet->speed, packet->header, 0x20); + driver_data->packet = NULL; + packet->ack = RCODE_CANCELLED; + packet->callback(packet, &ohci->card, packet->ack); +@@ -1435,6 +1647,9 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet) + 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; +@@ -1466,6 +1681,7 @@ ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation) + out: + spin_unlock_irqrestore(&ohci->lock, flags); + return retval; ++#endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */ + } + + static u64 +@@ -2045,17 +2261,9 @@ static const struct fw_card_driver ohci_driver = { + .stop_iso = ohci_stop_iso, + }; + +-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; +- u64 guid; +- int err; +- size_t size; +- + #ifdef CONFIG_PPC_PMAC +- /* Necessary on some machines if fw-ohci was loaded/ unloaded before */ ++static void ohci_pmac_on(struct pci_dev *dev) ++{ + if (machine_is(powermac)) { + struct device_node *ofn = pci_device_to_OF_node(dev); + +@@ -2064,8 +2272,33 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) + pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1); + } + } ++} ++ ++static void ohci_pmac_off(struct pci_dev *dev) ++{ ++ if (machine_is(powermac)) { ++ struct device_node *ofn = pci_device_to_OF_node(dev); ++ ++ if (ofn) { ++ pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0); ++ pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 0); ++ } ++ } ++} ++#else ++#define ohci_pmac_on(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) ++{ ++ struct fw_ohci *ohci; ++ u32 bus_options, max_receive, link_speed; ++ u64 guid; ++ int err; ++ size_t size; ++ + ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); + if (ohci == NULL) { + fw_error("Could not malloc fw_ohci data.\n"); +@@ -2074,10 +2307,12 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) + + fw_card_initialize(&ohci->card, &ohci_driver, &dev->dev); + ++ ohci_pmac_on(dev); ++ + err = pci_enable_device(dev); + if (err) { + fw_error("Failed to enable OHCI hardware.\n"); +- goto fail_put_card; ++ goto fail_free; + } + + pci_set_master(dev); +@@ -2173,8 +2408,9 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) + pci_release_region(dev, 0); + fail_disable: + pci_disable_device(dev); +- fail_put_card: +- fw_card_put(&ohci->card); ++ fail_free: ++ kfree(&ohci->card); ++ ohci_pmac_off(dev); + + return err; + } +@@ -2202,72 +2438,42 @@ static void pci_remove(struct pci_dev *dev) + pci_iounmap(dev, ohci->registers); + pci_release_region(dev, 0); + pci_disable_device(dev); +- fw_card_put(&ohci->card); +- +-#ifdef CONFIG_PPC_PMAC +- /* On UniNorth, power down the cable and turn off the chip clock +- * to save power on laptops */ +- if (machine_is(powermac)) { +- struct device_node *ofn = pci_device_to_OF_node(dev); +- +- if (ofn) { +- pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0); +- pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 0); +- } +- } +-#endif /* CONFIG_PPC_PMAC */ ++ kfree(&ohci->card); ++ ohci_pmac_off(dev); + + fw_notify("Removed fw-ohci device.\n"); + } + + #ifdef CONFIG_PM +-static int pci_suspend(struct pci_dev *pdev, pm_message_t state) ++static int pci_suspend(struct pci_dev *dev, pm_message_t state) + { +- struct fw_ohci *ohci = pci_get_drvdata(pdev); ++ struct fw_ohci *ohci = pci_get_drvdata(dev); + int err; + + software_reset(ohci); +- free_irq(pdev->irq, ohci); +- err = pci_save_state(pdev); ++ free_irq(dev->irq, ohci); ++ err = pci_save_state(dev); + if (err) { + fw_error("pci_save_state failed\n"); + return err; + } +- err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); ++ err = pci_set_power_state(dev, pci_choose_state(dev, state)); + if (err) + fw_error("pci_set_power_state failed with %d\n", err); +- +-/* PowerMac suspend code comes last */ +-#ifdef CONFIG_PPC_PMAC +- if (machine_is(powermac)) { +- struct device_node *ofn = pci_device_to_OF_node(pdev); +- +- if (ofn) +- pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0); +- } +-#endif /* CONFIG_PPC_PMAC */ ++ ohci_pmac_off(dev); + + return 0; + } + +-static int pci_resume(struct pci_dev *pdev) ++static int pci_resume(struct pci_dev *dev) + { +- struct fw_ohci *ohci = pci_get_drvdata(pdev); ++ struct fw_ohci *ohci = pci_get_drvdata(dev); + int err; + +-/* PowerMac resume code comes first */ +-#ifdef CONFIG_PPC_PMAC +- if (machine_is(powermac)) { +- struct device_node *ofn = pci_device_to_OF_node(pdev); +- +- if (ofn) +- pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1); +- } +-#endif /* CONFIG_PPC_PMAC */ +- +- pci_set_power_state(pdev, PCI_D0); +- pci_restore_state(pdev); +- err = pci_enable_device(pdev); ++ ohci_pmac_on(dev); ++ pci_set_power_state(dev, PCI_D0); ++ pci_restore_state(dev); ++ err = pci_enable_device(dev); + if (err) { + fw_error("pci_enable_device failed\n"); + return err; +diff --git a/drivers/firewire/fw-ohci.h b/drivers/firewire/fw-ohci.h +index dec4f04..5754c6e 100644 +--- a/drivers/firewire/fw-ohci.h ++++ b/drivers/firewire/fw-ohci.h +@@ -30,6 +30,7 @@ + #define OHCI1394_HCControl_softReset 0x00010000 + #define OHCI1394_SelfIDBuffer 0x064 + #define OHCI1394_SelfIDCount 0x068 ++#define OHCI1394_SelfIDCount_selfIDError 0x80000000 + #define OHCI1394_IRMultiChanMaskHiSet 0x070 + #define OHCI1394_IRMultiChanMaskHiClear 0x074 + #define OHCI1394_IRMultiChanMaskLoSet 0x078 +diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c +index 62b4e47..2a99937 100644 +--- a/drivers/firewire/fw-sbp2.c ++++ b/drivers/firewire/fw-sbp2.c +@@ -153,6 +153,7 @@ struct sbp2_target { + struct list_head lu_list; + + u64 management_agent_address; ++ u64 guid; + int directory_id; + int node_id; + int address_high; +@@ -173,10 +174,8 @@ struct sbp2_target { + #define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */ + #define SBP2_ORB_NULL 0x80000000 + #define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000 +-#define SBP2_RETRY_LIMIT 0xf /* 15 retries */ +- +-#define SBP2_DIRECTION_TO_MEDIA 0x0 +-#define SBP2_DIRECTION_FROM_MEDIA 0x1 ++#define SBP2_RETRY_LIMIT 0xf /* 15 retries */ ++#define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */ + + /* Unit directory keys */ + #define SBP2_CSR_UNIT_CHARACTERISTICS 0x3a +@@ -224,8 +223,8 @@ struct sbp2_status { + }; + + struct sbp2_pointer { +- u32 high; +- u32 low; ++ __be32 high; ++ __be32 low; + }; + + struct sbp2_orb { +@@ -253,8 +252,8 @@ struct sbp2_management_orb { + struct { + struct sbp2_pointer password; + struct sbp2_pointer response; +- u32 misc; +- u32 length; ++ __be32 misc; ++ __be32 length; + struct sbp2_pointer status_fifo; + } request; + __be32 response[4]; +@@ -263,20 +262,17 @@ struct sbp2_management_orb { + struct sbp2_status status; + }; + +-#define LOGIN_RESPONSE_GET_LOGIN_ID(v) ((v).misc & 0xffff) +-#define LOGIN_RESPONSE_GET_LENGTH(v) (((v).misc >> 16) & 0xffff) +- + struct sbp2_login_response { +- u32 misc; ++ __be32 misc; + struct sbp2_pointer command_block_agent; +- u32 reconnect_hold; ++ __be32 reconnect_hold; + }; + #define COMMAND_ORB_DATA_SIZE(v) ((v)) + #define COMMAND_ORB_PAGE_SIZE(v) ((v) << 16) + #define COMMAND_ORB_PAGE_TABLE_PRESENT ((1) << 19) + #define COMMAND_ORB_MAX_PAYLOAD(v) ((v) << 20) + #define COMMAND_ORB_SPEED(v) ((v) << 24) +-#define COMMAND_ORB_DIRECTION(v) ((v) << 27) ++#define COMMAND_ORB_DIRECTION ((1) << 27) + #define COMMAND_ORB_REQUEST_FORMAT(v) ((v) << 29) + #define COMMAND_ORB_NOTIFY ((1) << 31) + +@@ -285,7 +281,7 @@ struct sbp2_command_orb { + struct { + struct sbp2_pointer next; + struct sbp2_pointer data_descriptor; +- u32 misc; ++ __be32 misc; + u8 command_block[12]; + } request; + struct scsi_cmnd *cmd; +@@ -459,8 +455,7 @@ sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, + unsigned long flags; + + orb->pointer.high = 0; +- orb->pointer.low = orb->request_bus; +- fw_memcpy_to_be32(&orb->pointer, &orb->pointer, sizeof(orb->pointer)); ++ orb->pointer.low = cpu_to_be32(orb->request_bus); + + spin_lock_irqsave(&device->card->lock, flags); + list_add_tail(&orb->link, &lu->orb_list); +@@ -536,31 +531,31 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, + if (dma_mapping_error(orb->response_bus)) + goto fail_mapping_response; + +- orb->request.response.high = 0; +- orb->request.response.low = orb->response_bus; ++ orb->request.response.high = 0; ++ orb->request.response.low = cpu_to_be32(orb->response_bus); + +- orb->request.misc = ++ orb->request.misc = cpu_to_be32( + MANAGEMENT_ORB_NOTIFY | + MANAGEMENT_ORB_FUNCTION(function) | +- MANAGEMENT_ORB_LUN(lun_or_login_id); +- orb->request.length = +- MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof(orb->response)); ++ MANAGEMENT_ORB_LUN(lun_or_login_id)); ++ orb->request.length = cpu_to_be32( ++ MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof(orb->response))); + +- orb->request.status_fifo.high = lu->address_handler.offset >> 32; +- orb->request.status_fifo.low = lu->address_handler.offset; ++ orb->request.status_fifo.high = ++ cpu_to_be32(lu->address_handler.offset >> 32); ++ orb->request.status_fifo.low = ++ cpu_to_be32(lu->address_handler.offset); + + if (function == SBP2_LOGIN_REQUEST) { + /* Ask for 2^2 == 4 seconds reconnect grace period */ +- orb->request.misc |= ++ orb->request.misc |= cpu_to_be32( + MANAGEMENT_ORB_RECONNECT(2) | +- MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login); ++ MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login)); + timeout = lu->tgt->mgt_orb_timeout; + } else { + timeout = SBP2_ORB_TIMEOUT; + } + +- fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request)); +- + init_completion(&orb->done); + orb->base.callback = complete_management_orb; + +@@ -605,8 +600,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, + sizeof(orb->response), DMA_FROM_DEVICE); + fail_mapping_response: + if (response) +- fw_memcpy_from_be32(response, +- orb->response, sizeof(orb->response)); ++ memcpy(response, orb->response, sizeof(orb->response)); + kref_put(&orb->base.kref, free_orb); + + return retval; +@@ -701,10 +695,8 @@ static void sbp2_conditionally_block(struct sbp2_logical_unit *lu) + if (!tgt->dont_block && !lu->blocked && + lu->generation != card->generation) { + lu->blocked = true; +- if (++tgt->blocked == 1) { ++ if (++tgt->blocked == 1) + scsi_block_requests(shost); +- fw_notify("blocked %s\n", lu->tgt->bus_id); +- } + } + spin_unlock_irqrestore(&card->lock, flags); + } +@@ -731,10 +723,8 @@ static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu) + } + spin_unlock_irqrestore(&card->lock, flags); + +- if (unblock) { ++ if (unblock) + scsi_unblock_requests(shost); +- fw_notify("unblocked %s\n", lu->tgt->bus_id); +- } + } + + /* +@@ -796,7 +786,7 @@ static void sbp2_release_target(struct kref *kref) + scsi_remove_host(shost); + fw_notify("released %s\n", tgt->bus_id); + +- put_device(&tgt->unit->device); ++ fw_unit_put(tgt->unit); + scsi_host_put(shost); + fw_device_put(device); + } +@@ -825,6 +815,22 @@ complete_set_busy_timeout(struct fw_card *card, int rcode, + complete(done); + } + ++/* ++ * Write retransmit retry values into the BUSY_TIMEOUT register. ++ * - The single-phase retry protocol is supported by all SBP-2 devices, but the ++ * default retry_limit value is 0 (i.e. never retry transmission). We write a ++ * saner value after logging into the device. ++ * - The dual-phase retry protocol is optional to implement, and if not ++ * supported, writes to the dual-phase portion of the register will be ++ * ignored. We try to write the original 1394-1995 default here. ++ * - In the case of devices that are also SBP-3-compliant, all writes are ++ * ignored, as the register is read-only, but contains single-phase retry of ++ * 15, which is what we're trying to set for all SBP-2 device anyway, so this ++ * write attempt is safe and yields more consistent behavior for all devices. ++ * ++ * See section 8.3.2.3.5 of the 1394-1995 spec, section 6.2 of the SBP-2 spec, ++ * and section 6.4 of the SBP-3 spec for further details. ++ */ + static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu) + { + struct fw_device *device = fw_device(lu->tgt->unit->device.parent); +@@ -832,8 +838,7 @@ static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu) + struct fw_transaction t; + static __be32 busy_timeout; + +- /* FIXME: we should try to set dual-phase cycle_limit too */ +- busy_timeout = cpu_to_be32(SBP2_RETRY_LIMIT); ++ busy_timeout = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT); + + fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST, + lu->tgt->node_id, lu->generation, device->max_speed, +@@ -885,11 +890,10 @@ static void sbp2_login(struct work_struct *work) + tgt->address_high = local_node_id << 16; + sbp2_set_generation(lu, generation); + +- /* Get command block agent offset and login id. */ + lu->command_block_agent_address = +- ((u64) (response.command_block_agent.high & 0xffff) << 32) | +- response.command_block_agent.low; +- lu->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response); ++ ((u64)(be32_to_cpu(response.command_block_agent.high) & 0xffff) ++ << 32) | be32_to_cpu(response.command_block_agent.low); ++ lu->login_id = be32_to_cpu(response.misc) & 0xffff; + + fw_notify("%s: logged in to LUN %04x (%d retries)\n", + tgt->bus_id, lu->lun, lu->retries); +@@ -1111,6 +1115,7 @@ static int sbp2_probe(struct device *dev) + kref_init(&tgt->kref); + INIT_LIST_HEAD(&tgt->lu_list); + tgt->bus_id = unit->device.bus_id; ++ tgt->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4]; + + if (fw_device_enable_phys_dma(device) < 0) + goto fail_shost_put; +@@ -1119,6 +1124,7 @@ static int sbp2_probe(struct device *dev) + goto fail_shost_put; + + fw_device_get(device); ++ fw_unit_get(unit); + + /* Initialize to values that won't match anything in our table. */ + firmware_revision = 0xff000000; +@@ -1134,8 +1140,6 @@ static int sbp2_probe(struct device *dev) + + sbp2_init_workarounds(tgt, model, firmware_revision); + +- get_device(&unit->device); +- + /* Do the login in a workqueue so we can easily reschedule retries. */ + list_for_each_entry(lu, &tgt->lu_list, link) + sbp2_queue_work(lu, 0); +@@ -1367,9 +1371,12 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device, + * tables. + */ + if (count == 1 && sg_dma_len(sg) < SBP2_MAX_SG_ELEMENT_LENGTH) { +- orb->request.data_descriptor.high = lu->tgt->address_high; +- orb->request.data_descriptor.low = sg_dma_address(sg); +- orb->request.misc |= COMMAND_ORB_DATA_SIZE(sg_dma_len(sg)); ++ orb->request.data_descriptor.high = ++ cpu_to_be32(lu->tgt->address_high); ++ orb->request.data_descriptor.low = ++ cpu_to_be32(sg_dma_address(sg)); ++ orb->request.misc |= ++ cpu_to_be32(COMMAND_ORB_DATA_SIZE(sg_dma_len(sg))); + return 0; + } + +@@ -1390,16 +1397,14 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device, + goto fail_page_table; + } + l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH); +- orb->page_table[j].low = sg_addr; +- orb->page_table[j].high = (l << 16); ++ orb->page_table[j].low = cpu_to_be32(sg_addr); ++ orb->page_table[j].high = cpu_to_be32(l << 16); + sg_addr += l; + sg_len -= l; + j++; + } + } + +- fw_memcpy_to_be32(orb->page_table, orb->page_table, +- sizeof(orb->page_table[0]) * j); + orb->page_table_bus = + dma_map_single(device->card->device, orb->page_table, + sizeof(orb->page_table), DMA_TO_DEVICE); +@@ -1413,11 +1418,10 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device, + * initiator (i.e. us), but data_descriptor can refer to data + * on other nodes so we need to put our ID in descriptor.high. + */ +- orb->request.data_descriptor.high = lu->tgt->address_high; +- orb->request.data_descriptor.low = orb->page_table_bus; +- orb->request.misc |= +- COMMAND_ORB_PAGE_TABLE_PRESENT | +- COMMAND_ORB_DATA_SIZE(j); ++ orb->request.data_descriptor.high = cpu_to_be32(lu->tgt->address_high); ++ orb->request.data_descriptor.low = cpu_to_be32(orb->page_table_bus); ++ orb->request.misc |= cpu_to_be32(COMMAND_ORB_PAGE_TABLE_PRESENT | ++ COMMAND_ORB_DATA_SIZE(j)); + + return 0; + +@@ -1463,8 +1467,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) + orb->done = done; + orb->cmd = cmd; + +- orb->request.next.high = SBP2_ORB_NULL; +- orb->request.next.low = 0x0; ++ orb->request.next.high = cpu_to_be32(SBP2_ORB_NULL); + /* + * At speed 100 we can do 512 bytes per packet, at speed 200, + * 1024 bytes per packet etc. The SBP-2 max_payload field +@@ -1473,25 +1476,17 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) + */ + max_payload = min(device->max_speed + 7, + device->card->max_receive - 1); +- orb->request.misc = ++ orb->request.misc = cpu_to_be32( + COMMAND_ORB_MAX_PAYLOAD(max_payload) | + COMMAND_ORB_SPEED(device->max_speed) | +- COMMAND_ORB_NOTIFY; ++ COMMAND_ORB_NOTIFY); + + if (cmd->sc_data_direction == DMA_FROM_DEVICE) +- orb->request.misc |= +- COMMAND_ORB_DIRECTION(SBP2_DIRECTION_FROM_MEDIA); +- else if (cmd->sc_data_direction == DMA_TO_DEVICE) +- orb->request.misc |= +- COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA); ++ orb->request.misc |= cpu_to_be32(COMMAND_ORB_DIRECTION); + + if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0) + goto out; + +- fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request)); +- +- memset(orb->request.command_block, +- 0, sizeof(orb->request.command_block)); + memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); + + orb->base.callback = complete_command_orb; +@@ -1519,11 +1514,8 @@ static int sbp2_scsi_slave_alloc(struct scsi_device *sdev) + + sdev->allow_restart = 1; + +- /* +- * Update the dma alignment (minimum alignment requirements for +- * start and end of DMA transfers) to be a sector +- */ +- blk_queue_update_dma_alignment(sdev->request_queue, 511); ++ /* SBP-2 requires quadlet alignment of the data buffers. */ ++ blk_queue_update_dma_alignment(sdev->request_queue, 4 - 1); + + if (lu->tgt->workarounds & SBP2_WORKAROUND_INQUIRY_36) + sdev->inquiry_len = 36; +@@ -1581,16 +1573,14 @@ sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr, + { + struct scsi_device *sdev = to_scsi_device(dev); + struct sbp2_logical_unit *lu; +- struct fw_device *device; + + if (!sdev) + return 0; + + lu = sdev->hostdata; +- device = fw_device(lu->tgt->unit->device.parent); + +- return sprintf(buf, "%08x%08x:%06x:%04x\n", +- device->config_rom[3], device->config_rom[4], ++ return sprintf(buf, "%016llx:%06x:%04x\n", ++ (unsigned long long)lu->tgt->guid, + lu->tgt->directory_id, lu->lun); + } + +diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c +index d2c7a3d..ffbf7d1 100644 +--- a/drivers/firewire/fw-topology.c ++++ b/drivers/firewire/fw-topology.c +@@ -108,6 +108,7 @@ static struct fw_node *fw_node_create(u32 sid, int port_count, int color) + node->node_id = LOCAL_BUS | SELF_ID_PHY_ID(sid); + node->link_on = SELF_ID_LINK_ON(sid); + node->phy_speed = SELF_ID_PHY_SPEED(sid); ++ node->initiated_reset = SELF_ID_PHY_INITIATOR(sid); + node->port_count = port_count; + + atomic_set(&node->ref_count, 1); +@@ -289,12 +290,11 @@ static struct fw_node *build_tree(struct fw_card *card, + beta_repeaters_present = true; + + /* +- * If all PHYs does not report the same gap count +- * setting, we fall back to 63 which will force a gap +- * count reconfiguration and a reset. ++ * If PHYs report different gap counts, set an invalid count ++ * which will force a gap count reconfiguration and a reset. + */ + if (SELF_ID_GAP_COUNT(q) != gap_count) +- gap_count = 63; ++ gap_count = 0; + + update_hop_count(node); + +@@ -431,6 +431,8 @@ update_tree(struct fw_card *card, struct fw_node *root) + event = FW_NODE_LINK_OFF; + else if (!node0->link_on && node1->link_on) + event = FW_NODE_LINK_ON; ++ else if (node1->initiated_reset && node1->link_on) ++ event = FW_NODE_INITIATED_RESET; + else + event = FW_NODE_UPDATED; + +@@ -510,6 +512,18 @@ fw_core_handle_bus_reset(struct fw_card *card, + + fw_flush_transactions(card); + ++ /* ++ * If the selfID buffer is not the immediate successor of the ++ * previously processed one, we cannot reliably compare the ++ * old and new topologies. ++ */ ++ if (!is_next_generation(generation, card->generation) && ++ card->local_node != NULL) { ++ fw_notify("skipped bus generations, destroying all nodes\n"); ++ fw_destroy_nodes(card); ++ card->bm_retries = 0; ++ } ++ + spin_lock_irqsave(&card->lock, flags); + + /* +diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h +index cedc1ec..addb9f8 100644 +--- a/drivers/firewire/fw-topology.h ++++ b/drivers/firewire/fw-topology.h +@@ -20,11 +20,12 @@ + #define __fw_topology_h + + enum { +- FW_NODE_CREATED = 0x00, +- FW_NODE_UPDATED = 0x01, +- FW_NODE_DESTROYED = 0x02, +- FW_NODE_LINK_ON = 0x03, +- FW_NODE_LINK_OFF = 0x04, ++ FW_NODE_CREATED, ++ FW_NODE_UPDATED, ++ FW_NODE_DESTROYED, ++ FW_NODE_LINK_ON, ++ FW_NODE_LINK_OFF, ++ FW_NODE_INITIATED_RESET, + }; + + struct fw_node { +diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c +index e6f1bda..3a59e9b 100644 +--- a/drivers/firewire/fw-transaction.c ++++ b/drivers/firewire/fw-transaction.c +@@ -18,6 +18,7 @@ + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + ++#include + #include + #include + #include +@@ -294,42 +295,40 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t, + } + EXPORT_SYMBOL(fw_send_request); + ++struct fw_phy_packet { ++ struct fw_packet packet; ++ struct completion done; ++}; ++ + static void + transmit_phy_packet_callback(struct fw_packet *packet, + struct fw_card *card, int status) + { +- kfree(packet); +-} +- +-static void send_phy_packet(struct fw_card *card, u32 data, int generation) +-{ +- struct fw_packet *packet; +- +- packet = kzalloc(sizeof(*packet), GFP_ATOMIC); +- if (packet == NULL) +- return; +- +- packet->header[0] = data; +- packet->header[1] = ~data; +- packet->header_length = 8; +- packet->payload_length = 0; +- packet->speed = SCODE_100; +- packet->generation = generation; +- packet->callback = transmit_phy_packet_callback; ++ struct fw_phy_packet *p = ++ container_of(packet, struct fw_phy_packet, packet); + +- card->driver->send_request(card, packet); ++ complete(&p->done); + } + + void fw_send_phy_config(struct fw_card *card, + int node_id, int generation, int gap_count) + { +- u32 q; +- +- q = PHY_IDENTIFIER(PHY_PACKET_CONFIG) | +- PHY_CONFIG_ROOT_ID(node_id) | +- PHY_CONFIG_GAP_COUNT(gap_count); +- +- send_phy_packet(card, q, generation); ++ struct fw_phy_packet p; ++ u32 data = PHY_IDENTIFIER(PHY_PACKET_CONFIG) | ++ PHY_CONFIG_ROOT_ID(node_id) | ++ PHY_CONFIG_GAP_COUNT(gap_count); ++ ++ p.packet.header[0] = data; ++ p.packet.header[1] = ~data; ++ p.packet.header_length = 8; ++ p.packet.payload_length = 0; ++ p.packet.speed = SCODE_100; ++ p.packet.generation = generation; ++ p.packet.callback = transmit_phy_packet_callback; ++ init_completion(&p.done); ++ ++ card->driver->send_request(card, &p.packet); ++ wait_for_completion(&p.done); + } + + void fw_flush_transactions(struct fw_card *card) +@@ -389,21 +388,21 @@ lookup_enclosing_address_handler(struct list_head *list, + static DEFINE_SPINLOCK(address_handler_lock); + static LIST_HEAD(address_handler_list); + +-const struct fw_address_region fw_low_memory_region = +- { .start = 0x000000000000ULL, .end = 0x000100000000ULL, }; + const struct fw_address_region fw_high_memory_region = + { .start = 0x000100000000ULL, .end = 0xffffe0000000ULL, }; ++EXPORT_SYMBOL(fw_high_memory_region); ++ ++#if 0 ++const struct fw_address_region fw_low_memory_region = ++ { .start = 0x000000000000ULL, .end = 0x000100000000ULL, }; + const struct fw_address_region fw_private_region = + { .start = 0xffffe0000000ULL, .end = 0xfffff0000000ULL, }; + const struct fw_address_region fw_csr_region = +- { .start = 0xfffff0000000ULL, .end = 0xfffff0000800ULL, }; ++ { .start = CSR_REGISTER_BASE, ++ .end = CSR_REGISTER_BASE | CSR_CONFIG_ROM_END, }; + const struct fw_address_region fw_unit_space_region = + { .start = 0xfffff0000900ULL, .end = 0x1000000000000ULL, }; +-EXPORT_SYMBOL(fw_low_memory_region); +-EXPORT_SYMBOL(fw_high_memory_region); +-EXPORT_SYMBOL(fw_private_region); +-EXPORT_SYMBOL(fw_csr_region); +-EXPORT_SYMBOL(fw_unit_space_region); ++#endif /* 0 */ + + /** + * Allocate a range of addresses in the node space of the OHCI +@@ -747,7 +746,8 @@ fw_core_handle_response(struct fw_card *card, struct fw_packet *p) + EXPORT_SYMBOL(fw_core_handle_response); + + static const struct fw_address_region topology_map_region = +- { .start = 0xfffff0001000ull, .end = 0xfffff0001400ull, }; ++ { .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, +@@ -785,7 +785,8 @@ static struct fw_address_handler topology_map = { + }; + + static const struct fw_address_region registers_region = +- { .start = 0xfffff0000000ull, .end = 0xfffff0000400ull, }; ++ { .start = CSR_REGISTER_BASE, ++ .end = CSR_REGISTER_BASE | CSR_CONFIG_ROM, }; + + static void + handle_registers(struct fw_card *card, struct fw_request *request, +@@ -794,7 +795,7 @@ handle_registers(struct fw_card *card, struct fw_request *request, + unsigned long long offset, + void *payload, size_t length, void *callback_data) + { +- int reg = offset - CSR_REGISTER_BASE; ++ int reg = offset & ~CSR_REGISTER_BASE; + unsigned long long bus_time; + __be32 *data = payload; + +diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h +index a43bb22..eb01e5c 100644 +--- a/drivers/firewire/fw-transaction.h ++++ b/drivers/firewire/fw-transaction.h +@@ -201,11 +201,7 @@ struct fw_address_region { + u64 end; + }; + +-extern const struct fw_address_region fw_low_memory_region; + extern const struct fw_address_region fw_high_memory_region; +-extern const struct fw_address_region fw_private_region; +-extern const struct fw_address_region fw_csr_region; +-extern const struct fw_address_region fw_unit_space_region; + + int fw_core_add_address_handler(struct fw_address_handler *handler, + const struct fw_address_region *region); +@@ -221,12 +217,9 @@ struct fw_card { + const struct fw_card_driver *driver; + struct device *device; + atomic_t device_count; +- struct kref kref; + + int node_id; + int generation; +- /* This is the generation used for timestamping incoming requests. */ +- int request_generation; + int current_tlabel, tlabel_mask; + struct list_head transaction_list; + struct timer_list flush_timer; +@@ -263,8 +256,14 @@ struct fw_card { + int bm_generation; + }; + +-struct fw_card *fw_card_get(struct fw_card *card); +-void fw_card_put(struct fw_card *card); ++/* ++ * Check whether new_generation is the immediate successor of old_generation. ++ * Take counter roll-over at 255 (as per to OHCI) into account. ++ */ ++static inline bool is_next_generation(int new_generation, int old_generation) ++{ ++ return (new_generation & 0xff) == ((old_generation + 1) & 0xff); ++} + + /* + * The iso packet format allows for an immediate header/payload part +diff --git a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c +index 52ac83e..c90be40 100644 +--- a/drivers/ieee1394/csr.c ++++ b/drivers/ieee1394/csr.c +@@ -133,8 +133,7 @@ static void host_reset(struct hpsb_host *host) + host->csr.state &= ~0x100; + } + +- host->csr.topology_map[1] = +- cpu_to_be32(be32_to_cpu(host->csr.topology_map[1]) + 1); ++ be32_add_cpu(&host->csr.topology_map[1], 1); + host->csr.topology_map[2] = cpu_to_be32(host->node_count << 16 + | host->selfid_count); + host->csr.topology_map[0] = +@@ -142,8 +141,7 @@ static void host_reset(struct hpsb_host *host) + | csr_crc16(host->csr.topology_map + 1, + host->selfid_count + 2)); + +- host->csr.speed_map[1] = +- cpu_to_be32(be32_to_cpu(host->csr.speed_map[1]) + 1); ++ be32_add_cpu(&host->csr.speed_map[1], 1); + host->csr.speed_map[0] = cpu_to_be32(0x3f1 << 16 + | csr_crc16(host->csr.speed_map+1, + 0x3f1)); +diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c +index 6572211..6228fad 100644 +--- a/drivers/ieee1394/dv1394.c ++++ b/drivers/ieee1394/dv1394.c +@@ -2179,8 +2179,7 @@ static struct ieee1394_device_id dv1394_id_table[] = { + MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table); + + static struct hpsb_protocol_driver dv1394_driver = { +- .name = "dv1394", +- .id_table = dv1394_id_table, ++ .name = "dv1394", + }; + + +@@ -2568,7 +2567,6 @@ static int __init dv1394_init_module(void) + + cdev_init(&dv1394_cdev, &dv1394_fops); + dv1394_cdev.owner = THIS_MODULE; +- kobject_set_name(&dv1394_cdev.kobj, "dv1394"); + ret = cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16); + if (ret) { + printk(KERN_ERR "dv1394: unable to register character device\n"); +diff --git a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c +index b642546..fa2bfec 100644 +--- a/drivers/ieee1394/highlevel.c ++++ b/drivers/ieee1394/highlevel.c +@@ -339,7 +339,7 @@ u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl, + if ((alignment & 3) || (alignment > 0x800000000000ULL) || + (hweight64(alignment) != 1)) { + HPSB_ERR("%s called with invalid alignment: 0x%048llx", +- __FUNCTION__, (unsigned long long)alignment); ++ __func__, (unsigned long long)alignment); + return retval; + } + +@@ -354,7 +354,7 @@ u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl, + if (((start|end) & ~align_mask) || (start >= end) || + (end > CSR1212_ALL_SPACE_END)) { + HPSB_ERR("%s called with invalid addresses " +- "(start = %012Lx end = %012Lx)", __FUNCTION__, ++ "(start = %012Lx end = %012Lx)", __func__, + (unsigned long long)start,(unsigned long long)end); + return retval; + } +@@ -422,7 +422,7 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, + + if (((start|end) & 3) || (start >= end) || + (end > CSR1212_ALL_SPACE_END)) { +- HPSB_ERR("%s called with invalid addresses", __FUNCTION__); ++ HPSB_ERR("%s called with invalid addresses", __func__); + return 0; + } + +diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c +index 36c747b..942bf1f 100644 +--- a/drivers/ieee1394/ieee1394_core.c ++++ b/drivers/ieee1394/ieee1394_core.c +@@ -242,7 +242,7 @@ int hpsb_bus_reset(struct hpsb_host *host) + { + if (host->in_bus_reset) { + HPSB_NOTICE("%s called while bus reset already in progress", +- __FUNCTION__); ++ __func__); + return 1; + } + +diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c +index 511e432..70afa37 100644 +--- a/drivers/ieee1394/nodemgr.c ++++ b/drivers/ieee1394/nodemgr.c +@@ -701,7 +701,11 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv) + return 0; + + driver = container_of(drv, struct hpsb_protocol_driver, driver); +- for (id = driver->id_table; id->match_flags != 0; id++) { ++ id = driver->id_table; ++ if (!id) ++ return 0; ++ ++ for (; id->match_flags != 0; id++) { + if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) && + id->vendor_id != ud->vendor_id) + continue; +diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c +index 969de2a..0690469 100644 +--- a/drivers/ieee1394/ohci1394.c ++++ b/drivers/ieee1394/ohci1394.c +@@ -149,7 +149,7 @@ printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , + /* Module Parameters */ + static int phys_dma = 1; + module_param(phys_dma, int, 0444); +-MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1)."); ++MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1)."); + + static void dma_trm_tasklet(unsigned long data); + static void dma_trm_reset(struct dma_trm_ctx *d); +@@ -708,7 +708,7 @@ static void insert_packet(struct ti_ohci *ohci, + /* FIXME: do something about it */ + PRINT(KERN_ERR, + "%s: packet data addr: %p size %Zd bytes " +- "cross page boundary", __FUNCTION__, ++ "cross page boundary", __func__, + packet->data, packet->data_size); + } + #endif +@@ -2089,10 +2089,8 @@ static void dma_trm_reset(struct dma_trm_ctx *d) + + spin_lock_irqsave(&d->lock, flags); + +- list_splice(&d->fifo_list, &packet_list); +- list_splice(&d->pending_list, &packet_list); +- INIT_LIST_HEAD(&d->fifo_list); +- INIT_LIST_HEAD(&d->pending_list); ++ list_splice_init(&d->fifo_list, &packet_list); ++ list_splice_init(&d->pending_list, &packet_list); + + d->branchAddrPtr = NULL; + d->sent_ind = d->prg_ind; +@@ -2787,7 +2785,7 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, + d->buf_bus = kzalloc(d->num_desc * sizeof(*d->buf_bus), GFP_ATOMIC); + + if (d->buf_cpu == NULL || d->buf_bus == NULL) { +- PRINT(KERN_ERR, "Failed to allocate dma buffer"); ++ PRINT(KERN_ERR, "Failed to allocate %s", "DMA buffer"); + free_dma_rcv_ctx(d); + return -ENOMEM; + } +@@ -2796,7 +2794,7 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, + d->prg_bus = kzalloc(d->num_desc * sizeof(*d->prg_bus), GFP_ATOMIC); + + if (d->prg_cpu == NULL || d->prg_bus == NULL) { +- PRINT(KERN_ERR, "Failed to allocate dma prg"); ++ PRINT(KERN_ERR, "Failed to allocate %s", "DMA prg"); + free_dma_rcv_ctx(d); + return -ENOMEM; + } +@@ -2804,7 +2802,7 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, + d->spb = kmalloc(d->split_buf_size, GFP_ATOMIC); + + if (d->spb == NULL) { +- PRINT(KERN_ERR, "Failed to allocate split buffer"); ++ PRINT(KERN_ERR, "Failed to allocate %s", "split buffer"); + free_dma_rcv_ctx(d); + return -ENOMEM; + } +@@ -2830,7 +2828,7 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, + memset(d->buf_cpu[i], 0, d->buf_size); + } else { + PRINT(KERN_ERR, +- "Failed to allocate dma buffer"); ++ "Failed to allocate %s", "DMA buffer"); + free_dma_rcv_ctx(d); + return -ENOMEM; + } +@@ -2841,7 +2839,7 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, + memset(d->prg_cpu[i], 0, sizeof(struct dma_cmd)); + } else { + PRINT(KERN_ERR, +- "Failed to allocate dma prg"); ++ "Failed to allocate %s", "DMA prg"); + free_dma_rcv_ctx(d); + return -ENOMEM; + } +@@ -2902,7 +2900,7 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, + d->prg_bus = kzalloc(d->num_desc * sizeof(*d->prg_bus), GFP_KERNEL); + + if (d->prg_cpu == NULL || d->prg_bus == NULL) { +- PRINT(KERN_ERR, "Failed to allocate at dma prg"); ++ PRINT(KERN_ERR, "Failed to allocate %s", "AT DMA prg"); + free_dma_trm_ctx(d); + return -ENOMEM; + } +@@ -2925,7 +2923,7 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, + memset(d->prg_cpu[i], 0, sizeof(struct at_dma_prg)); + } else { + PRINT(KERN_ERR, +- "Failed to allocate at dma prg"); ++ "Failed to allocate %s", "AT DMA prg"); + free_dma_trm_ctx(d); + return -ENOMEM; + } +@@ -2986,22 +2984,9 @@ static struct hpsb_host_driver ohci1394_driver = { + * PCI Driver Interface functions * + ***********************************/ + +-#define FAIL(err, fmt, args...) \ +-do { \ +- PRINT_G(KERN_ERR, fmt , ## args); \ +- ohci1394_pci_remove(dev); \ +- return err; \ +-} while (0) +- +-static int __devinit ohci1394_pci_probe(struct pci_dev *dev, +- const struct pci_device_id *ent) +-{ +- struct hpsb_host *host; +- struct ti_ohci *ohci; /* shortcut to currently handled device */ +- resource_size_t ohci_base; +- + #ifdef CONFIG_PPC_PMAC +- /* Necessary on some machines if ohci1394 was loaded/ unloaded before */ ++static void ohci1394_pmac_on(struct pci_dev *dev) ++{ + if (machine_is(powermac)) { + struct device_node *ofn = pci_device_to_OF_node(dev); + +@@ -3010,15 +2995,45 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, + pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1); + } + } ++} ++ ++static void ohci1394_pmac_off(struct pci_dev *dev) ++{ ++ if (machine_is(powermac)) { ++ struct device_node *ofn = pci_device_to_OF_node(dev); ++ ++ if (ofn) { ++ pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0); ++ pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 0); ++ } ++ } ++} ++#else ++#define ohci1394_pmac_on(dev) ++#define ohci1394_pmac_off(dev) + #endif /* CONFIG_PPC_PMAC */ + +- if (pci_enable_device(dev)) +- FAIL(-ENXIO, "Failed to enable OHCI hardware"); ++static int __devinit ohci1394_pci_probe(struct pci_dev *dev, ++ const struct pci_device_id *ent) ++{ ++ struct hpsb_host *host; ++ struct ti_ohci *ohci; /* shortcut to currently handled device */ ++ resource_size_t ohci_base; ++ int err = -ENOMEM; ++ ++ ohci1394_pmac_on(dev); ++ if (pci_enable_device(dev)) { ++ PRINT_G(KERN_ERR, "Failed to enable OHCI hardware"); ++ err = -ENXIO; ++ goto err; ++ } + pci_set_master(dev); + + host = hpsb_alloc_host(&ohci1394_driver, sizeof(struct ti_ohci), &dev->dev); +- if (!host) FAIL(-ENOMEM, "Failed to allocate host structure"); +- ++ if (!host) { ++ PRINT_G(KERN_ERR, "Failed to allocate %s", "host structure"); ++ goto err; ++ } + ohci = host->hostdata; + ohci->dev = dev; + ohci->host = host; +@@ -3067,15 +3082,20 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, + (unsigned long long)pci_resource_len(dev, 0)); + + if (!request_mem_region(ohci_base, OHCI1394_REGISTER_SIZE, +- OHCI1394_DRIVER_NAME)) +- FAIL(-ENOMEM, "MMIO resource (0x%llx - 0x%llx) unavailable", ++ OHCI1394_DRIVER_NAME)) { ++ PRINT_G(KERN_ERR, "MMIO resource (0x%llx - 0x%llx) unavailable", + (unsigned long long)ohci_base, + (unsigned long long)ohci_base + OHCI1394_REGISTER_SIZE); ++ goto err; ++ } + ohci->init_state = OHCI_INIT_HAVE_MEM_REGION; + + ohci->registers = ioremap(ohci_base, OHCI1394_REGISTER_SIZE); +- if (ohci->registers == NULL) +- FAIL(-ENXIO, "Failed to remap registers - card not accessible"); ++ if (ohci->registers == NULL) { ++ PRINT_G(KERN_ERR, "Failed to remap registers"); ++ err = -ENXIO; ++ goto err; ++ } + ohci->init_state = OHCI_INIT_HAVE_IOMAPPING; + DBGMSG("Remapped memory spaces reg 0x%p", ohci->registers); + +@@ -3083,16 +3103,20 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, + ohci->csr_config_rom_cpu = + pci_alloc_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN, + &ohci->csr_config_rom_bus); +- if (ohci->csr_config_rom_cpu == NULL) +- FAIL(-ENOMEM, "Failed to allocate buffer config rom"); ++ if (ohci->csr_config_rom_cpu == NULL) { ++ PRINT_G(KERN_ERR, "Failed to allocate %s", "buffer config rom"); ++ goto err; ++ } + ohci->init_state = OHCI_INIT_HAVE_CONFIG_ROM_BUFFER; + + /* self-id dma buffer allocation */ + ohci->selfid_buf_cpu = + pci_alloc_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, + &ohci->selfid_buf_bus); +- if (ohci->selfid_buf_cpu == NULL) +- FAIL(-ENOMEM, "Failed to allocate DMA buffer for self-id packets"); ++ if (ohci->selfid_buf_cpu == NULL) { ++ PRINT_G(KERN_ERR, "Failed to allocate %s", "self-ID buffer"); ++ goto err; ++ } + ohci->init_state = OHCI_INIT_HAVE_SELFID_BUFFER; + + if ((unsigned long)ohci->selfid_buf_cpu & 0x1fff) +@@ -3108,28 +3132,32 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, + if (alloc_dma_rcv_ctx(ohci, &ohci->ar_req_context, + DMA_CTX_ASYNC_REQ, 0, AR_REQ_NUM_DESC, + AR_REQ_BUF_SIZE, AR_REQ_SPLIT_BUF_SIZE, +- OHCI1394_AsReqRcvContextBase) < 0) +- FAIL(-ENOMEM, "Failed to allocate AR Req context"); +- ++ OHCI1394_AsReqRcvContextBase) < 0) { ++ PRINT_G(KERN_ERR, "Failed to allocate %s", "AR Req context"); ++ goto err; ++ } + /* AR DMA response context allocation */ + if (alloc_dma_rcv_ctx(ohci, &ohci->ar_resp_context, + DMA_CTX_ASYNC_RESP, 0, AR_RESP_NUM_DESC, + AR_RESP_BUF_SIZE, AR_RESP_SPLIT_BUF_SIZE, +- OHCI1394_AsRspRcvContextBase) < 0) +- FAIL(-ENOMEM, "Failed to allocate AR Resp context"); +- ++ OHCI1394_AsRspRcvContextBase) < 0) { ++ PRINT_G(KERN_ERR, "Failed to allocate %s", "AR Resp context"); ++ goto err; ++ } + /* AT DMA request context */ + if (alloc_dma_trm_ctx(ohci, &ohci->at_req_context, + DMA_CTX_ASYNC_REQ, 0, AT_REQ_NUM_DESC, +- OHCI1394_AsReqTrContextBase) < 0) +- FAIL(-ENOMEM, "Failed to allocate AT Req context"); +- ++ OHCI1394_AsReqTrContextBase) < 0) { ++ PRINT_G(KERN_ERR, "Failed to allocate %s", "AT Req context"); ++ goto err; ++ } + /* AT DMA response context */ + if (alloc_dma_trm_ctx(ohci, &ohci->at_resp_context, + DMA_CTX_ASYNC_RESP, 1, AT_RESP_NUM_DESC, +- OHCI1394_AsRspTrContextBase) < 0) +- FAIL(-ENOMEM, "Failed to allocate AT Resp context"); +- ++ OHCI1394_AsRspTrContextBase) < 0) { ++ PRINT_G(KERN_ERR, "Failed to allocate %s", "AT Resp context"); ++ goto err; ++ } + /* Start off with a soft reset, to clear everything to a sane + * state. */ + ohci_soft_reset(ohci); +@@ -3172,9 +3200,10 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, + * by that point. + */ + if (request_irq(dev->irq, ohci_irq_handler, IRQF_SHARED, +- OHCI1394_DRIVER_NAME, ohci)) +- FAIL(-ENOMEM, "Failed to allocate shared interrupt %d", dev->irq); +- ++ OHCI1394_DRIVER_NAME, ohci)) { ++ PRINT_G(KERN_ERR, "Failed to allocate interrupt %d", dev->irq); ++ goto err; ++ } + ohci->init_state = OHCI_INIT_HAVE_IRQ; + ohci_initialize(ohci); + +@@ -3194,25 +3223,28 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, + host->middle_addr_space = OHCI1394_MIDDLE_ADDRESS_SPACE; + + /* Tell the highlevel this host is ready */ +- if (hpsb_add_host(host)) +- FAIL(-ENOMEM, "Failed to register host with highlevel"); +- ++ if (hpsb_add_host(host)) { ++ PRINT_G(KERN_ERR, "Failed to register host with highlevel"); ++ goto err; ++ } + ohci->init_state = OHCI_INIT_DONE; + + return 0; +-#undef FAIL ++err: ++ ohci1394_pci_remove(dev); ++ return err; + } + +-static void ohci1394_pci_remove(struct pci_dev *pdev) ++static void ohci1394_pci_remove(struct pci_dev *dev) + { + struct ti_ohci *ohci; +- struct device *dev; ++ struct device *device; + +- ohci = pci_get_drvdata(pdev); ++ ohci = pci_get_drvdata(dev); + if (!ohci) +- return; ++ goto out; + +- dev = get_device(&ohci->host->device); ++ device = get_device(&ohci->host->device); + + switch (ohci->init_state) { + case OHCI_INIT_DONE: +@@ -3246,7 +3278,7 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) + /* Soft reset before we start - this disables + * interrupts and clears linkEnable and LPS. */ + ohci_soft_reset(ohci); +- free_irq(ohci->dev->irq, ohci); ++ free_irq(dev->irq, ohci); + + case OHCI_INIT_HAVE_TXRX_BUFFERS__MAYBE: + /* The ohci_soft_reset() stops all DMA contexts, so we +@@ -3257,12 +3289,12 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) + free_dma_trm_ctx(&ohci->at_resp_context); + + case OHCI_INIT_HAVE_SELFID_BUFFER: +- pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, ++ pci_free_consistent(dev, OHCI1394_SI_DMA_BUF_SIZE, + ohci->selfid_buf_cpu, + ohci->selfid_buf_bus); + + case OHCI_INIT_HAVE_CONFIG_ROM_BUFFER: +- pci_free_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN, ++ pci_free_consistent(dev, OHCI_CONFIG_ROM_LEN, + ohci->csr_config_rom_cpu, + ohci->csr_config_rom_bus); + +@@ -3270,35 +3302,24 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) + iounmap(ohci->registers); + + case OHCI_INIT_HAVE_MEM_REGION: +- release_mem_region(pci_resource_start(ohci->dev, 0), ++ release_mem_region(pci_resource_start(dev, 0), + OHCI1394_REGISTER_SIZE); + +-#ifdef CONFIG_PPC_PMAC +- /* On UniNorth, power down the cable and turn off the chip clock +- * to save power on laptops */ +- if (machine_is(powermac)) { +- struct device_node* ofn = pci_device_to_OF_node(ohci->dev); +- +- if (ofn) { +- pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0); +- pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 0); +- } +- } +-#endif /* CONFIG_PPC_PMAC */ +- + case OHCI_INIT_ALLOC_HOST: +- pci_set_drvdata(ohci->dev, NULL); ++ pci_set_drvdata(dev, NULL); + } + +- if (dev) +- put_device(dev); ++ if (device) ++ put_device(device); ++out: ++ ohci1394_pmac_off(dev); + } + + #ifdef CONFIG_PM +-static int ohci1394_pci_suspend(struct pci_dev *pdev, pm_message_t state) ++static int ohci1394_pci_suspend(struct pci_dev *dev, pm_message_t state) + { + int err; +- struct ti_ohci *ohci = pci_get_drvdata(pdev); ++ struct ti_ohci *ohci = pci_get_drvdata(dev); + + if (!ohci) { + printk(KERN_ERR "%s: tried to suspend nonexisting host\n", +@@ -3326,32 +3347,23 @@ static int ohci1394_pci_suspend(struct pci_dev *pdev, pm_message_t state) + ohci_devctl(ohci->host, RESET_BUS, LONG_RESET_NO_FORCE_ROOT); + ohci_soft_reset(ohci); + +- err = pci_save_state(pdev); ++ err = pci_save_state(dev); + if (err) { + PRINT(KERN_ERR, "pci_save_state failed with %d", err); + return err; + } +- err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); ++ err = pci_set_power_state(dev, pci_choose_state(dev, state)); + if (err) + DBGMSG("pci_set_power_state failed with %d", err); +- +-/* PowerMac suspend code comes last */ +-#ifdef CONFIG_PPC_PMAC +- if (machine_is(powermac)) { +- struct device_node *ofn = pci_device_to_OF_node(pdev); +- +- if (ofn) +- pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0); +- } +-#endif /* CONFIG_PPC_PMAC */ ++ ohci1394_pmac_off(dev); + + return 0; + } + +-static int ohci1394_pci_resume(struct pci_dev *pdev) ++static int ohci1394_pci_resume(struct pci_dev *dev) + { + int err; +- struct ti_ohci *ohci = pci_get_drvdata(pdev); ++ struct ti_ohci *ohci = pci_get_drvdata(dev); + + if (!ohci) { + printk(KERN_ERR "%s: tried to resume nonexisting host\n", +@@ -3360,19 +3372,10 @@ static int ohci1394_pci_resume(struct pci_dev *pdev) + } + DBGMSG("resume called"); + +-/* PowerMac resume code comes first */ +-#ifdef CONFIG_PPC_PMAC +- if (machine_is(powermac)) { +- struct device_node *ofn = pci_device_to_OF_node(pdev); +- +- if (ofn) +- pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1); +- } +-#endif /* CONFIG_PPC_PMAC */ +- +- pci_set_power_state(pdev, PCI_D0); +- pci_restore_state(pdev); +- err = pci_enable_device(pdev); ++ ohci1394_pmac_on(dev); ++ pci_set_power_state(dev, PCI_D0); ++ pci_restore_state(dev); ++ err = pci_enable_device(dev); + if (err) { + PRINT(KERN_ERR, "pci_enable_device failed with %d", err); + return err; +diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c +index 8af01ab..7aee1ac 100644 +--- a/drivers/ieee1394/pcilynx.c ++++ b/drivers/ieee1394/pcilynx.c +@@ -226,7 +226,7 @@ static int get_phy_reg(struct ti_lynx *lynx, int addr) + if (addr > 15) { + PRINT(KERN_ERR, lynx->id, + "%s: PHY register address %d out of range", +- __FUNCTION__, addr); ++ __func__, addr); + return -1; + } + +@@ -238,7 +238,7 @@ static int get_phy_reg(struct ti_lynx *lynx, int addr) + + if (i > 10000) { + PRINT(KERN_ERR, lynx->id, "%s: runaway loop, aborting", +- __FUNCTION__); ++ __func__); + retval = -1; + break; + } +@@ -261,13 +261,13 @@ static int set_phy_reg(struct ti_lynx *lynx, int addr, int val) + + if (addr > 15) { + PRINT(KERN_ERR, lynx->id, +- "%s: PHY register address %d out of range", __FUNCTION__, addr); ++ "%s: PHY register address %d out of range", __func__, addr); + return -1; + } + + if (val > 0xff) { + PRINT(KERN_ERR, lynx->id, +- "%s: PHY register value %d out of range", __FUNCTION__, val); ++ "%s: PHY register value %d out of range", __func__, val); + return -1; + } + +@@ -287,7 +287,7 @@ static int sel_phy_reg_page(struct ti_lynx *lynx, int page) + + if (page > 7) { + PRINT(KERN_ERR, lynx->id, +- "%s: PHY page %d out of range", __FUNCTION__, page); ++ "%s: PHY page %d out of range", __func__, page); + return -1; + } + +@@ -309,7 +309,7 @@ static int sel_phy_reg_port(struct ti_lynx *lynx, int port) + + if (port > 15) { + PRINT(KERN_ERR, lynx->id, +- "%s: PHY port %d out of range", __FUNCTION__, port); ++ "%s: PHY port %d out of range", __func__, port); + return -1; + } + +@@ -738,8 +738,7 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) + spin_lock_irqsave(&lynx->async.queue_lock, flags); + + reg_write(lynx, DMA_CHAN_CTRL(CHANNEL_ASYNC_SEND), 0); +- list_splice(&lynx->async.queue, &packet_list); +- INIT_LIST_HEAD(&lynx->async.queue); ++ list_splice_init(&lynx->async.queue, &packet_list); + + if (list_empty(&lynx->async.pcl_queue)) { + spin_unlock_irqrestore(&lynx->async.queue_lock, flags); +diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c +index 37e7e10..04e96ba 100644 +--- a/drivers/ieee1394/raw1394.c ++++ b/drivers/ieee1394/raw1394.c +@@ -2959,7 +2959,6 @@ MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table); + + static struct hpsb_protocol_driver raw1394_driver = { + .name = "raw1394", +- .id_table = raw1394_id_table, + }; + + /******************************************************************************/ +@@ -3004,7 +3003,6 @@ static int __init init_raw1394(void) + + cdev_init(&raw1394_cdev, &raw1394_fops); + raw1394_cdev.owner = THIS_MODULE; +- kobject_set_name(&raw1394_cdev.kobj, RAW1394_DEVICE_NAME); + ret = cdev_add(&raw1394_cdev, IEEE1394_RAW1394_DEV, 1); + if (ret) { + HPSB_ERR("raw1394 failed to register minor device block"); +diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c +index f53f72d..16b9d0a 100644 +--- a/drivers/ieee1394/sbp2.c ++++ b/drivers/ieee1394/sbp2.c +@@ -615,7 +615,7 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb( + cmd->Current_SCpnt = Current_SCpnt; + list_add_tail(&cmd->list, &lu->cmd_orb_inuse); + } else +- SBP2_ERR("%s: no orbs available", __FUNCTION__); ++ SBP2_ERR("%s: no orbs available", __func__); + spin_unlock_irqrestore(&lu->cmd_orb_lock, flags); + return cmd; + } +@@ -1294,7 +1294,7 @@ static int sbp2_set_busy_timeout(struct sbp2_lu *lu) + + data = cpu_to_be32(SBP2_BUSY_TIMEOUT_VALUE); + if (hpsb_node_write(lu->ne, SBP2_BUSY_TIMEOUT_ADDRESS, &data, 4)) +- SBP2_ERR("%s error", __FUNCTION__); ++ SBP2_ERR("%s error", __func__); + return 0; + } + +@@ -1985,11 +1985,8 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev) + lu->sdev = sdev; + sdev->allow_restart = 1; + +- /* +- * Update the dma alignment (minimum alignment requirements for +- * start and end of DMA transfers) to be a sector +- */ +- blk_queue_update_dma_alignment(sdev->request_queue, 511); ++ /* SBP-2 requires quadlet alignment of the data buffers. */ ++ blk_queue_update_dma_alignment(sdev->request_queue, 4 - 1); + + if (lu->workarounds & SBP2_WORKAROUND_INQUIRY_36) + sdev->inquiry_len = 36; +diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c +index bd28adf..e03024e 100644 +--- a/drivers/ieee1394/video1394.c ++++ b/drivers/ieee1394/video1394.c +@@ -1315,8 +1315,7 @@ static struct ieee1394_device_id video1394_id_table[] = { + MODULE_DEVICE_TABLE(ieee1394, video1394_id_table); + + static struct hpsb_protocol_driver video1394_driver = { +- .name = VIDEO1394_DRIVER_NAME, +- .id_table = video1394_id_table, ++ .name = VIDEO1394_DRIVER_NAME, + }; + + +@@ -1504,7 +1503,6 @@ static int __init video1394_init_module (void) + + cdev_init(&video1394_cdev, &video1394_fops); + video1394_cdev.owner = THIS_MODULE; +- kobject_set_name(&video1394_cdev.kobj, VIDEO1394_DRIVER_NAME); + ret = cdev_add(&video1394_cdev, IEEE1394_VIDEO1394_DEV, 16); + if (ret) { + PRINT_G(KERN_ERR, "video1394: unable to get minor device block"); +diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug +index 0796c1a..4e370e1 100644 +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -592,6 +592,16 @@ config LATENCYTOP + Enable this option if you want to use the LatencyTOP tool + to find out which userspace is blocking on what kernel operations. + ++config FIREWIRE_OHCI_REMOTE_DMA ++ bool "Remote debugging via firewire-ohci" ++ depends on FIREWIRE_OHCI ++ help ++ This option lets you use the FireWire bus for remote debugging. ++ It enables unfiltered remote DMA in the firewire-ohci driver. ++ See Documentation/debugging-via-ohci1394.txt for more information. ++ ++ If unsure, say N. ++ + config PROVIDE_OHCI1394_DMA_INIT + bool "Provide code for enabling DMA over FireWire early on boot" + depends on PCI && X86 diff --git a/debian/patches/series/1~experimental.1 b/debian/patches/series/1~experimental.1 index 92fb68a24..421a88e06 100644 --- a/debian/patches/series/1~experimental.1 +++ b/debian/patches/series/1~experimental.1 @@ -36,3 +36,4 @@ + bugfix/all/rtc-x1205-new-style-conversion.patch + bugfix/all/rtc-x1205-new-style-conversion-checkpatch-fixes.patch + bugfix/all/mtd-prevent-physmap-from-causing-request_module-runaway-loop-modprobe-net-pf-1.patch ++ features/all/firewire-git.patch