aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/core-transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firewire/core-transaction.c')
-rw-r--r--drivers/firewire/core-transaction.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 673b03f8b4ec..9882240205cd 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -229,6 +229,23 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
229 packet->payload_mapped = false; 229 packet->payload_mapped = false;
230} 230}
231 231
232static int allocate_tlabel(struct fw_card *card)
233{
234 int tlabel;
235
236 tlabel = card->current_tlabel;
237 while (card->tlabel_mask & (1ULL << tlabel)) {
238 tlabel = (tlabel + 1) & 0x3f;
239 if (tlabel == card->current_tlabel)
240 return -EBUSY;
241 }
242
243 card->current_tlabel = (tlabel + 1) & 0x3f;
244 card->tlabel_mask |= 1ULL << tlabel;
245
246 return tlabel;
247}
248
232/** 249/**
233 * This function provides low-level access to the IEEE1394 transaction 250 * This function provides low-level access to the IEEE1394 transaction
234 * logic. Most C programs would use either fw_read(), fw_write() or 251 * logic. Most C programs would use either fw_read(), fw_write() or
@@ -290,16 +307,13 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
290 307
291 spin_lock_irqsave(&card->lock, flags); 308 spin_lock_irqsave(&card->lock, flags);
292 309
293 tlabel = card->current_tlabel; 310 tlabel = allocate_tlabel(card);
294 if (card->tlabel_mask & (1ULL << tlabel)) { 311 if (tlabel < 0) {
295 spin_unlock_irqrestore(&card->lock, flags); 312 spin_unlock_irqrestore(&card->lock, flags);
296 callback(card, RCODE_SEND_ERROR, NULL, 0, callback_data); 313 callback(card, RCODE_SEND_ERROR, NULL, 0, callback_data);
297 return; 314 return;
298 } 315 }
299 316
300 card->current_tlabel = (card->current_tlabel + 1) & 0x3f;
301 card->tlabel_mask |= (1ULL << tlabel);
302
303 t->node_id = destination_id; 317 t->node_id = destination_id;
304 t->tlabel = tlabel; 318 t->tlabel = tlabel;
305 t->callback = callback; 319 t->callback = callback;