diff options
author | Kristian Høgsberg <krh@redhat.com> | 2007-03-07 12:12:47 -0500 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2007-03-09 16:03:10 -0500 |
commit | 2aaad97be6b58ae865f402fcd27d138e7346ff81 (patch) | |
tree | 10a7f3d7adee7aac8e1d0c71ea2f14446665d19c /drivers/firewire/fw-sbp2.c | |
parent | 048961ef90b584d00ec79c75cb7c7b28403f0c87 (diff) |
firewire: Don't time out command orbs, leave that to the scsi stack.
The mod_timer based timing out of orb was a little to agressive and
would time out legit, but long-lived scsi cmds. Besides, the scsi
stack keeps track of this already. Since we're only timing out
management orbs, go back to wait_for_completion_timeout.
Signed-off-by: Kristian Høgsberg <krh@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/fw-sbp2.c')
-rw-r--r-- | drivers/firewire/fw-sbp2.c | 31 |
1 files changed, 11 insertions, 20 deletions
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 07e410b0ae53..2e5479b972fe 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c | |||
@@ -68,9 +68,6 @@ struct sbp2_device { | |||
68 | int address_high; | 68 | int address_high; |
69 | int generation; | 69 | int generation; |
70 | 70 | ||
71 | /* Timer for flushing ORBs. */ | ||
72 | struct timer_list orb_timer; | ||
73 | |||
74 | int retries; | 71 | int retries; |
75 | struct delayed_work work; | 72 | struct delayed_work work; |
76 | struct Scsi_Host *scsi_host; | 73 | struct Scsi_Host *scsi_host; |
@@ -342,9 +339,6 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit, | |||
342 | list_add_tail(&orb->link, &sd->orb_list); | 339 | list_add_tail(&orb->link, &sd->orb_list); |
343 | spin_unlock_irqrestore(&device->card->lock, flags); | 340 | spin_unlock_irqrestore(&device->card->lock, flags); |
344 | 341 | ||
345 | mod_timer(&sd->orb_timer, | ||
346 | jiffies + DIV_ROUND_UP(SBP2_ORB_TIMEOUT * HZ, 1000)); | ||
347 | |||
348 | fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, | 342 | fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, |
349 | node_id, generation, | 343 | node_id, generation, |
350 | device->node->max_speed, offset, | 344 | device->node->max_speed, offset, |
@@ -352,13 +346,14 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit, | |||
352 | complete_transaction, orb); | 346 | complete_transaction, orb); |
353 | } | 347 | } |
354 | 348 | ||
355 | static void sbp2_cancel_orbs(struct fw_unit *unit) | 349 | static int sbp2_cancel_orbs(struct fw_unit *unit) |
356 | { | 350 | { |
357 | struct fw_device *device = fw_device(unit->device.parent); | 351 | struct fw_device *device = fw_device(unit->device.parent); |
358 | struct sbp2_device *sd = unit->device.driver_data; | 352 | struct sbp2_device *sd = unit->device.driver_data; |
359 | struct sbp2_orb *orb, *next; | 353 | struct sbp2_orb *orb, *next; |
360 | struct list_head list; | 354 | struct list_head list; |
361 | unsigned long flags; | 355 | unsigned long flags; |
356 | int retval = -ENOENT; | ||
362 | 357 | ||
363 | INIT_LIST_HEAD(&list); | 358 | INIT_LIST_HEAD(&list); |
364 | spin_lock_irqsave(&device->card->lock, flags); | 359 | spin_lock_irqsave(&device->card->lock, flags); |
@@ -366,19 +361,15 @@ static void sbp2_cancel_orbs(struct fw_unit *unit) | |||
366 | spin_unlock_irqrestore(&device->card->lock, flags); | 361 | spin_unlock_irqrestore(&device->card->lock, flags); |
367 | 362 | ||
368 | list_for_each_entry_safe(orb, next, &list, link) { | 363 | list_for_each_entry_safe(orb, next, &list, link) { |
364 | retval = 0; | ||
369 | if (fw_cancel_transaction(device->card, &orb->t) == 0) | 365 | if (fw_cancel_transaction(device->card, &orb->t) == 0) |
370 | continue; | 366 | continue; |
371 | 367 | ||
372 | orb->rcode = RCODE_CANCELLED; | 368 | orb->rcode = RCODE_CANCELLED; |
373 | orb->callback(orb, NULL); | 369 | orb->callback(orb, NULL); |
374 | } | 370 | } |
375 | } | ||
376 | 371 | ||
377 | static void orb_timer_callback(unsigned long data) | 372 | return retval; |
378 | { | ||
379 | struct sbp2_device *sd = (struct sbp2_device *)data; | ||
380 | |||
381 | sbp2_cancel_orbs(sd->unit); | ||
382 | } | 373 | } |
383 | 374 | ||
384 | static void | 375 | static void |
@@ -447,20 +438,22 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, | |||
447 | 438 | ||
448 | init_completion(&orb->done); | 439 | init_completion(&orb->done); |
449 | orb->base.callback = complete_management_orb; | 440 | orb->base.callback = complete_management_orb; |
441 | |||
450 | sbp2_send_orb(&orb->base, unit, | 442 | sbp2_send_orb(&orb->base, unit, |
451 | node_id, generation, sd->management_agent_address); | 443 | node_id, generation, sd->management_agent_address); |
452 | 444 | ||
453 | wait_for_completion(&orb->done); | 445 | wait_for_completion_timeout(&orb->done, |
446 | msecs_to_jiffies(SBP2_ORB_TIMEOUT)); | ||
454 | 447 | ||
455 | retval = -EIO; | 448 | retval = -EIO; |
456 | if (orb->base.rcode != RCODE_COMPLETE) { | 449 | if (sbp2_cancel_orbs(unit) == 0) { |
457 | fw_error("management write failed, rcode 0x%02x\n", | 450 | fw_error("orb reply timed out, rcode=0x%02x\n", |
458 | orb->base.rcode); | 451 | orb->base.rcode); |
459 | goto out; | 452 | goto out; |
460 | } | 453 | } |
461 | 454 | ||
462 | if (orb->base.rcode == RCODE_CANCELLED) { | 455 | if (orb->base.rcode != RCODE_COMPLETE) { |
463 | fw_error("orb reply timed out, rcode=0x%02x\n", | 456 | fw_error("management write failed, rcode 0x%02x\n", |
464 | orb->base.rcode); | 457 | orb->base.rcode); |
465 | goto out; | 458 | goto out; |
466 | } | 459 | } |
@@ -602,7 +595,6 @@ static int sbp2_probe(struct device *dev) | |||
602 | unit->device.driver_data = sd; | 595 | unit->device.driver_data = sd; |
603 | sd->unit = unit; | 596 | sd->unit = unit; |
604 | INIT_LIST_HEAD(&sd->orb_list); | 597 | INIT_LIST_HEAD(&sd->orb_list); |
605 | setup_timer(&sd->orb_timer, orb_timer_callback, (unsigned long)sd); | ||
606 | 598 | ||
607 | sd->address_handler.length = 0x100; | 599 | sd->address_handler.length = 0x100; |
608 | sd->address_handler.address_callback = sbp2_status_write; | 600 | sd->address_handler.address_callback = sbp2_status_write; |
@@ -675,7 +667,6 @@ static int sbp2_remove(struct device *dev) | |||
675 | SBP2_LOGOUT_REQUEST, sd->login_id, NULL); | 667 | SBP2_LOGOUT_REQUEST, sd->login_id, NULL); |
676 | 668 | ||
677 | remove_scsi_devices(unit); | 669 | remove_scsi_devices(unit); |
678 | del_timer_sync(&sd->orb_timer); | ||
679 | 670 | ||
680 | fw_core_remove_address_handler(&sd->address_handler); | 671 | fw_core_remove_address_handler(&sd->address_handler); |
681 | kfree(sd); | 672 | kfree(sd); |