aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-sbp2.c
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2007-02-06 14:49:33 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2007-03-09 16:02:52 -0500
commit1d3d52c5367e0ca352aff6d6986533787bcf36d0 (patch)
treee151460d410ba18aeffb2d87d4c7d9ecf04dfe7b /drivers/firewire/fw-sbp2.c
parent730c32f58ba81b3a4fe6d19c7d9e9829dd96d363 (diff)
firewire: fw-sbp2: Do ORB timeout right.
When a management ORB times out, either because the fw_transaction times out or when we don't get the status write, we need to properly cancel the entire operation. 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.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index bb133398feec..c196333e1de9 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -24,6 +24,7 @@
24#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/scatterlist.h> 25#include <linux/scatterlist.h>
26#include <linux/dma-mapping.h> 26#include <linux/dma-mapping.h>
27#include <linux/timer.h>
27 28
28#include <scsi/scsi.h> 29#include <scsi/scsi.h>
29#include <scsi/scsi_cmnd.h> 30#include <scsi/scsi_cmnd.h>
@@ -58,12 +59,16 @@ struct sbp2_device {
58 int address_high; 59 int address_high;
59 int generation; 60 int generation;
60 61
62 /* Timer for flushing ORBs. */
63 struct timer_list orb_timer;
64
61 struct work_struct work; 65 struct work_struct work;
62 struct Scsi_Host *scsi_host; 66 struct Scsi_Host *scsi_host;
63}; 67};
64 68
65#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000 69#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
66#define SBP2_MAX_SECTORS 255 /* Max sectors supported */ 70#define SBP2_MAX_SECTORS 255 /* Max sectors supported */
71#define SBP2_ORB_TIMEOUT 2000 /* Timeout in ms */
67 72
68#define SBP2_ORB_NULL 0x80000000 73#define SBP2_ORB_NULL 0x80000000
69 74
@@ -327,6 +332,9 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit,
327 list_add_tail(&orb->link, &sd->orb_list); 332 list_add_tail(&orb->link, &sd->orb_list);
328 spin_unlock_irqrestore(&device->card->lock, flags); 333 spin_unlock_irqrestore(&device->card->lock, flags);
329 334
335 mod_timer(&sd->orb_timer,
336 jiffies + DIV_ROUND_UP(SBP2_ORB_TIMEOUT * HZ, 1000));
337
330 fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, 338 fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST,
331 node_id, generation, 339 node_id, generation,
332 device->node->max_speed, offset, 340 device->node->max_speed, offset,
@@ -356,6 +364,13 @@ static void sbp2_cancel_orbs(struct fw_unit *unit)
356 } 364 }
357} 365}
358 366
367static void orb_timer_callback(unsigned long data)
368{
369 struct sbp2_device *sd = (struct sbp2_device *)data;
370
371 sbp2_cancel_orbs(sd->unit);
372}
373
359static void 374static void
360complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) 375complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
361{ 376{
@@ -374,7 +389,6 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
374 struct fw_device *device = fw_device(unit->device.parent); 389 struct fw_device *device = fw_device(unit->device.parent);
375 struct sbp2_device *sd = unit->device.driver_data; 390 struct sbp2_device *sd = unit->device.driver_data;
376 struct sbp2_management_orb *orb; 391 struct sbp2_management_orb *orb;
377 unsigned long timeout;
378 int retval = -ENOMEM; 392 int retval = -ENOMEM;
379 393
380 orb = kzalloc(sizeof *orb, GFP_ATOMIC); 394 orb = kzalloc(sizeof *orb, GFP_ATOMIC);
@@ -426,7 +440,7 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
426 sbp2_send_orb(&orb->base, unit, 440 sbp2_send_orb(&orb->base, unit,
427 node_id, generation, sd->management_agent_address); 441 node_id, generation, sd->management_agent_address);
428 442
429 timeout = wait_for_completion_timeout(&orb->done, 10 * HZ); 443 wait_for_completion(&orb->done);
430 444
431 /* FIXME: Handle bus reset race here. */ 445 /* FIXME: Handle bus reset race here. */
432 446
@@ -437,7 +451,7 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
437 goto out; 451 goto out;
438 } 452 }
439 453
440 if (timeout == 0) { 454 if (orb->base.rcode == RCODE_CANCELLED) {
441 fw_error("orb reply timed out, rcode=0x%02x\n", 455 fw_error("orb reply timed out, rcode=0x%02x\n",
442 orb->base.rcode); 456 orb->base.rcode);
443 goto out; 457 goto out;
@@ -516,6 +530,7 @@ static int sbp2_probe(struct device *dev)
516 unit->device.driver_data = sd; 530 unit->device.driver_data = sd;
517 sd->unit = unit; 531 sd->unit = unit;
518 INIT_LIST_HEAD(&sd->orb_list); 532 INIT_LIST_HEAD(&sd->orb_list);
533 setup_timer(&sd->orb_timer, orb_timer_callback, (unsigned long)sd);
519 534
520 sd->address_handler.length = 0x100; 535 sd->address_handler.length = 0x100;
521 sd->address_handler.address_callback = sbp2_status_write; 536 sd->address_handler.address_callback = sbp2_status_write;
@@ -583,6 +598,7 @@ static int sbp2_probe(struct device *dev)
583 if (sbp2_send_management_orb(unit, node_id, generation, 598 if (sbp2_send_management_orb(unit, node_id, generation,
584 SBP2_LOGIN_REQUEST, lun, &response) < 0) { 599 SBP2_LOGIN_REQUEST, lun, &response) < 0) {
585 fw_core_remove_address_handler(&sd->address_handler); 600 fw_core_remove_address_handler(&sd->address_handler);
601 del_timer_sync(&sd->orb_timer);
586 kfree(sd); 602 kfree(sd);
587 return -EBUSY; 603 return -EBUSY;
588 } 604 }
@@ -618,6 +634,7 @@ static int sbp2_probe(struct device *dev)
618 SBP2_LOGOUT_REQUEST, sd->login_id, 634 SBP2_LOGOUT_REQUEST, sd->login_id,
619 NULL); 635 NULL);
620 fw_core_remove_address_handler(&sd->address_handler); 636 fw_core_remove_address_handler(&sd->address_handler);
637 del_timer_sync(&sd->orb_timer);
621 kfree(sd); 638 kfree(sd);
622 return retval; 639 return retval;
623 } 640 }
@@ -634,6 +651,7 @@ static int sbp2_remove(struct device *dev)
634 SBP2_LOGOUT_REQUEST, sd->login_id, NULL); 651 SBP2_LOGOUT_REQUEST, sd->login_id, NULL);
635 652
636 remove_scsi_devices(unit); 653 remove_scsi_devices(unit);
654 del_timer_sync(&sd->orb_timer);
637 655
638 fw_core_remove_address_handler(&sd->address_handler); 656 fw_core_remove_address_handler(&sd->address_handler);
639 kfree(sd); 657 kfree(sd);