aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-25 14:24:53 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-25 14:24:53 -0400
commitf2154eef2a926435cdf79156cd361092d6cba91e (patch)
treebc92864fd906158d65f8792af2e166dd68fa4a50
parent6ae26fa468533c86aaa6936fd366142fcf01386f (diff)
parente57d2011a6276d55a87f26653a0395f302ce0d51 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6: firewire: Add ref-counting for sbp2 orbs (fix command abortion) firewire: fix unloading of fw-ohci while devices are attached ieee1394: sbp2: fix sbp2_remove_device for error cases
-rw-r--r--drivers/firewire/fw-card.c6
-rw-r--r--drivers/firewire/fw-sbp2.c49
-rw-r--r--drivers/ieee1394/sbp2.c14
3 files changed, 51 insertions, 18 deletions
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index 0aeab3218bb6..3e9719948a8e 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -510,9 +510,11 @@ fw_core_remove_card(struct fw_card *card)
510 /* Set up the dummy driver. */ 510 /* Set up the dummy driver. */
511 card->driver = &dummy_driver; 511 card->driver = &dummy_driver;
512 512
513 fw_flush_transactions(card);
514
515 fw_destroy_nodes(card); 513 fw_destroy_nodes(card);
514 flush_scheduled_work();
515
516 fw_flush_transactions(card);
517 del_timer_sync(&card->flush_timer);
516 518
517 fw_card_put(card); 519 fw_card_put(card);
518} 520}
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index ba816ef6def1..238730f75db1 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -159,6 +159,7 @@ struct sbp2_pointer {
159 159
160struct sbp2_orb { 160struct sbp2_orb {
161 struct fw_transaction t; 161 struct fw_transaction t;
162 struct kref kref;
162 dma_addr_t request_bus; 163 dma_addr_t request_bus;
163 int rcode; 164 int rcode;
164 struct sbp2_pointer pointer; 165 struct sbp2_pointer pointer;
@@ -280,6 +281,14 @@ static const struct {
280}; 281};
281 282
282static void 283static void
284free_orb(struct kref *kref)
285{
286 struct sbp2_orb *orb = container_of(kref, struct sbp2_orb, kref);
287
288 kfree(orb);
289}
290
291static void
283sbp2_status_write(struct fw_card *card, struct fw_request *request, 292sbp2_status_write(struct fw_card *card, struct fw_request *request,
284 int tcode, int destination, int source, 293 int tcode, int destination, int source,
285 int generation, int speed, 294 int generation, int speed,
@@ -312,8 +321,8 @@ sbp2_status_write(struct fw_card *card, struct fw_request *request,
312 spin_lock_irqsave(&card->lock, flags); 321 spin_lock_irqsave(&card->lock, flags);
313 list_for_each_entry(orb, &sd->orb_list, link) { 322 list_for_each_entry(orb, &sd->orb_list, link) {
314 if (STATUS_GET_ORB_HIGH(status) == 0 && 323 if (STATUS_GET_ORB_HIGH(status) == 0 &&
315 STATUS_GET_ORB_LOW(status) == orb->request_bus && 324 STATUS_GET_ORB_LOW(status) == orb->request_bus) {
316 orb->rcode == RCODE_COMPLETE) { 325 orb->rcode = RCODE_COMPLETE;
317 list_del(&orb->link); 326 list_del(&orb->link);
318 break; 327 break;
319 } 328 }
@@ -325,6 +334,8 @@ sbp2_status_write(struct fw_card *card, struct fw_request *request,
325 else 334 else
326 fw_error("status write for unknown orb\n"); 335 fw_error("status write for unknown orb\n");
327 336
337 kref_put(&orb->kref, free_orb);
338
328 fw_send_response(card, request, RCODE_COMPLETE); 339 fw_send_response(card, request, RCODE_COMPLETE);
329} 340}
330 341
@@ -335,13 +346,27 @@ complete_transaction(struct fw_card *card, int rcode,
335 struct sbp2_orb *orb = data; 346 struct sbp2_orb *orb = data;
336 unsigned long flags; 347 unsigned long flags;
337 348
338 orb->rcode = rcode; 349 /*
339 if (rcode != RCODE_COMPLETE) { 350 * This is a little tricky. We can get the status write for
340 spin_lock_irqsave(&card->lock, flags); 351 * the orb before we get this callback. The status write
352 * handler above will assume the orb pointer transaction was
353 * successful and set the rcode to RCODE_COMPLETE for the orb.
354 * So this callback only sets the rcode if it hasn't already
355 * been set and only does the cleanup if the transaction
356 * failed and we didn't already get a status write.
357 */
358 spin_lock_irqsave(&card->lock, flags);
359
360 if (orb->rcode == -1)
361 orb->rcode = rcode;
362 if (orb->rcode != RCODE_COMPLETE) {
341 list_del(&orb->link); 363 list_del(&orb->link);
342 spin_unlock_irqrestore(&card->lock, flags);
343 orb->callback(orb, NULL); 364 orb->callback(orb, NULL);
344 } 365 }
366
367 spin_unlock_irqrestore(&card->lock, flags);
368
369 kref_put(&orb->kref, free_orb);
345} 370}
346 371
347static void 372static void
@@ -360,6 +385,10 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit,
360 list_add_tail(&orb->link, &sd->orb_list); 385 list_add_tail(&orb->link, &sd->orb_list);
361 spin_unlock_irqrestore(&device->card->lock, flags); 386 spin_unlock_irqrestore(&device->card->lock, flags);
362 387
388 /* Take a ref for the orb list and for the transaction callback. */
389 kref_get(&orb->kref);
390 kref_get(&orb->kref);
391
363 fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, 392 fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST,
364 node_id, generation, device->max_speed, offset, 393 node_id, generation, device->max_speed, offset,
365 &orb->pointer, sizeof(orb->pointer), 394 &orb->pointer, sizeof(orb->pointer),
@@ -416,6 +445,7 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
416 if (orb == NULL) 445 if (orb == NULL)
417 return -ENOMEM; 446 return -ENOMEM;
418 447
448 kref_init(&orb->base.kref);
419 orb->response_bus = 449 orb->response_bus =
420 dma_map_single(device->card->device, &orb->response, 450 dma_map_single(device->card->device, &orb->response,
421 sizeof(orb->response), DMA_FROM_DEVICE); 451 sizeof(orb->response), DMA_FROM_DEVICE);
@@ -490,7 +520,7 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
490 if (response) 520 if (response)
491 fw_memcpy_from_be32(response, 521 fw_memcpy_from_be32(response,
492 orb->response, sizeof(orb->response)); 522 orb->response, sizeof(orb->response));
493 kfree(orb); 523 kref_put(&orb->base.kref, free_orb);
494 524
495 return retval; 525 return retval;
496} 526}
@@ -886,7 +916,6 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
886 916
887 orb->cmd->result = result; 917 orb->cmd->result = result;
888 orb->done(orb->cmd); 918 orb->done(orb->cmd);
889 kfree(orb);
890} 919}
891 920
892static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) 921static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
@@ -1005,6 +1034,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
1005 1034
1006 /* Initialize rcode to something not RCODE_COMPLETE. */ 1035 /* Initialize rcode to something not RCODE_COMPLETE. */
1007 orb->base.rcode = -1; 1036 orb->base.rcode = -1;
1037 kref_init(&orb->base.kref);
1008 1038
1009 orb->unit = unit; 1039 orb->unit = unit;
1010 orb->done = done; 1040 orb->done = done;
@@ -1051,10 +1081,11 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
1051 sbp2_send_orb(&orb->base, unit, sd->node_id, sd->generation, 1081 sbp2_send_orb(&orb->base, unit, sd->node_id, sd->generation,
1052 sd->command_block_agent_address + SBP2_ORB_POINTER); 1082 sd->command_block_agent_address + SBP2_ORB_POINTER);
1053 1083
1084 kref_put(&orb->base.kref, free_orb);
1054 return 0; 1085 return 0;
1055 1086
1056 fail_mapping: 1087 fail_mapping:
1057 kfree(orb); 1088 kref_put(&orb->base.kref, free_orb);
1058 fail_alloc: 1089 fail_alloc:
1059 return SCSI_MLQUEUE_HOST_BUSY; 1090 return SCSI_MLQUEUE_HOST_BUSY;
1060} 1091}
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 47dbe8f17e82..a81ba8fca0db 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -513,9 +513,9 @@ static int sbp2util_create_command_orb_pool(struct sbp2_lu *lu)
513 return 0; 513 return 0;
514} 514}
515 515
516static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu) 516static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu,
517 struct hpsb_host *host)
517{ 518{
518 struct hpsb_host *host = lu->hi->host;
519 struct list_head *lh, *next; 519 struct list_head *lh, *next;
520 struct sbp2_command_info *cmd; 520 struct sbp2_command_info *cmd;
521 unsigned long flags; 521 unsigned long flags;
@@ -922,15 +922,16 @@ static void sbp2_remove_device(struct sbp2_lu *lu)
922 922
923 if (!lu) 923 if (!lu)
924 return; 924 return;
925
926 hi = lu->hi; 925 hi = lu->hi;
926 if (!hi)
927 goto no_hi;
927 928
928 if (lu->shost) { 929 if (lu->shost) {
929 scsi_remove_host(lu->shost); 930 scsi_remove_host(lu->shost);
930 scsi_host_put(lu->shost); 931 scsi_host_put(lu->shost);
931 } 932 }
932 flush_scheduled_work(); 933 flush_scheduled_work();
933 sbp2util_remove_command_orb_pool(lu); 934 sbp2util_remove_command_orb_pool(lu, hi->host);
934 935
935 list_del(&lu->lu_list); 936 list_del(&lu->lu_list);
936 937
@@ -971,9 +972,8 @@ static void sbp2_remove_device(struct sbp2_lu *lu)
971 972
972 lu->ud->device.driver_data = NULL; 973 lu->ud->device.driver_data = NULL;
973 974
974 if (hi) 975 module_put(hi->host->driver->owner);
975 module_put(hi->host->driver->owner); 976no_hi:
976
977 kfree(lu); 977 kfree(lu);
978} 978}
979 979