aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_fc.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/scsi/scsi_transport_fc.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/scsi/scsi_transport_fc.c')
-rw-r--r--drivers/scsi/scsi_transport_fc.c176
1 files changed, 125 insertions, 51 deletions
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index c6f70dae9b2e..6cfffc88022a 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -27,6 +27,8 @@
27 */ 27 */
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/slab.h>
31#include <linux/delay.h>
30#include <scsi/scsi_device.h> 32#include <scsi/scsi_device.h>
31#include <scsi/scsi_host.h> 33#include <scsi/scsi_host.h>
32#include <scsi/scsi_transport.h> 34#include <scsi/scsi_transport.h>
@@ -474,7 +476,8 @@ MODULE_PARM_DESC(dev_loss_tmo,
474 "Maximum number of seconds that the FC transport should" 476 "Maximum number of seconds that the FC transport should"
475 " insulate the loss of a remote port. Once this value is" 477 " insulate the loss of a remote port. Once this value is"
476 " exceeded, the scsi target is removed. Value should be" 478 " exceeded, the scsi target is removed. Value should be"
477 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT."); 479 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT if"
480 " fast_io_fail_tmo is not set.");
478 481
479/* 482/*
480 * Netlink Infrastructure 483 * Netlink Infrastructure
@@ -648,11 +651,22 @@ static __init int fc_transport_init(void)
648 return error; 651 return error;
649 error = transport_class_register(&fc_vport_class); 652 error = transport_class_register(&fc_vport_class);
650 if (error) 653 if (error)
651 return error; 654 goto unreg_host_class;
652 error = transport_class_register(&fc_rport_class); 655 error = transport_class_register(&fc_rport_class);
653 if (error) 656 if (error)
654 return error; 657 goto unreg_vport_class;
655 return transport_class_register(&fc_transport_class); 658 error = transport_class_register(&fc_transport_class);
659 if (error)
660 goto unreg_rport_class;
661 return 0;
662
663unreg_rport_class:
664 transport_class_unregister(&fc_rport_class);
665unreg_vport_class:
666 transport_class_unregister(&fc_vport_class);
667unreg_host_class:
668 transport_class_unregister(&fc_host_class);
669 return error;
656} 670}
657 671
658static void __exit fc_transport_exit(void) 672static void __exit fc_transport_exit(void)
@@ -830,9 +844,17 @@ store_fc_rport_dev_loss_tmo(struct device *dev, struct device_attribute *attr,
830 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) 844 (rport->port_state == FC_PORTSTATE_NOTPRESENT))
831 return -EBUSY; 845 return -EBUSY;
832 val = simple_strtoul(buf, &cp, 0); 846 val = simple_strtoul(buf, &cp, 0);
833 if ((*cp && (*cp != '\n')) || 847 if ((*cp && (*cp != '\n')) || (val < 0))
834 (val < 0) || (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT))
835 return -EINVAL; 848 return -EINVAL;
849
850 /*
851 * If fast_io_fail is off we have to cap
852 * dev_loss_tmo at SCSI_DEVICE_BLOCK_MAX_TIMEOUT
853 */
854 if (rport->fast_io_fail_tmo == -1 &&
855 val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)
856 return -EINVAL;
857
836 i->f->set_rport_dev_loss_tmo(rport, val); 858 i->f->set_rport_dev_loss_tmo(rport, val);
837 return count; 859 return count;
838} 860}
@@ -913,9 +935,16 @@ store_fc_rport_fast_io_fail_tmo(struct device *dev,
913 rport->fast_io_fail_tmo = -1; 935 rport->fast_io_fail_tmo = -1;
914 else { 936 else {
915 val = simple_strtoul(buf, &cp, 0); 937 val = simple_strtoul(buf, &cp, 0);
916 if ((*cp && (*cp != '\n')) || 938 if ((*cp && (*cp != '\n')) || (val < 0))
917 (val < 0) || (val >= rport->dev_loss_tmo))
918 return -EINVAL; 939 return -EINVAL;
940 /*
941 * Cap fast_io_fail by dev_loss_tmo or
942 * SCSI_DEVICE_BLOCK_MAX_TIMEOUT.
943 */
944 if ((val >= rport->dev_loss_tmo) ||
945 (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT))
946 return -EINVAL;
947
919 rport->fast_io_fail_tmo = val; 948 rport->fast_io_fail_tmo = val;
920 } 949 }
921 return count; 950 return count;
@@ -1204,6 +1233,15 @@ store_fc_vport_delete(struct device *dev, struct device_attribute *attr,
1204{ 1233{
1205 struct fc_vport *vport = transport_class_to_vport(dev); 1234 struct fc_vport *vport = transport_class_to_vport(dev);
1206 struct Scsi_Host *shost = vport_to_shost(vport); 1235 struct Scsi_Host *shost = vport_to_shost(vport);
1236 unsigned long flags;
1237
1238 spin_lock_irqsave(shost->host_lock, flags);
1239 if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) {
1240 spin_unlock_irqrestore(shost->host_lock, flags);
1241 return -EBUSY;
1242 }
1243 vport->flags |= FC_VPORT_DELETING;
1244 spin_unlock_irqrestore(shost->host_lock, flags);
1207 1245
1208 fc_queue_work(shost, &vport->vport_delete_work); 1246 fc_queue_work(shost, &vport->vport_delete_work);
1209 return count; 1247 return count;
@@ -1793,6 +1831,9 @@ store_fc_host_vport_delete(struct device *dev, struct device_attribute *attr,
1793 list_for_each_entry(vport, &fc_host->vports, peers) { 1831 list_for_each_entry(vport, &fc_host->vports, peers) {
1794 if ((vport->channel == 0) && 1832 if ((vport->channel == 0) &&
1795 (vport->port_name == wwpn) && (vport->node_name == wwnn)) { 1833 (vport->port_name == wwpn) && (vport->node_name == wwnn)) {
1834 if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))
1835 break;
1836 vport->flags |= FC_VPORT_DELETING;
1796 match = 1; 1837 match = 1;
1797 break; 1838 break;
1798 } 1839 }
@@ -2384,6 +2425,7 @@ fc_rport_final_delete(struct work_struct *work)
2384 struct Scsi_Host *shost = rport_to_shost(rport); 2425 struct Scsi_Host *shost = rport_to_shost(rport);
2385 struct fc_internal *i = to_fc_internal(shost->transportt); 2426 struct fc_internal *i = to_fc_internal(shost->transportt);
2386 unsigned long flags; 2427 unsigned long flags;
2428 int do_callback = 0;
2387 2429
2388 /* 2430 /*
2389 * if a scan is pending, flush the SCSI Host work_q so that 2431 * if a scan is pending, flush the SCSI Host work_q so that
@@ -2422,8 +2464,15 @@ fc_rport_final_delete(struct work_struct *work)
2422 * Avoid this call if we already called it when we preserved the 2464 * Avoid this call if we already called it when we preserved the
2423 * rport for the binding. 2465 * rport for the binding.
2424 */ 2466 */
2467 spin_lock_irqsave(shost->host_lock, flags);
2425 if (!(rport->flags & FC_RPORT_DEVLOSS_CALLBK_DONE) && 2468 if (!(rport->flags & FC_RPORT_DEVLOSS_CALLBK_DONE) &&
2426 (i->f->dev_loss_tmo_callbk)) 2469 (i->f->dev_loss_tmo_callbk)) {
2470 rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE;
2471 do_callback = 1;
2472 }
2473 spin_unlock_irqrestore(shost->host_lock, flags);
2474
2475 if (do_callback)
2427 i->f->dev_loss_tmo_callbk(rport); 2476 i->f->dev_loss_tmo_callbk(rport);
2428 2477
2429 fc_bsg_remove(rport->rqst_q); 2478 fc_bsg_remove(rport->rqst_q);
@@ -2970,6 +3019,7 @@ fc_timeout_deleted_rport(struct work_struct *work)
2970 struct fc_internal *i = to_fc_internal(shost->transportt); 3019 struct fc_internal *i = to_fc_internal(shost->transportt);
2971 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 3020 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
2972 unsigned long flags; 3021 unsigned long flags;
3022 int do_callback = 0;
2973 3023
2974 spin_lock_irqsave(shost->host_lock, flags); 3024 spin_lock_irqsave(shost->host_lock, flags);
2975 3025
@@ -3035,7 +3085,6 @@ fc_timeout_deleted_rport(struct work_struct *work)
3035 rport->roles = FC_PORT_ROLE_UNKNOWN; 3085 rport->roles = FC_PORT_ROLE_UNKNOWN;
3036 rport->port_state = FC_PORTSTATE_NOTPRESENT; 3086 rport->port_state = FC_PORTSTATE_NOTPRESENT;
3037 rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT; 3087 rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;
3038 rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE;
3039 3088
3040 /* 3089 /*
3041 * Pre-emptively kill I/O rather than waiting for the work queue 3090 * Pre-emptively kill I/O rather than waiting for the work queue
@@ -3045,32 +3094,40 @@ fc_timeout_deleted_rport(struct work_struct *work)
3045 spin_unlock_irqrestore(shost->host_lock, flags); 3094 spin_unlock_irqrestore(shost->host_lock, flags);
3046 fc_terminate_rport_io(rport); 3095 fc_terminate_rport_io(rport);
3047 3096
3048 BUG_ON(rport->port_state != FC_PORTSTATE_NOTPRESENT); 3097 spin_lock_irqsave(shost->host_lock, flags);
3049 3098
3050 /* remove the identifiers that aren't used in the consisting binding */ 3099 if (rport->port_state == FC_PORTSTATE_NOTPRESENT) { /* still missing */
3051 switch (fc_host->tgtid_bind_type) { 3100
3052 case FC_TGTID_BIND_BY_WWPN: 3101 /* remove the identifiers that aren't used in the consisting binding */
3053 rport->node_name = -1; 3102 switch (fc_host->tgtid_bind_type) {
3054 rport->port_id = -1; 3103 case FC_TGTID_BIND_BY_WWPN:
3055 break; 3104 rport->node_name = -1;
3056 case FC_TGTID_BIND_BY_WWNN: 3105 rport->port_id = -1;
3057 rport->port_name = -1; 3106 break;
3058 rport->port_id = -1; 3107 case FC_TGTID_BIND_BY_WWNN:
3059 break; 3108 rport->port_name = -1;
3060 case FC_TGTID_BIND_BY_ID: 3109 rport->port_id = -1;
3061 rport->node_name = -1; 3110 break;
3062 rport->port_name = -1; 3111 case FC_TGTID_BIND_BY_ID:
3063 break; 3112 rport->node_name = -1;
3064 case FC_TGTID_BIND_NONE: /* to keep compiler happy */ 3113 rport->port_name = -1;
3065 break; 3114 break;
3115 case FC_TGTID_BIND_NONE: /* to keep compiler happy */
3116 break;
3117 }
3118
3119 /*
3120 * As this only occurs if the remote port (scsi target)
3121 * went away and didn't come back - we'll remove
3122 * all attached scsi devices.
3123 */
3124 rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE;
3125 fc_queue_work(shost, &rport->stgt_delete_work);
3126
3127 do_callback = 1;
3066 } 3128 }
3067 3129
3068 /* 3130 spin_unlock_irqrestore(shost->host_lock, flags);
3069 * As this only occurs if the remote port (scsi target)
3070 * went away and didn't come back - we'll remove
3071 * all attached scsi devices.
3072 */
3073 fc_queue_work(shost, &rport->stgt_delete_work);
3074 3131
3075 /* 3132 /*
3076 * Notify the driver that the rport is now dead. The LLDD will 3133 * Notify the driver that the rport is now dead. The LLDD will
@@ -3078,7 +3135,7 @@ fc_timeout_deleted_rport(struct work_struct *work)
3078 * 3135 *
3079 * Note: we set the CALLBK_DONE flag above to correspond 3136 * Note: we set the CALLBK_DONE flag above to correspond
3080 */ 3137 */
3081 if (i->f->dev_loss_tmo_callbk) 3138 if (do_callback && i->f->dev_loss_tmo_callbk)
3082 i->f->dev_loss_tmo_callbk(rport); 3139 i->f->dev_loss_tmo_callbk(rport);
3083} 3140}
3084 3141
@@ -3128,6 +3185,31 @@ fc_scsi_scan_rport(struct work_struct *work)
3128 spin_unlock_irqrestore(shost->host_lock, flags); 3185 spin_unlock_irqrestore(shost->host_lock, flags);
3129} 3186}
3130 3187
3188/**
3189 * fc_block_scsi_eh - Block SCSI eh thread for blocked fc_rport
3190 * @cmnd: SCSI command that scsi_eh is trying to recover
3191 *
3192 * This routine can be called from a FC LLD scsi_eh callback. It
3193 * blocks the scsi_eh thread until the fc_rport leaves the
3194 * FC_PORTSTATE_BLOCKED. This is necessary to avoid the scsi_eh
3195 * failing recovery actions for blocked rports which would lead to
3196 * offlined SCSI devices.
3197 */
3198void fc_block_scsi_eh(struct scsi_cmnd *cmnd)
3199{
3200 struct Scsi_Host *shost = cmnd->device->host;
3201 struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
3202 unsigned long flags;
3203
3204 spin_lock_irqsave(shost->host_lock, flags);
3205 while (rport->port_state == FC_PORTSTATE_BLOCKED) {
3206 spin_unlock_irqrestore(shost->host_lock, flags);
3207 msleep(1000);
3208 spin_lock_irqsave(shost->host_lock, flags);
3209 }
3210 spin_unlock_irqrestore(shost->host_lock, flags);
3211}
3212EXPORT_SYMBOL(fc_block_scsi_eh);
3131 3213
3132/** 3214/**
3133 * fc_vport_setup - allocates and creates a FC virtual port. 3215 * fc_vport_setup - allocates and creates a FC virtual port.
@@ -3301,18 +3383,6 @@ fc_vport_terminate(struct fc_vport *vport)
3301 unsigned long flags; 3383 unsigned long flags;
3302 int stat; 3384 int stat;
3303 3385
3304 spin_lock_irqsave(shost->host_lock, flags);
3305 if (vport->flags & FC_VPORT_CREATING) {
3306 spin_unlock_irqrestore(shost->host_lock, flags);
3307 return -EBUSY;
3308 }
3309 if (vport->flags & (FC_VPORT_DEL)) {
3310 spin_unlock_irqrestore(shost->host_lock, flags);
3311 return -EALREADY;
3312 }
3313 vport->flags |= FC_VPORT_DELETING;
3314 spin_unlock_irqrestore(shost->host_lock, flags);
3315
3316 if (i->f->vport_delete) 3386 if (i->f->vport_delete)
3317 stat = i->f->vport_delete(vport); 3387 stat = i->f->vport_delete(vport);
3318 else 3388 else
@@ -3474,7 +3544,10 @@ fc_bsg_job_timeout(struct request *req)
3474 if (!done && i->f->bsg_timeout) { 3544 if (!done && i->f->bsg_timeout) {
3475 /* call LLDD to abort the i/o as it has timed out */ 3545 /* call LLDD to abort the i/o as it has timed out */
3476 err = i->f->bsg_timeout(job); 3546 err = i->f->bsg_timeout(job);
3477 if (err) 3547 if (err == -EAGAIN) {
3548 job->ref_cnt--;
3549 return BLK_EH_RESET_TIMER;
3550 } else if (err)
3478 printk(KERN_ERR "ERROR: FC BSG request timeout - LLD " 3551 printk(KERN_ERR "ERROR: FC BSG request timeout - LLD "
3479 "abort failed with status %d\n", err); 3552 "abort failed with status %d\n", err);
3480 } 3553 }
@@ -3769,8 +3842,9 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
3769 return; 3842 return;
3770 3843
3771 while (!blk_queue_plugged(q)) { 3844 while (!blk_queue_plugged(q)) {
3772 if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED)) 3845 if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED) &&
3773 break; 3846 !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT))
3847 break;
3774 3848
3775 req = blk_fetch_request(q); 3849 req = blk_fetch_request(q);
3776 if (!req) 3850 if (!req)
@@ -3779,7 +3853,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
3779 if (rport && (rport->port_state != FC_PORTSTATE_ONLINE)) { 3853 if (rport && (rport->port_state != FC_PORTSTATE_ONLINE)) {
3780 req->errors = -ENXIO; 3854 req->errors = -ENXIO;
3781 spin_unlock_irq(q->queue_lock); 3855 spin_unlock_irq(q->queue_lock);
3782 blk_end_request(req, -ENXIO, blk_rq_bytes(req)); 3856 blk_end_request_all(req, -ENXIO);
3783 spin_lock_irq(q->queue_lock); 3857 spin_lock_irq(q->queue_lock);
3784 continue; 3858 continue;
3785 } 3859 }
@@ -3789,7 +3863,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
3789 ret = fc_req_to_bsgjob(shost, rport, req); 3863 ret = fc_req_to_bsgjob(shost, rport, req);
3790 if (ret) { 3864 if (ret) {
3791 req->errors = ret; 3865 req->errors = ret;
3792 blk_end_request(req, ret, blk_rq_bytes(req)); 3866 blk_end_request_all(req, ret);
3793 spin_lock_irq(q->queue_lock); 3867 spin_lock_irq(q->queue_lock);
3794 continue; 3868 continue;
3795 } 3869 }