aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorJay Fenlason <fenlason@redhat.com>2008-07-20 08:20:53 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2008-10-15 16:21:09 -0400
commit1e119fa9950dfe0e6d97470098db776110ca47a9 (patch)
tree02ad70ddae6d5cf4869c628e44dae97686a03d97 /drivers/firewire
parentfc392fe83176cefbab99f9d12e6e27395aa2b5d0 (diff)
firewire: fw_send_request_sync()
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>
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/fw-card.c56
-rw-r--r--drivers/firewire/fw-device.c37
-rw-r--r--drivers/firewire/fw-sbp2.c46
-rw-r--r--drivers/firewire/fw-transaction.c48
-rw-r--r--drivers/firewire/fw-transaction.h9
5 files changed, 82 insertions, 114 deletions
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index bbd73a406e53..418c18f07e9d 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -189,39 +189,16 @@ static const char gap_count_table[] = {
189 63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40 189 63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40
190}; 190};
191 191
192struct bm_data {
193 struct fw_transaction t;
194 struct {
195 __be32 arg;
196 __be32 data;
197 } lock;
198 u32 old;
199 int rcode;
200 struct completion done;
201};
202
203static void
204complete_bm_lock(struct fw_card *card, int rcode,
205 void *payload, size_t length, void *data)
206{
207 struct bm_data *bmd = data;
208
209 if (rcode == RCODE_COMPLETE)
210 bmd->old = be32_to_cpu(*(__be32 *) payload);
211 bmd->rcode = rcode;
212 complete(&bmd->done);
213}
214
215static void 192static void
216fw_card_bm_work(struct work_struct *work) 193fw_card_bm_work(struct work_struct *work)
217{ 194{
218 struct fw_card *card = container_of(work, struct fw_card, work.work); 195 struct fw_card *card = container_of(work, struct fw_card, work.work);
219 struct fw_device *root_device; 196 struct fw_device *root_device;
220 struct fw_node *root_node, *local_node; 197 struct fw_node *root_node, *local_node;
221 struct bm_data bmd;
222 unsigned long flags; 198 unsigned long flags;
223 int root_id, new_root_id, irm_id, gap_count, generation, grace; 199 int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode;
224 bool do_reset = false; 200 bool do_reset = false;
201 __be32 lock_data[2];
225 202
226 spin_lock_irqsave(&card->lock, flags); 203 spin_lock_irqsave(&card->lock, flags);
227 local_node = card->local_node; 204 local_node = card->local_node;
@@ -263,33 +240,28 @@ fw_card_bm_work(struct work_struct *work)
263 goto pick_me; 240 goto pick_me;
264 } 241 }
265 242
266 bmd.lock.arg = cpu_to_be32(0x3f); 243 lock_data[0] = cpu_to_be32(0x3f);
267 bmd.lock.data = cpu_to_be32(local_node->node_id); 244 lock_data[1] = cpu_to_be32(local_node->node_id);
268 245
269 spin_unlock_irqrestore(&card->lock, flags); 246 spin_unlock_irqrestore(&card->lock, flags);
270 247
271 init_completion(&bmd.done); 248 rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
272 fw_send_request(card, &bmd.t, TCODE_LOCK_COMPARE_SWAP, 249 irm_id, generation, SCODE_100,
273 irm_id, generation, 250 CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
274 SCODE_100, CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, 251 lock_data, sizeof(lock_data));
275 &bmd.lock, sizeof(bmd.lock),
276 complete_bm_lock, &bmd);
277 wait_for_completion(&bmd.done);
278 252
279 if (bmd.rcode == RCODE_GENERATION) { 253 if (rcode == RCODE_GENERATION)
280 /* 254 /* Another bus reset, BM work has been rescheduled. */
281 * Another bus reset happened. Just return,
282 * the BM work has been rescheduled.
283 */
284 goto out; 255 goto out;
285 }
286 256
287 if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f) 257 if (rcode == RCODE_COMPLETE &&
258 lock_data[0] != cpu_to_be32(0x3f))
288 /* Somebody else is BM, let them do the work. */ 259 /* Somebody else is BM, let them do the work. */
289 goto out; 260 goto out;
290 261
291 spin_lock_irqsave(&card->lock, flags); 262 spin_lock_irqsave(&card->lock, flags);
292 if (bmd.rcode != RCODE_COMPLETE) { 263
264 if (rcode != RCODE_COMPLETE) {
293 /* 265 /*
294 * The lock request failed, maybe the IRM 266 * The lock request failed, maybe the IRM
295 * isn't really IRM capable after all. Let's 267 * isn't really IRM capable after all. Let's
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index 0855fb5568e8..3fccdd484100 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -381,46 +381,21 @@ static struct device_attribute fw_device_attributes[] = {
381 __ATTR_NULL, 381 __ATTR_NULL,
382}; 382};
383 383
384struct read_quadlet_callback_data {
385 struct completion done;
386 int rcode;
387 u32 data;
388};
389
390static void
391complete_transaction(struct fw_card *card, int rcode,
392 void *payload, size_t length, void *data)
393{
394 struct read_quadlet_callback_data *callback_data = data;
395
396 if (rcode == RCODE_COMPLETE)
397 callback_data->data = be32_to_cpu(*(__be32 *)payload);
398 callback_data->rcode = rcode;
399 complete(&callback_data->done);
400}
401
402static int 384static int
403read_rom(struct fw_device *device, int generation, int index, u32 *data) 385read_rom(struct fw_device *device, int generation, int index, u32 *data)
404{ 386{
405 struct read_quadlet_callback_data callback_data; 387 int rcode;
406 struct fw_transaction t;
407 u64 offset;
408 388
409 /* device->node_id, accessed below, must not be older than generation */ 389 /* device->node_id, accessed below, must not be older than generation */
410 smp_rmb(); 390 smp_rmb();
411 391
412 init_completion(&callback_data.done); 392 rcode = fw_run_transaction(device->card, TCODE_READ_QUADLET_REQUEST,
413
414 offset = (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4;
415 fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST,
416 device->node_id, generation, device->max_speed, 393 device->node_id, generation, device->max_speed,
417 offset, NULL, 4, complete_transaction, &callback_data); 394 (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4,
418 395 data, 4);
419 wait_for_completion(&callback_data.done); 396 be32_to_cpus(data);
420
421 *data = callback_data.data;
422 397
423 return callback_data.rcode; 398 return rcode;
424} 399}
425 400
426#define READ_BIB_ROM_SIZE 256 401#define READ_BIB_ROM_SIZE 256
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index aaff50ebba1d..05997cee4f37 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -621,25 +621,15 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
621 return retval; 621 return retval;
622} 622}
623 623
624static void
625complete_agent_reset_write(struct fw_card *card, int rcode,
626 void *payload, size_t length, void *done)
627{
628 complete(done);
629}
630
631static void sbp2_agent_reset(struct sbp2_logical_unit *lu) 624static void sbp2_agent_reset(struct sbp2_logical_unit *lu)
632{ 625{
633 struct fw_device *device = fw_device(lu->tgt->unit->device.parent); 626 struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
634 DECLARE_COMPLETION_ONSTACK(done); 627 __be32 d = 0;
635 struct fw_transaction t;
636 static u32 z;
637 628
638 fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST, 629 fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST,
639 lu->tgt->node_id, lu->generation, device->max_speed, 630 lu->tgt->node_id, lu->generation, device->max_speed,
640 lu->command_block_agent_address + SBP2_AGENT_RESET, 631 lu->command_block_agent_address + SBP2_AGENT_RESET,
641 &z, sizeof(z), complete_agent_reset_write, &done); 632 &d, sizeof(d));
642 wait_for_completion(&done);
643} 633}
644 634
645static void 635static void
@@ -653,7 +643,7 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
653{ 643{
654 struct fw_device *device = fw_device(lu->tgt->unit->device.parent); 644 struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
655 struct fw_transaction *t; 645 struct fw_transaction *t;
656 static u32 z; 646 static __be32 d;
657 647
658 t = kmalloc(sizeof(*t), GFP_ATOMIC); 648 t = kmalloc(sizeof(*t), GFP_ATOMIC);
659 if (t == NULL) 649 if (t == NULL)
@@ -662,7 +652,7 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
662 fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST, 652 fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
663 lu->tgt->node_id, lu->generation, device->max_speed, 653 lu->tgt->node_id, lu->generation, device->max_speed,
664 lu->command_block_agent_address + SBP2_AGENT_RESET, 654 lu->command_block_agent_address + SBP2_AGENT_RESET,
665 &z, sizeof(z), complete_agent_reset_write_no_wait, t); 655 &d, sizeof(d), complete_agent_reset_write_no_wait, t);
666} 656}
667 657
668static void sbp2_set_generation(struct sbp2_logical_unit *lu, int generation) 658static void sbp2_set_generation(struct sbp2_logical_unit *lu, int generation)
@@ -823,13 +813,6 @@ static void sbp2_target_put(struct sbp2_target *tgt)
823 kref_put(&tgt->kref, sbp2_release_target); 813 kref_put(&tgt->kref, sbp2_release_target);
824} 814}
825 815
826static void
827complete_set_busy_timeout(struct fw_card *card, int rcode,
828 void *payload, size_t length, void *done)
829{
830 complete(done);
831}
832
833/* 816/*
834 * Write retransmit retry values into the BUSY_TIMEOUT register. 817 * Write retransmit retry values into the BUSY_TIMEOUT register.
835 * - The single-phase retry protocol is supported by all SBP-2 devices, but the 818 * - 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,
849static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu) 832static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu)
850{ 833{
851 struct fw_device *device = fw_device(lu->tgt->unit->device.parent); 834 struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
852 DECLARE_COMPLETION_ONSTACK(done); 835 __be32 d = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT);
853 struct fw_transaction t;
854 static __be32 busy_timeout;
855
856 busy_timeout = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT);
857 836
858 fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST, 837 fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST,
859 lu->tgt->node_id, lu->generation, device->max_speed, 838 lu->tgt->node_id, lu->generation, device->max_speed,
860 CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT, &busy_timeout, 839 CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT,
861 sizeof(busy_timeout), complete_set_busy_timeout, &done); 840 &d, sizeof(d));
862 wait_for_completion(&done);
863} 841}
864 842
865static void sbp2_reconnect(struct work_struct *work); 843static void sbp2_reconnect(struct work_struct *work);
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index e5d1a0b64fcf..022ac4fabb67 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -247,7 +247,7 @@ fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
247 */ 247 */
248void 248void
249fw_send_request(struct fw_card *card, struct fw_transaction *t, 249fw_send_request(struct fw_card *card, struct fw_transaction *t,
250 int tcode, int node_id, int generation, int speed, 250 int tcode, int destination_id, int generation, int speed,
251 unsigned long long offset, 251 unsigned long long offset,
252 void *payload, size_t length, 252 void *payload, size_t length,
253 fw_transaction_callback_t callback, void *callback_data) 253 fw_transaction_callback_t callback, void *callback_data)
@@ -279,13 +279,14 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t,
279 card->current_tlabel = (card->current_tlabel + 1) & 0x1f; 279 card->current_tlabel = (card->current_tlabel + 1) & 0x1f;
280 card->tlabel_mask |= (1 << tlabel); 280 card->tlabel_mask |= (1 << tlabel);
281 281
282 t->node_id = node_id; 282 t->node_id = destination_id;
283 t->tlabel = tlabel; 283 t->tlabel = tlabel;
284 t->callback = callback; 284 t->callback = callback;
285 t->callback_data = callback_data; 285 t->callback_data = callback_data;
286 286
287 fw_fill_request(&t->packet, tcode, t->tlabel, node_id, card->node_id, 287 fw_fill_request(&t->packet, tcode, t->tlabel,
288 generation, speed, offset, payload, length); 288 destination_id, card->node_id, generation,
289 speed, offset, payload, length);
289 t->packet.callback = transmit_complete_callback; 290 t->packet.callback = transmit_complete_callback;
290 291
291 list_add_tail(&t->link, &card->transaction_list); 292 list_add_tail(&t->link, &card->transaction_list);
@@ -296,6 +297,45 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t,
296} 297}
297EXPORT_SYMBOL(fw_send_request); 298EXPORT_SYMBOL(fw_send_request);
298 299
300struct transaction_callback_data {
301 struct completion done;
302 void *payload;
303 int rcode;
304};
305
306static void transaction_callback(struct fw_card *card, int rcode,
307 void *payload, size_t length, void *data)
308{
309 struct transaction_callback_data *d = data;
310
311 if (rcode == RCODE_COMPLETE)
312 memcpy(d->payload, payload, length);
313 d->rcode = rcode;
314 complete(&d->done);
315}
316
317/**
318 * fw_run_transaction - send request and sleep until transaction is completed
319 *
320 * Returns the RCODE.
321 */
322int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
323 int generation, int speed, unsigned long long offset,
324 void *data, size_t length)
325{
326 struct transaction_callback_data d;
327 struct fw_transaction t;
328
329 init_completion(&d.done);
330 d.payload = data;
331 fw_send_request(card, &t, tcode, destination_id, generation, speed,
332 offset, data, length, transaction_callback, &d);
333 wait_for_completion(&d.done);
334
335 return d.rcode;
336}
337EXPORT_SYMBOL(fw_run_transaction);
338
299static DEFINE_MUTEX(phy_config_mutex); 339static DEFINE_MUTEX(phy_config_mutex);
300static DECLARE_COMPLETION(phy_config_done); 340static DECLARE_COMPLETION(phy_config_done);
301 341
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index 2ae1b0d6cb7b..027f58ce81ad 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -426,11 +426,14 @@ fw_core_initiate_bus_reset(struct fw_card *card, int short_reset);
426 426
427void 427void
428fw_send_request(struct fw_card *card, struct fw_transaction *t, 428fw_send_request(struct fw_card *card, struct fw_transaction *t,
429 int tcode, int node_id, int generation, int speed, 429 int tcode, int destination_id, int generation, int speed,
430 unsigned long long offset, 430 unsigned long long offset, void *data, size_t length,
431 void *data, size_t length,
432 fw_transaction_callback_t callback, void *callback_data); 431 fw_transaction_callback_t callback, void *callback_data);
433 432
433int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
434 int generation, int speed, unsigned long long offset,
435 void *data, size_t length);
436
434int fw_cancel_transaction(struct fw_card *card, 437int fw_cancel_transaction(struct fw_card *card,
435 struct fw_transaction *transaction); 438 struct fw_transaction *transaction);
436 439