diff options
| author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2007-11-06 19:12:51 -0500 |
|---|---|---|
| committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2008-01-30 16:22:21 -0500 |
| commit | 285838eb22ef0db77b464da70b7352cdbfffc939 (patch) | |
| tree | c346c7bbc284622bbf76e9f30f05a65ad8859067 | |
| parent | 85c5798b09e9248f29edbc42f10b99842661e85c (diff) | |
firewire: fw-sbp2: refactor workq and kref handling
This somewhat reduces the size of firewire-sbp2.ko.
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
| -rw-r--r-- | drivers/firewire/fw-sbp2.c | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index c2169d215bf7..2108cd92451b 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c | |||
| @@ -628,6 +628,21 @@ static void sbp2_release_target(struct kref *kref) | |||
| 628 | 628 | ||
| 629 | static struct workqueue_struct *sbp2_wq; | 629 | static struct workqueue_struct *sbp2_wq; |
| 630 | 630 | ||
| 631 | /* | ||
| 632 | * Always get the target's kref when scheduling work on one its units. | ||
| 633 | * Each workqueue job is responsible to call sbp2_target_put() upon return. | ||
| 634 | */ | ||
| 635 | static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay) | ||
| 636 | { | ||
| 637 | if (queue_delayed_work(sbp2_wq, &lu->work, delay)) | ||
| 638 | kref_get(&lu->tgt->kref); | ||
| 639 | } | ||
| 640 | |||
| 641 | static void sbp2_target_put(struct sbp2_target *tgt) | ||
| 642 | { | ||
| 643 | kref_put(&tgt->kref, sbp2_release_target); | ||
| 644 | } | ||
| 645 | |||
| 631 | static void sbp2_reconnect(struct work_struct *work); | 646 | static void sbp2_reconnect(struct work_struct *work); |
| 632 | 647 | ||
| 633 | static void sbp2_login(struct work_struct *work) | 648 | static void sbp2_login(struct work_struct *work) |
| @@ -649,16 +664,12 @@ static void sbp2_login(struct work_struct *work) | |||
| 649 | 664 | ||
| 650 | if (sbp2_send_management_orb(lu, node_id, generation, | 665 | if (sbp2_send_management_orb(lu, node_id, generation, |
| 651 | SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) { | 666 | SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) { |
| 652 | if (lu->retries++ < 5) { | 667 | if (lu->retries++ < 5) |
| 653 | if (queue_delayed_work(sbp2_wq, &lu->work, | 668 | sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); |
| 654 | DIV_ROUND_UP(HZ, 5))) | 669 | else |
| 655 | kref_get(&lu->tgt->kref); | ||
| 656 | } else { | ||
| 657 | fw_error("failed to login to %s LUN %04x\n", | 670 | fw_error("failed to login to %s LUN %04x\n", |
| 658 | unit->device.bus_id, lu->lun); | 671 | unit->device.bus_id, lu->lun); |
| 659 | } | 672 | goto out; |
| 660 | kref_put(&lu->tgt->kref, sbp2_release_target); | ||
| 661 | return; | ||
| 662 | } | 673 | } |
| 663 | 674 | ||
| 664 | lu->generation = generation; | 675 | lu->generation = generation; |
| @@ -700,7 +711,8 @@ static void sbp2_login(struct work_struct *work) | |||
| 700 | lu->sdev = sdev; | 711 | lu->sdev = sdev; |
| 701 | scsi_device_put(sdev); | 712 | scsi_device_put(sdev); |
| 702 | } | 713 | } |
| 703 | kref_put(&lu->tgt->kref, sbp2_release_target); | 714 | out: |
| 715 | sbp2_target_put(lu->tgt); | ||
| 704 | } | 716 | } |
| 705 | 717 | ||
| 706 | static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) | 718 | static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) |
| @@ -865,18 +877,13 @@ static int sbp2_probe(struct device *dev) | |||
| 865 | 877 | ||
| 866 | get_device(&unit->device); | 878 | get_device(&unit->device); |
| 867 | 879 | ||
| 868 | /* | 880 | /* Do the login in a workqueue so we can easily reschedule retries. */ |
| 869 | * We schedule work to do the login so we can easily | ||
| 870 | * reschedule retries. Always get the ref before scheduling | ||
| 871 | * work. | ||
| 872 | */ | ||
| 873 | list_for_each_entry(lu, &tgt->lu_list, link) | 881 | list_for_each_entry(lu, &tgt->lu_list, link) |
| 874 | if (queue_delayed_work(sbp2_wq, &lu->work, 0)) | 882 | sbp2_queue_work(lu, 0); |
| 875 | kref_get(&tgt->kref); | ||
| 876 | return 0; | 883 | return 0; |
| 877 | 884 | ||
| 878 | fail_tgt_put: | 885 | fail_tgt_put: |
| 879 | kref_put(&tgt->kref, sbp2_release_target); | 886 | sbp2_target_put(tgt); |
| 880 | return -ENOMEM; | 887 | return -ENOMEM; |
| 881 | 888 | ||
| 882 | fail_shost_put: | 889 | fail_shost_put: |
| @@ -889,7 +896,7 @@ static int sbp2_remove(struct device *dev) | |||
| 889 | struct fw_unit *unit = fw_unit(dev); | 896 | struct fw_unit *unit = fw_unit(dev); |
| 890 | struct sbp2_target *tgt = unit->device.driver_data; | 897 | struct sbp2_target *tgt = unit->device.driver_data; |
| 891 | 898 | ||
| 892 | kref_put(&tgt->kref, sbp2_release_target); | 899 | sbp2_target_put(tgt); |
| 893 | return 0; | 900 | return 0; |
| 894 | } | 901 | } |
| 895 | 902 | ||
| @@ -915,10 +922,8 @@ static void sbp2_reconnect(struct work_struct *work) | |||
| 915 | lu->retries = 0; | 922 | lu->retries = 0; |
| 916 | PREPARE_DELAYED_WORK(&lu->work, sbp2_login); | 923 | PREPARE_DELAYED_WORK(&lu->work, sbp2_login); |
| 917 | } | 924 | } |
| 918 | if (queue_delayed_work(sbp2_wq, &lu->work, DIV_ROUND_UP(HZ, 5))) | 925 | sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); |
| 919 | kref_get(&lu->tgt->kref); | 926 | goto out; |
| 920 | kref_put(&lu->tgt->kref, sbp2_release_target); | ||
| 921 | return; | ||
| 922 | } | 927 | } |
| 923 | 928 | ||
| 924 | lu->generation = generation; | 929 | lu->generation = generation; |
| @@ -930,8 +935,8 @@ static void sbp2_reconnect(struct work_struct *work) | |||
| 930 | 935 | ||
| 931 | sbp2_agent_reset(lu); | 936 | sbp2_agent_reset(lu); |
| 932 | sbp2_cancel_orbs(lu); | 937 | sbp2_cancel_orbs(lu); |
| 933 | 938 | out: | |
| 934 | kref_put(&lu->tgt->kref, sbp2_release_target); | 939 | sbp2_target_put(lu->tgt); |
| 935 | } | 940 | } |
| 936 | 941 | ||
| 937 | static void sbp2_update(struct fw_unit *unit) | 942 | static void sbp2_update(struct fw_unit *unit) |
| @@ -947,8 +952,7 @@ static void sbp2_update(struct fw_unit *unit) | |||
| 947 | */ | 952 | */ |
| 948 | list_for_each_entry(lu, &tgt->lu_list, link) { | 953 | list_for_each_entry(lu, &tgt->lu_list, link) { |
| 949 | lu->retries = 0; | 954 | lu->retries = 0; |
| 950 | if (queue_delayed_work(sbp2_wq, &lu->work, 0)) | 955 | sbp2_queue_work(lu, 0); |
| 951 | kref_get(&tgt->kref); | ||
| 952 | } | 956 | } |
| 953 | } | 957 | } |
| 954 | 958 | ||
