From 0a9972baa7454c747fd5f67ce864420dff99d383 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 23 Jun 2007 20:28:17 +0200 Subject: firewire: fix async reception on big endian machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit descriptor.data_address is little endian Tested-by: Olaf Hering Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-ohci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index b72a5c1f9e6..96c8ac5b86c 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -373,8 +373,8 @@ static void ar_context_tasklet(unsigned long data) offset = offsetof(struct ar_buffer, data); dma_unmap_single(ohci->card.device, - ab->descriptor.data_address - offset, - PAGE_SIZE, DMA_BIDIRECTIONAL); + le32_to_cpu(ab->descriptor.data_address) - offset, + PAGE_SIZE, DMA_BIDIRECTIONAL); buffer = ab; ab = ab->next; @@ -427,7 +427,7 @@ static void ar_context_run(struct ar_context *ctx) size_t offset; offset = offsetof(struct ar_buffer, data); - ab_bus = ab->descriptor.data_address - offset; + ab_bus = le32_to_cpu(ab->descriptor.data_address) - offset; reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ab_bus | 1); reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN); -- cgit v1.2.3-70-g09d2 From fe77d4f283e840879f0e23b86a5d6a486823fdef Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 25 Jun 2007 22:18:40 +0200 Subject: firewire: add Kconfig help on building both stacks Alas that won't work so good, because nobody reads help texts. I thought about adding some crude multiple choice selection (build the old stack, build the new stack, build both stacks). It's possible, but it would introduce awkward dummy config variables. Signed-off-by: Stefan Richter --- drivers/firewire/Kconfig | 65 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 22 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig index 396dade731f..d011a76f8e7 100644 --- a/drivers/firewire/Kconfig +++ b/drivers/firewire/Kconfig @@ -4,27 +4,44 @@ comment "An alternative FireWire stack is available with EXPERIMENTAL=y" depends on EXPERIMENTAL=n config FIREWIRE - tristate "IEEE 1394 (FireWire) support (JUJU alternative stack, experimental)" + tristate "IEEE 1394 (FireWire) support - alternative stack, EXPERIMENTAL" depends on EXPERIMENTAL select CRC_ITU_T help - IEEE 1394 describes a high performance serial bus, which is also - known as FireWire(tm) or i.Link(tm) and is used for connecting all - sorts of devices (most notably digital video cameras) to your - computer. - - If you have FireWire hardware and want to use it, say Y here. This - is the core support only, you will also need to select a driver for - your IEEE 1394 adapter. - - To compile this driver as a module, say M here: the module will be - called firewire-core. - - This is the "JUJU" FireWire stack, an alternative implementation + This is the "Juju" FireWire stack, a new alternative implementation designed for robustness and simplicity. You can build either this stack, or the classic stack (the ieee1394 driver, ohci1394 etc.) or both. + To compile this driver as a module, say M here: the module will be + called firewire-core. It functionally replaces ieee1394, raw1394, + and video1394. + + NOTE: + + You should only build ONE of the stacks, unless you REALLY know what + you are doing. If you install both, you should configure them only as + modules rather than link them statically, and you should blacklist one + of the concurrent low-level drivers in /etc/modprobe.conf. Add either + + blacklist firewire-ohci + or + blacklist ohci1394 + + there depending on which driver you DON'T want to have auto-loaded. + You can optionally do the same with the other IEEE 1394/ FireWire + drivers. + + If you have an old modprobe which doesn't implement the blacklist + directive, use either + + install firewire-ohci /bin/true + or + install ohci1394 /bin/true + + and so on, depending on which modules you DON't want to have + auto-loaded. + config FIREWIRE_OHCI tristate "Support for OHCI FireWire host controllers" depends on PCI && FIREWIRE @@ -34,11 +51,13 @@ config FIREWIRE_OHCI is the only chipset in use, so say Y here. To compile this driver as a module, say M here: The module will be - called firewire-ohci. + called firewire-ohci. It replaces ohci1394 of the classic IEEE 1394 + stack. + + NOTE: - If you also build ohci1394 of the classic IEEE 1394 driver stack, - blacklist either ohci1394 or firewire-ohci to let hotplug load the - desired driver. + If you also build ohci1394 of the classic stack, blacklist either + ohci1394 or firewire-ohci to let hotplug load only the desired driver. config FIREWIRE_SBP2 tristate "Support for storage devices (SBP-2 protocol driver)" @@ -50,12 +69,14 @@ config FIREWIRE_SBP2 like scanners. To compile this driver as a module, say M here: The module will be - called firewire-sbp2. + called firewire-sbp2. It replaces sbp2 of the classic IEEE 1394 + stack. You should also enable support for disks, CD-ROMs, etc. in the SCSI configuration section. - If you also build sbp2 of the classic IEEE 1394 driver stack, - blacklist either sbp2 or firewire-sbp2 to let hotplug load the - desired driver. + NOTE: + + If you also build sbp2 of the classic stack, blacklist either sbp2 + or firewire-sbp2 to let hotplug load only the desired driver. -- cgit v1.2.3-70-g09d2 From b8f106570f20a7a98a18a14c2d11d65f581c2808 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Fri, 11 May 2007 23:04:08 +0200 Subject: firewire: fw-sbp2: remove unused struct member cleanup after support of single-buffer requests was dropped Signed-off-by: Stefan Richter Signed-off-by: Kristian Hoegsberg --- drivers/firewire/fw-sbp2.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index a98d3915e26..25f2aa430a3 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -207,7 +207,6 @@ struct sbp2_command_orb { struct sbp2_pointer page_table[SG_ALL]; dma_addr_t page_table_bus; - dma_addr_t request_buffer_bus; }; /* @@ -882,11 +881,6 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) dma_unmap_single(device->card->device, orb->page_table_bus, sizeof(orb->page_table_bus), DMA_TO_DEVICE); - if (orb->request_buffer_bus != 0) - dma_unmap_single(device->card->device, orb->request_buffer_bus, - sizeof(orb->request_buffer_bus), - DMA_FROM_DEVICE); - orb->cmd->result = result; orb->done(orb->cmd); kfree(orb); -- cgit v1.2.3-70-g09d2 From 8a8cea2734808522f02941ea16125810ee42c9c7 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 9 Jun 2007 19:26:22 +0200 Subject: firewire: missing newline in printk Also remove some errno printouts which will be shown by infrastructure code anyway. Signed-off-by: Stefan Richter --- drivers/firewire/fw-ohci.c | 6 +++--- drivers/firewire/fw-sbp2.c | 2 +- drivers/firewire/fw-topology.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 96c8ac5b86c..41476abc069 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -1934,12 +1934,12 @@ static int pci_suspend(struct pci_dev *pdev, pm_message_t state) free_irq(pdev->irq, ohci); err = pci_save_state(pdev); if (err) { - fw_error("pci_save_state failed with %d", err); + fw_error("pci_save_state failed\n"); return err; } err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); if (err) { - fw_error("pci_set_power_state failed with %d", err); + fw_error("pci_set_power_state failed\n"); return err; } @@ -1955,7 +1955,7 @@ static int pci_resume(struct pci_dev *pdev) pci_restore_state(pdev); err = pci_enable_device(pdev); if (err) { - fw_error("pci_enable_device failed with %d", err); + fw_error("pci_enable_device failed\n"); return err; } diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 25f2aa430a3..16e942f72e4 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -985,7 +985,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) * transfer direction not handled. */ if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) { - fw_error("Cannot handle DMA_BIDIRECTIONAL - rejecting command"); + fw_error("Can't handle DMA_BIDIRECTIONAL, rejecting command\n"); cmd->result = DID_ERROR << 16; done(cmd); return 0; diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c index 7aebb8ae0ef..4e358506d91 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/fw-topology.c @@ -214,7 +214,7 @@ static struct fw_node *build_tree(struct fw_card *card, node = fw_node_create(q, port_count, card->color); if (node == NULL) { - fw_error("Out of memory while building topology."); + fw_error("Out of memory while building topology.\n"); return NULL; } -- cgit v1.2.3-70-g09d2 From 25d83f583b334ac671fbb905c97c374ba34a597a Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 9 Jun 2007 19:27:07 +0200 Subject: firewire: remove unused macro Signed-off-by: Stefan Richter --- drivers/firewire/fw-transaction.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index acdc3be38c6..f54eee4e380 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -81,7 +81,6 @@ #define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args) #define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args) -#define fw_debug(s, args...) printk(KERN_DEBUG KBUILD_MODNAME ": " s, ## args) static inline void fw_memcpy_from_be32(void *_dst, void *_src, size_t size) -- cgit v1.2.3-70-g09d2 From 24d40125f1f59a6de9d9e6e046676bd60532596c Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 18 Jun 2007 19:44:12 +0200 Subject: firewire: optimize gap count with 1394b leaf nodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Table-based gap count optimization cannot be used if 1394b repeater PHYs are present. But it does work with 1394b leaf nodes. Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-card.c | 7 +++++-- drivers/firewire/fw-topology.c | 16 ++++++++-------- drivers/firewire/fw-topology.h | 6 ------ drivers/firewire/fw-transaction.h | 2 +- 4 files changed, 14 insertions(+), 17 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 9eb1edacd82..0aeab3218bb 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c @@ -336,8 +336,11 @@ fw_card_bm_work(struct work_struct *work) } pick_me: - /* Now figure out what gap count to set. */ - if (card->topology_type == FW_TOPOLOGY_A && + /* + * Pick a gap count from 1394a table E-1. The table doesn't cover + * the typically much larger 1394b beta repeater delays though. + */ + if (!card->beta_repeaters_present && card->root_node->max_hops < ARRAY_SIZE(gap_count_table)) gap_count = gap_count_table[card->root_node->max_hops]; else diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c index 4e358506d91..77e3f827600 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/fw-topology.c @@ -172,7 +172,8 @@ static struct fw_node *build_tree(struct fw_card *card, struct list_head stack, *h; u32 *next_sid, *end, q; int i, port_count, child_port_count, phy_id, parent_count, stack_depth; - int gap_count, topology_type; + int gap_count; + bool beta_repeaters_present; local_node = NULL; node = NULL; @@ -182,7 +183,7 @@ static struct fw_node *build_tree(struct fw_card *card, phy_id = 0; irm_node = NULL; gap_count = SELF_ID_GAP_COUNT(*sid); - topology_type = 0; + beta_repeaters_present = false; while (sid < end) { next_sid = count_ports(sid, &port_count, &child_port_count); @@ -224,11 +225,6 @@ static struct fw_node *build_tree(struct fw_card *card, if (SELF_ID_CONTENDER(q)) irm_node = node; - if (node->phy_speed == SCODE_BETA) - topology_type |= FW_TOPOLOGY_B; - else - topology_type |= FW_TOPOLOGY_A; - parent_count = 0; for (i = 0; i < port_count; i++) { @@ -278,6 +274,10 @@ static struct fw_node *build_tree(struct fw_card *card, list_add_tail(&node->link, &stack); stack_depth += 1 - child_port_count; + if (node->phy_speed == SCODE_BETA && + parent_count + child_port_count > 1) + 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 @@ -295,7 +295,7 @@ static struct fw_node *build_tree(struct fw_card *card, card->root_node = node; card->irm_node = irm_node; card->gap_count = gap_count; - card->topology_type = topology_type; + card->beta_repeaters_present = beta_repeaters_present; return local_node; } diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h index 363b6cbcd0b..aced9f7db35 100644 --- a/drivers/firewire/fw-topology.h +++ b/drivers/firewire/fw-topology.h @@ -19,12 +19,6 @@ #ifndef __fw_topology_h #define __fw_topology_h -enum { - FW_TOPOLOGY_A = 0x01, - FW_TOPOLOGY_B = 0x02, - FW_TOPOLOGY_MIXED = 0x03, -}; - enum { FW_NODE_CREATED = 0x00, FW_NODE_UPDATED = 0x01, diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index f54eee4e380..5abed193f4a 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -245,7 +245,7 @@ struct fw_card { struct fw_node *irm_node; int color; int gap_count; - int topology_type; + bool beta_repeaters_present; int index; -- cgit v1.2.3-70-g09d2 From f1397490017e337446c6a8b0562b584679a604a6 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 10 Jun 2007 21:31:36 +0200 Subject: firewire: support S100B...S400B and link slower than PHY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a speed probe to determine the speed over 1394b buses and of nodes which report a link speed less than their PHY speed. Log the effective maximum speed of newly created nodes in dmesg. Also, read the config ROM (except bus info block) at the maximum speed rather than S100. This isn't a real optimization though because we still only use quadlet read requests for the entire ROM. The patch also adds support for S1600 and S3200, although such hardware does not exist yet. Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-cdev.c | 2 +- drivers/firewire/fw-device.c | 38 ++++++++++++++++++++++++++++++++++---- drivers/firewire/fw-device.h | 1 + drivers/firewire/fw-sbp2.c | 7 +++---- drivers/firewire/fw-topology.h | 13 ++++++------- 5 files changed, 45 insertions(+), 16 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index dbb76427d52..75388641a7d 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c @@ -397,7 +397,7 @@ static int ioctl_send_request(struct client *client, void *buffer) request->tcode & 0x1f, device->node->node_id, request->generation, - device->node->max_speed, + device->max_speed, request->offset, response->response.data, request->length, complete_transaction, response); diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index c1ce465d971..2b658634163 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c @@ -401,8 +401,7 @@ static int read_rom(struct fw_device *device, int index, u32 * data) offset = 0xfffff0000400ULL + index * 4; fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST, - device->node_id, - device->generation, SCODE_100, + device->node_id, device->generation, device->max_speed, offset, NULL, 4, complete_transaction, &callback_data); wait_for_completion(&callback_data.done); @@ -418,6 +417,8 @@ static int read_bus_info_block(struct fw_device *device) u32 stack[16], sp, key; int i, end, length; + device->max_speed = SCODE_100; + /* First read the bus info block. */ for (i = 0; i < 5; i++) { if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE) @@ -434,6 +435,33 @@ static int read_bus_info_block(struct fw_device *device) return -1; } + device->max_speed = device->node->max_speed; + + /* + * Determine the speed of + * - devices with link speed less than PHY speed, + * - devices with 1394b PHY (unless only connected to 1394a PHYs), + * - all devices if there are 1394b repeaters. + * Note, we cannot use the bus info block's link_spd as starting point + * because some buggy firmwares set it lower than necessary and because + * 1394-1995 nodes do not have the field. + */ + if ((rom[2] & 0x7) < device->max_speed || + device->max_speed == SCODE_BETA || + device->card->beta_repeaters_present) { + u32 dummy; + + /* for S1600 and S3200 */ + if (device->max_speed == SCODE_BETA) + device->max_speed = device->card->link_speed; + + while (device->max_speed > SCODE_100) { + if (read_rom(device, 0, &dummy) == RCODE_COMPLETE) + break; + device->max_speed--; + } + } + /* * Now parse the config rom. The config rom is a recursive * directory structure so we parse it using a stack of @@ -680,8 +708,10 @@ static void fw_device_init(struct work_struct *work) FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) fw_device_shutdown(&device->work.work); else - fw_notify("created new fw device %s (%d config rom retries)\n", - device->device.bus_id, device->config_rom_retries); + fw_notify("created new fw device %s " + "(%d config rom retries, S%d00)\n", + device->device.bus_id, device->config_rom_retries, + 1 << device->max_speed); /* * Reschedule the IRM work if we just finished reading the diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h index af1723eae4b..d13e6a69707 100644 --- a/drivers/firewire/fw-device.h +++ b/drivers/firewire/fw-device.h @@ -40,6 +40,7 @@ struct fw_device { struct fw_node *node; int node_id; int generation; + unsigned max_speed; struct fw_card *card; struct device device; struct list_head link; diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 16e942f72e4..851c2da060d 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -346,8 +346,7 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit, spin_unlock_irqrestore(&device->card->lock, flags); fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, - node_id, generation, - device->node->max_speed, offset, + node_id, generation, device->max_speed, offset, &orb->pointer, sizeof(orb->pointer), complete_transaction, orb); } @@ -1018,8 +1017,8 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) * if we set this to max_speed + 7, we get the right value. */ orb->request.misc = - COMMAND_ORB_MAX_PAYLOAD(device->node->max_speed + 7) | - COMMAND_ORB_SPEED(device->node->max_speed) | + COMMAND_ORB_MAX_PAYLOAD(device->max_speed + 7) | + COMMAND_ORB_SPEED(device->max_speed) | COMMAND_ORB_NOTIFY; if (cmd->sc_data_direction == DMA_FROM_DEVICE) diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h index aced9f7db35..da61ec09183 100644 --- a/drivers/firewire/fw-topology.h +++ b/drivers/firewire/fw-topology.h @@ -29,19 +29,18 @@ enum { struct fw_port { struct fw_node *node; - unsigned speed : 3; /* S100, S200, ... S3200 */ }; struct fw_node { u16 node_id; u8 color; u8 port_count; - unsigned link_on : 1; - unsigned initiated_reset : 1; - unsigned b_path : 1; - u8 phy_speed : 3; /* As in the self ID packet. */ - u8 max_speed : 5; /* Minimum of all phy-speeds and port speeds on - * the path from the local node to this node. */ + u8 link_on : 1; + u8 initiated_reset : 1; + u8 b_path : 1; + u8 phy_speed : 2; /* As in the self ID packet. */ + u8 max_speed : 2; /* Minimum of all phy-speeds on the path from the + * local node to this node. */ u8 max_depth : 4; /* Maximum depth to any leaf node */ u8 max_hops : 4; /* Max hops in this sub tree */ atomic_t ref_count; -- cgit v1.2.3-70-g09d2 From dae1a3aa8ebdd30fbba56a8d4e22f92455fb0861 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 17 Jun 2007 23:39:58 +0200 Subject: firewire: simplify a struct type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cleanup after "firewire: support S100B...S400B and link slower than PHY" Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-topology.c | 48 ++++++++++++++++++++---------------------- drivers/firewire/fw-topology.h | 6 +----- 2 files changed, 24 insertions(+), 30 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c index 77e3f827600..39e5cd12aa5 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/fw-topology.c @@ -135,17 +135,17 @@ static void update_hop_count(struct fw_node *node) int i; for (i = 0; i < node->port_count; i++) { - if (node->ports[i].node == NULL) + if (node->ports[i] == NULL) continue; - if (node->ports[i].node->max_hops > max_child_hops) - max_child_hops = node->ports[i].node->max_hops; + if (node->ports[i]->max_hops > max_child_hops) + max_child_hops = node->ports[i]->max_hops; - if (node->ports[i].node->max_depth > depths[0]) { + if (node->ports[i]->max_depth > depths[0]) { depths[1] = depths[0]; - depths[0] = node->ports[i].node->max_depth; - } else if (node->ports[i].node->max_depth > depths[1]) - depths[1] = node->ports[i].node->max_depth; + depths[0] = node->ports[i]->max_depth; + } else if (node->ports[i]->max_depth > depths[1]) + depths[1] = node->ports[i]->max_depth; } node->max_depth = depths[0] + 1; @@ -245,12 +245,12 @@ static struct fw_node *build_tree(struct fw_card *card, break; case SELFID_PORT_CHILD: - node->ports[i].node = child; + node->ports[i] = child; /* * Fix up parent reference for this * child node. */ - child->ports[child->color].node = node; + child->ports[child->color] = node; child->color = card->color; child = fw_node(child->link.next); break; @@ -321,7 +321,7 @@ for_each_fw_node(struct fw_card *card, struct fw_node *root, node->color = card->color; for (i = 0; i < node->port_count; i++) { - child = node->ports[i].node; + child = node->ports[i]; if (!child) continue; if (child->color == card->color) @@ -382,11 +382,11 @@ static void move_tree(struct fw_node *node0, struct fw_node *node1, int port) struct fw_node *tree; int i; - tree = node1->ports[port].node; - node0->ports[port].node = tree; + tree = node1->ports[port]; + node0->ports[port] = tree; for (i = 0; i < tree->port_count; i++) { - if (tree->ports[i].node == node1) { - tree->ports[i].node = node0; + if (tree->ports[i] == node1) { + tree->ports[i] = node0; break; } } @@ -437,19 +437,17 @@ update_tree(struct fw_card *card, struct fw_node *root) card->irm_node = node0; for (i = 0; i < node0->port_count; i++) { - if (node0->ports[i].node && node1->ports[i].node) { + if (node0->ports[i] && node1->ports[i]) { /* * This port didn't change, queue the * connected node for further * investigation. */ - if (node0->ports[i].node->color == card->color) + if (node0->ports[i]->color == card->color) continue; - list_add_tail(&node0->ports[i].node->link, - &list0); - list_add_tail(&node1->ports[i].node->link, - &list1); - } else if (node0->ports[i].node) { + list_add_tail(&node0->ports[i]->link, &list0); + list_add_tail(&node1->ports[i]->link, &list1); + } else if (node0->ports[i]) { /* * The nodes connected here were * unplugged; unref the lost nodes and @@ -457,10 +455,10 @@ update_tree(struct fw_card *card, struct fw_node *root) * them. */ - for_each_fw_node(card, node0->ports[i].node, + for_each_fw_node(card, node0->ports[i], report_lost_node); - node0->ports[i].node = NULL; - } else if (node1->ports[i].node) { + node0->ports[i] = NULL; + } else if (node1->ports[i]) { /* * One or more node were connected to * this port. Move the new nodes into @@ -468,7 +466,7 @@ update_tree(struct fw_card *card, struct fw_node *root) * callbacks for them. */ move_tree(node0, node1, i); - for_each_fw_node(card, node0->ports[i].node, + for_each_fw_node(card, node0->ports[i], report_found_node); } } diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h index da61ec09183..1b56b4ac7fb 100644 --- a/drivers/firewire/fw-topology.h +++ b/drivers/firewire/fw-topology.h @@ -27,10 +27,6 @@ enum { FW_NODE_LINK_OFF = 0x04, }; -struct fw_port { - struct fw_node *node; -}; - struct fw_node { u16 node_id; u8 color; @@ -51,7 +47,7 @@ struct fw_node { /* Upper layer specific data. */ void *data; - struct fw_port ports[0]; + struct fw_node *ports[0]; }; static inline struct fw_node * -- cgit v1.2.3-70-g09d2 From cf47c7a26ca13b944900dce208890c5b6d5f3a14 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 17 Jun 2007 23:52:08 +0200 Subject: firewire: fw-sbp2: implement max sectors limit for some old bridges This currently only affects one bridge in the hardwired blacklist. I don't own one of those, hence haven't tested it. Signed-off-by: Stefan Richter --- drivers/firewire/fw-sbp2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 851c2da060d..49f7fd52ae8 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -1080,7 +1081,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) fw_notify("setting fix_capacity for %s\n", unit->device.bus_id); sdev->fix_capacity = 1; } - + if (sd->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS) + blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512); return 0; } -- cgit v1.2.3-70-g09d2 From 79352e9f94cff4078f2ffefac4a41b7f14046fb6 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 18 Jun 2007 18:46:49 +0200 Subject: firewire: fw-sbp2: let SCSI shutdown commands through before logout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This affects of course only the "soft shutdown" case, e.g. "modprobe -r firewire-sbp2", while it doesn't matter for hot unplug. Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 49f7fd52ae8..846aad8666f 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -520,17 +520,15 @@ static int sbp2_agent_reset(struct fw_unit *unit) static void sbp2_reconnect(struct work_struct *work); static struct scsi_host_template scsi_driver_template; -static void -release_sbp2_device(struct kref *kref) +static void release_sbp2_device(struct kref *kref) { struct sbp2_device *sd = container_of(kref, struct sbp2_device, kref); struct Scsi_Host *host = container_of((void *)sd, struct Scsi_Host, hostdata[0]); + scsi_remove_host(host); sbp2_send_management_orb(sd->unit, sd->node_id, sd->generation, SBP2_LOGOUT_REQUEST, sd->login_id, NULL); - - scsi_remove_host(host); fw_core_remove_address_handler(&sd->address_handler); fw_notify("removed sbp2 unit %s\n", sd->unit->device.bus_id); put_device(&sd->unit->device); -- cgit v1.2.3-70-g09d2 From 5cd54c94b0ba45033c126237d3d70c6e7ab52c3f Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 17 Jun 2007 23:55:41 +0200 Subject: firewire: fw-sbp2: implement nonexclusive login MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 846aad8666f..2c39f19a9ee 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -47,6 +48,18 @@ #include "fw-topology.h" #include "fw-device.h" +/* + * So far only bridges from Oxford Semiconductor are known to support + * concurrent logins. Depending on firmware, four or two concurrent logins + * are possible on OXFW911 and newer Oxsemi bridges. + * + * Concurrent logins are useful together with cluster filesystems. + */ +static int sbp2_param_exclusive_login = 1; +module_param_named(exclusive_login, sbp2_param_exclusive_login, bool, 0644); +MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " + "(default = Y, use N for concurrent initiators)"); + /* I don't know why the SCSI stack doesn't define something like this... */ typedef void (*scsi_done_fn_t)(struct scsi_cmnd *); @@ -155,7 +168,7 @@ struct sbp2_orb { #define MANAGEMENT_ORB_LUN(v) ((v)) #define MANAGEMENT_ORB_FUNCTION(v) ((v) << 16) #define MANAGEMENT_ORB_RECONNECT(v) ((v) << 20) -#define MANAGEMENT_ORB_EXCLUSIVE ((1) << 28) +#define MANAGEMENT_ORB_EXCLUSIVE(v) ((v) ? 1 << 28 : 0) #define MANAGEMENT_ORB_REQUEST_FORMAT(v) ((v) << 29) #define MANAGEMENT_ORB_NOTIFY ((1) << 31) @@ -431,14 +444,9 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, orb->request.status_fifo.high = sd->address_handler.offset >> 32; orb->request.status_fifo.low = sd->address_handler.offset; - /* - * FIXME: Yeah, ok this isn't elegant, we hardwire exclusive - * login and 1 second reconnect time. The reconnect setting - * is probably fine, but the exclusive login should be an option. - */ if (function == SBP2_LOGIN_REQUEST) { orb->request.misc |= - MANAGEMENT_ORB_EXCLUSIVE | + MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login) | MANAGEMENT_ORB_RECONNECT(0); } -- cgit v1.2.3-70-g09d2 From 6f061487f7d31427d7e8f420f366e5537ae16f43 Mon Sep 17 00:00:00 2001 From: Jay Fenlason Date: Wed, 27 Jun 2007 16:04:33 -0400 Subject: firewire: fw-sbp2: correctly dereference by container_of MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace a cast with a container_of(). As long as nobody reorders the structure elements, they do the same thing, but container_of() is more readable. Signed-off-by: Stefan Richter (added complete_command_orb) Acked-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 2c39f19a9ee..1fc1af7f55a 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -395,7 +395,7 @@ static void complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) { struct sbp2_management_orb *orb = - (struct sbp2_management_orb *)base_orb; + container_of(base_orb, struct sbp2_management_orb, base); if (status) memcpy(&orb->status, status, sizeof(*status)); @@ -838,7 +838,8 @@ sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data) static void complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) { - struct sbp2_command_orb *orb = (struct sbp2_command_orb *)base_orb; + struct sbp2_command_orb *orb = + container_of(base_orb, struct sbp2_command_orb, base); struct fw_unit *unit = orb->unit; struct fw_device *device = fw_device(unit->device.parent); struct scatterlist *sg; -- cgit v1.2.3-70-g09d2 From ffd0db26ddc32cd87097ece9725921f43ad487ee Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 1 Jul 2007 13:54:24 +0200 Subject: firewire: fw-sbp2: use correct speed in sbp2_agent_reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit noticed by Jay Fenlason Signed-off-by: Stefan Richter Acked-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 1fc1af7f55a..faee586516a 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -518,7 +518,7 @@ static int sbp2_agent_reset(struct fw_unit *unit) return -ENOMEM; fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST, - sd->node_id, sd->generation, SCODE_400, + sd->node_id, sd->generation, device->max_speed, sd->command_block_agent_address + SBP2_AGENT_RESET, &zero, sizeof(zero), complete_agent_reset_write, t); -- cgit v1.2.3-70-g09d2 From e7cdf237b2a8b4b566721cfb08e448b454c74ada Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 1 Jul 2007 13:54:57 +0200 Subject: firewire: fw-sbp2: memset wants string.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Richter Acked-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index faee586516a..491d9484df1 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3-70-g09d2 From 9fb2dd12c019965ffd15e5a0727af14488b3a772 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 1 Jul 2007 13:55:31 +0200 Subject: firewire: fw-sbp2: correctly align page tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is required per SBP-2 clause 5.2. Signed-off-by: Stefan Richter Acked-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 491d9484df1..212674d723e 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -220,7 +220,7 @@ struct sbp2_command_orb { scsi_done_fn_t done; struct fw_unit *unit; - struct sbp2_pointer page_table[SG_ALL]; + struct sbp2_pointer page_table[SG_ALL] __attribute__((aligned(8))); dma_addr_t page_table_bus; }; -- cgit v1.2.3-70-g09d2 From 332ef3310bc37ff29fd4382d6dfb38a787078091 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 1 Jul 2007 13:56:03 +0200 Subject: firewire: fw-sbp2: add a boundary check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add rudimentary check for the case that the page table overflows due to merging of s/g elements by the IOMMU. This would have lead to overwriting of arbitrary memory. After this change I expect that an offending command will be unsuccessfully retried until the scsi_device is taken offline by SCSI core. It's a border case and not worth to implement a recovery strategy. Signed-off-by: Stefan Richter Acked-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 212674d723e..c7518ea4c8e 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -937,6 +937,11 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) sg_len = sg_dma_len(sg + i); sg_addr = sg_dma_address(sg + i); while (sg_len) { + /* FIXME: This won't get us out of the pinch. */ + if (unlikely(j >= ARRAY_SIZE(orb->page_table))) { + fw_error("page table overflow\n"); + 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); -- cgit v1.2.3-70-g09d2 From b4be016ad81af5a83f0be820edf106de883e6ade Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 2 Jul 2007 22:07:34 +0200 Subject: firewire: fw-sbp2: fix DMA mapping of S/G tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - The CPU must not touch the buffer after it was DMA-mapped. - The size argument of dma_unmap_single(...page_table...) was bogus. - Move a comment closer to the code to which it refers to. Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index c7518ea4c8e..a2ddf318a25 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -887,7 +887,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) if (orb->page_table_bus != 0) dma_unmap_single(device->card->device, orb->page_table_bus, - sizeof(orb->page_table_bus), DMA_TO_DEVICE); + sizeof(orb->page_table), DMA_TO_DEVICE); orb->cmd->result = result; orb->done(orb->cmd); @@ -902,7 +902,6 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) struct fw_device *device = fw_device(unit->device.parent); struct scatterlist *sg; int sg_len, l, i, j, count; - size_t size; dma_addr_t sg_addr; sg = (struct scatterlist *)orb->cmd->request_buffer; @@ -951,7 +950,13 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) } } - size = sizeof(orb->page_table[0]) * 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); + if (dma_mapping_error(orb->page_table_bus)) + goto fail_page_table; /* * The data_descriptor pointer is the one case where we need @@ -960,20 +965,12 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) * 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->page_table_bus = - dma_map_single(device->card->device, orb->page_table, - size, DMA_TO_DEVICE); - if (dma_mapping_error(orb->page_table_bus)) - goto fail_page_table; orb->request.data_descriptor.high = sd->address_high; orb->request.data_descriptor.low = orb->page_table_bus; orb->request.misc |= COMMAND_ORB_PAGE_TABLE_PRESENT | COMMAND_ORB_DATA_SIZE(j); - fw_memcpy_to_be32(orb->page_table, orb->page_table, size); - return 0; fail_page_table: -- cgit v1.2.3-70-g09d2 From 8526392ae816a2c69f57097ba032865523019caa Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 2 Jul 2007 21:04:08 +0200 Subject: firewire: fw-sbp2: fix DMA mapping of command ORBs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CPU must not touch the buffer after it was DMA-mapped. Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index a2ddf318a25..f488ff8903f 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -1009,11 +1009,6 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) /* Initialize rcode to something not RCODE_COMPLETE. */ orb->base.rcode = -1; - orb->base.request_bus = - dma_map_single(device->card->device, &orb->request, - sizeof(orb->request), DMA_TO_DEVICE); - if (dma_mapping_error(orb->base.request_bus)) - goto fail_mapping; orb->unit = unit; orb->done = done; @@ -1040,7 +1035,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA); if (cmd->use_sg && sbp2_command_orb_map_scatterlist(orb) < 0) - goto fail_map_payload; + goto fail_mapping; fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request)); @@ -1049,15 +1044,17 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); orb->base.callback = complete_command_orb; + orb->base.request_bus = + dma_map_single(device->card->device, &orb->request, + sizeof(orb->request), DMA_TO_DEVICE); + if (dma_mapping_error(orb->base.request_bus)) + goto fail_mapping; sbp2_send_orb(&orb->base, unit, sd->node_id, sd->generation, sd->command_block_agent_address + SBP2_ORB_POINTER); return 0; - fail_map_payload: - dma_unmap_single(device->card->device, orb->base.request_bus, - sizeof(orb->request), DMA_TO_DEVICE); fail_mapping: kfree(orb); fail_alloc: -- cgit v1.2.3-70-g09d2 From 7aa484815f8c4defd01366f239b71da5e6b8a791 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 2 Jul 2007 21:04:44 +0200 Subject: firewire: fw-sbp2: fix DMA mapping of management ORBs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CPU must not touch the buffer after it was DMA-mapped. Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers/firewire') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index f488ff8903f..7c53be0387f 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -416,21 +416,11 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, if (orb == NULL) return -ENOMEM; - /* - * The sbp2 device is going to send a block read request to - * read out the request from host memory, so map it for dma. - */ - orb->base.request_bus = - dma_map_single(device->card->device, &orb->request, - sizeof(orb->request), DMA_TO_DEVICE); - if (dma_mapping_error(orb->base.request_bus)) - goto out; - orb->response_bus = dma_map_single(device->card->device, &orb->response, sizeof(orb->response), DMA_FROM_DEVICE); if (dma_mapping_error(orb->response_bus)) - goto out; + goto fail_mapping_response; orb->request.response.high = 0; orb->request.response.low = orb->response_bus; @@ -456,6 +446,12 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, init_completion(&orb->done); orb->base.callback = complete_management_orb; + orb->base.request_bus = + dma_map_single(device->card->device, &orb->request, + sizeof(orb->request), DMA_TO_DEVICE); + if (dma_mapping_error(orb->base.request_bus)) + goto fail_mapping_request; + sbp2_send_orb(&orb->base, unit, node_id, generation, sd->management_agent_address); @@ -487,9 +483,10 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, out: dma_unmap_single(device->card->device, orb->base.request_bus, sizeof(orb->request), DMA_TO_DEVICE); + fail_mapping_request: dma_unmap_single(device->card->device, orb->response_bus, sizeof(orb->response), DMA_FROM_DEVICE); - + fail_mapping_response: if (response) fw_memcpy_from_be32(response, orb->response, sizeof(orb->response)); -- cgit v1.2.3-70-g09d2