diff options
Diffstat (limited to 'drivers/firewire/core-transaction.c')
-rw-r--r-- | drivers/firewire/core-transaction.c | 24 |
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 | ||
232 | static 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; |