firewire: fw_send_request_sync()
authorJay Fenlason <fenlason@redhat.com>
Sun, 20 Jul 2008 12:20:53 +0000 (14:20 +0200)
committerStefan Richter <stefanr@s5r6.in-berlin.de>
Wed, 15 Oct 2008 20:21:09 +0000 (22:21 +0200)
Share code between fw_send_request + wait_for_completion callers.

Signed-off-by: Jay Fenlason <fenlason@redhat.com>
Addendum:
Removes an unnecessary struct and an ununsed retry loop.
Calls it fw_run_transaction() instead of fw_send_request_sync().

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Acked-by: Kristian Høgsberg <krh@redhat.com>
drivers/firewire/fw-card.c
drivers/firewire/fw-device.c
drivers/firewire/fw-sbp2.c
drivers/firewire/fw-transaction.c
drivers/firewire/fw-transaction.h

index bbd73a4..418c18f 100644 (file)
@@ -189,39 +189,16 @@ static const char gap_count_table[] = {
        63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40
 };
 
-struct bm_data {
-       struct fw_transaction t;
-       struct {
-               __be32 arg;
-               __be32 data;
-       } lock;
-       u32 old;
-       int rcode;
-       struct completion done;
-};
-
-static void
-complete_bm_lock(struct fw_card *card, int rcode,
-                void *payload, size_t length, void *data)
-{
-       struct bm_data *bmd = data;
-
-       if (rcode == RCODE_COMPLETE)
-               bmd->old = be32_to_cpu(*(__be32 *) payload);
-       bmd->rcode = rcode;
-       complete(&bmd->done);
-}
-
 static void
 fw_card_bm_work(struct work_struct *work)
 {
        struct fw_card *card = container_of(work, struct fw_card, work.work);
        struct fw_device *root_device;
        struct fw_node *root_node, *local_node;
-       struct bm_data bmd;
        unsigned long flags;
-       int root_id, new_root_id, irm_id, gap_count, generation, grace;
+       int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode;
        bool do_reset = false;
+       __be32 lock_data[2];
 
        spin_lock_irqsave(&card->lock, flags);
        local_node = card->local_node;
@@ -263,33 +240,28 @@ fw_card_bm_work(struct work_struct *work)
                        goto pick_me;
                }
 
-               bmd.lock.arg = cpu_to_be32(0x3f);
-               bmd.lock.data = cpu_to_be32(local_node->node_id);
+               lock_data[0] = cpu_to_be32(0x3f);
+               lock_data[1] = cpu_to_be32(local_node->node_id);
 
                spin_unlock_irqrestore(&card->lock, flags);
 
-               init_completion(&bmd.done);
-               fw_send_request(card, &bmd.t, TCODE_LOCK_COMPARE_SWAP,
-                               irm_id, generation,
-                               SCODE_100, CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
-                               &bmd.lock, sizeof(bmd.lock),
-                               complete_bm_lock, &bmd);
-               wait_for_completion(&bmd.done);
+               rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
+                               irm_id, generation, SCODE_100,
+                               CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
+                               lock_data, sizeof(lock_data));
 
-               if (bmd.rcode == RCODE_GENERATION) {
-                       /*
-                        * Another bus reset happened. Just return,
-                        * the BM work has been rescheduled.
-                        */
+               if (rcode == RCODE_GENERATION)
+                       /* Another bus reset, BM work has been rescheduled. */
                        goto out;
-               }
 
-               if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f)
+               if (rcode == RCODE_COMPLETE &&
+                   lock_data[0] != cpu_to_be32(0x3f))
                        /* Somebody else is BM, let them do the work. */
                        goto out;
 
                spin_lock_irqsave(&card->lock, flags);
-               if (bmd.rcode != RCODE_COMPLETE) {
+
+               if (rcode != RCODE_COMPLETE) {
                        /*
                         * The lock request failed, maybe the IRM
                         * isn't really IRM capable after all. Let's
index 0855fb5..3fccdd4 100644 (file)
@@ -381,46 +381,21 @@ static struct device_attribute fw_device_attributes[] = {
        __ATTR_NULL,
 };
 
-struct read_quadlet_callback_data {
-       struct completion done;
-       int rcode;
-       u32 data;
-};
-
-static void
-complete_transaction(struct fw_card *card, int rcode,
-                    void *payload, size_t length, void *data)
-{
-       struct read_quadlet_callback_data *callback_data = data;
-
-       if (rcode == RCODE_COMPLETE)
-               callback_data->data = be32_to_cpu(*(__be32 *)payload);
-       callback_data->rcode = rcode;
-       complete(&callback_data->done);
-}
-
 static int
 read_rom(struct fw_device *device, int generation, int index, u32 *data)
 {
-       struct read_quadlet_callback_data callback_data;
-       struct fw_transaction t;
-       u64 offset;
+       int rcode;
 
        /* device->node_id, accessed below, must not be older than generation */
        smp_rmb();
 
-       init_completion(&callback_data.done);
-
-       offset = (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4;
-       fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST,
+       rcode = fw_run_transaction(device->card, TCODE_READ_QUADLET_REQUEST,
                        device->node_id, generation, device->max_speed,
-                       offset, NULL, 4, complete_transaction, &callback_data);
-
-       wait_for_completion(&callback_data.done);
-
-       *data = callback_data.data;
+                       (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4,
+                       data, 4);
+       be32_to_cpus(data);
 
-       return callback_data.rcode;
+       return rcode;
 }
 
 #define READ_BIB_ROM_SIZE      256
index aaff50e..05997ce 100644 (file)
@@ -621,25 +621,15 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
        return retval;
 }
 
-static void
-complete_agent_reset_write(struct fw_card *card, int rcode,
-                          void *payload, size_t length, void *done)
-{
-       complete(done);
-}
-
 static void sbp2_agent_reset(struct sbp2_logical_unit *lu)
 {
        struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
-       DECLARE_COMPLETION_ONSTACK(done);
-       struct fw_transaction t;
-       static u32 z;
+       __be32 d = 0;
 
-       fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
-                       lu->tgt->node_id, lu->generation, device->max_speed,
-                       lu->command_block_agent_address + SBP2_AGENT_RESET,
-                       &z, sizeof(z), complete_agent_reset_write, &done);
-       wait_for_completion(&done);
+       fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST,
+                          lu->tgt->node_id, lu->generation, device->max_speed,
+                          lu->command_block_agent_address + SBP2_AGENT_RESET,
+                          &d, sizeof(d));
 }
 
 static void
@@ -653,7 +643,7 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
 {
        struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
        struct fw_transaction *t;
-       static u32 z;
+       static __be32 d;
 
        t = kmalloc(sizeof(*t), GFP_ATOMIC);
        if (t == NULL)
@@ -662,7 +652,7 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
        fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
                        lu->tgt->node_id, lu->generation, device->max_speed,
                        lu->command_block_agent_address + SBP2_AGENT_RESET,
-                       &z, sizeof(z), complete_agent_reset_write_no_wait, t);
+                       &d, sizeof(d), complete_agent_reset_write_no_wait, t);
 }
 
 static void sbp2_set_generation(struct sbp2_logical_unit *lu, int generation)
@@ -823,13 +813,6 @@ static void sbp2_target_put(struct sbp2_target *tgt)
        kref_put(&tgt->kref, sbp2_release_target);
 }
 
-static void
-complete_set_busy_timeout(struct fw_card *card, int rcode,
-                         void *payload, size_t length, void *done)
-{
-       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
@@ -849,17 +832,12 @@ complete_set_busy_timeout(struct fw_card *card, int rcode,
 static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu)
 {
        struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
-       DECLARE_COMPLETION_ONSTACK(done);
-       struct fw_transaction t;
-       static __be32 busy_timeout;
-
-       busy_timeout = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT);
+       __be32 d = 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,
-                       CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT, &busy_timeout,
-                       sizeof(busy_timeout), complete_set_busy_timeout, &done);
-       wait_for_completion(&done);
+       fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST,
+                          lu->tgt->node_id, lu->generation, device->max_speed,
+                          CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT,
+                          &d, sizeof(d));
 }
 
 static void sbp2_reconnect(struct work_struct *work);
index e5d1a0b..022ac4f 100644 (file)
@@ -247,7 +247,7 @@ fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
  */
 void
 fw_send_request(struct fw_card *card, struct fw_transaction *t,
-               int tcode, int node_id, int generation, int speed,
+               int tcode, int destination_id, int generation, int speed,
                unsigned long long offset,
                void *payload, size_t length,
                fw_transaction_callback_t callback, void *callback_data)
@@ -279,13 +279,14 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t,
        card->current_tlabel = (card->current_tlabel + 1) & 0x1f;
        card->tlabel_mask |= (1 << tlabel);
 
-       t->node_id = node_id;
+       t->node_id = destination_id;
        t->tlabel = tlabel;
        t->callback = callback;
        t->callback_data = callback_data;
 
-       fw_fill_request(&t->packet, tcode, t->tlabel, node_id, card->node_id,
-                       generation, speed, offset, payload, length);
+       fw_fill_request(&t->packet, tcode, t->tlabel,
+                       destination_id, card->node_id, generation,
+                       speed, offset, payload, length);
        t->packet.callback = transmit_complete_callback;
 
        list_add_tail(&t->link, &card->transaction_list);
@@ -296,6 +297,45 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t,
 }
 EXPORT_SYMBOL(fw_send_request);
 
+struct transaction_callback_data {
+       struct completion done;
+       void *payload;
+       int rcode;
+};
+
+static void transaction_callback(struct fw_card *card, int rcode,
+                                void *payload, size_t length, void *data)
+{
+       struct transaction_callback_data *d = data;
+
+       if (rcode == RCODE_COMPLETE)
+               memcpy(d->payload, payload, length);
+       d->rcode = rcode;
+       complete(&d->done);
+}
+
+/**
+ * fw_run_transaction - send request and sleep until transaction is completed
+ *
+ * Returns the RCODE.
+ */
+int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
+               int generation, int speed, unsigned long long offset,
+               void *data, size_t length)
+{
+       struct transaction_callback_data d;
+       struct fw_transaction t;
+
+       init_completion(&d.done);
+       d.payload = data;
+       fw_send_request(card, &t, tcode, destination_id, generation, speed,
+                       offset, data, length, transaction_callback, &d);
+       wait_for_completion(&d.done);
+
+       return d.rcode;
+}
+EXPORT_SYMBOL(fw_run_transaction);
+
 static DEFINE_MUTEX(phy_config_mutex);
 static DECLARE_COMPLETION(phy_config_done);
 
index 2ae1b0d..027f58c 100644 (file)
@@ -426,11 +426,14 @@ fw_core_initiate_bus_reset(struct fw_card *card, int short_reset);
 
 void
 fw_send_request(struct fw_card *card, struct fw_transaction *t,
-               int tcode, int node_id, int generation, int speed,
-               unsigned long long offset,
-               void *data, size_t length,
+               int tcode, int destination_id, int generation, int speed,
+               unsigned long long offset, void *data, size_t length,
                fw_transaction_callback_t callback, void *callback_data);
 
+int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
+                      int generation, int speed, unsigned long long offset,
+                      void *data, size_t length);
+
 int fw_cancel_transaction(struct fw_card *card,
                          struct fw_transaction *transaction);