aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_fc.c
diff options
context:
space:
mode:
authorGiridhar Malavali <giridhar.malavali@qlogic.com>2009-06-19 19:26:53 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-21 12:12:56 -0400
commitb5c6f77680f4ff1775838fcedfdd6026bf5ad777 (patch)
tree6ce01ea3b1bafe595cc785349b5676542a0e7f9a /drivers/scsi/scsi_transport_fc.c
parent75be63bcf73ebdd1fdc1d49f6bf2d1326a1ba7de (diff)
fc_transport: The softirq_done function registration for BSG request
Registered the softirq_done function, since this is requried iby an request using block level request timeout functionality. This function will be called by the block layer as part of time out clean process to release the BSG request. Moved some of the BSG request completion activities to softirq_done routine to take care of both normal and timout completions. Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Acked-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/scsi_transport_fc.c')
-rw-r--r--drivers/scsi/scsi_transport_fc.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 3f64d93b6c8b..453d9e658eb6 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3397,7 +3397,6 @@ fc_destroy_bsgjob(struct fc_bsg_job *job)
3397 kfree(job); 3397 kfree(job);
3398} 3398}
3399 3399
3400
3401/** 3400/**
3402 * fc_bsg_jobdone - completion routine for bsg requests that the LLD has 3401 * fc_bsg_jobdone - completion routine for bsg requests that the LLD has
3403 * completed 3402 * completed
@@ -3408,15 +3407,10 @@ fc_bsg_jobdone(struct fc_bsg_job *job)
3408{ 3407{
3409 struct request *req = job->req; 3408 struct request *req = job->req;
3410 struct request *rsp = req->next_rq; 3409 struct request *rsp = req->next_rq;
3411 unsigned long flags;
3412 int err; 3410 int err;
3413 3411
3414 spin_lock_irqsave(&job->job_lock, flags);
3415 job->state_flags |= FC_RQST_STATE_DONE;
3416 job->ref_cnt--;
3417 spin_unlock_irqrestore(&job->job_lock, flags);
3418
3419 err = job->req->errors = job->reply->result; 3412 err = job->req->errors = job->reply->result;
3413
3420 if (err < 0) 3414 if (err < 0)
3421 /* we're only returning the result field in the reply */ 3415 /* we're only returning the result field in the reply */
3422 job->req->sense_len = sizeof(uint32_t); 3416 job->req->sense_len = sizeof(uint32_t);
@@ -3433,13 +3427,27 @@ fc_bsg_jobdone(struct fc_bsg_job *job)
3433 rsp->resid_len -= min(job->reply->reply_payload_rcv_len, 3427 rsp->resid_len -= min(job->reply->reply_payload_rcv_len,
3434 rsp->resid_len); 3428 rsp->resid_len);
3435 } 3429 }
3430 blk_complete_request(req);
3431}
3432
3433/**
3434 * fc_bsg_softirq_done - softirq done routine for destroying the bsg requests
3435 * @req: BSG request that holds the job to be destroyed
3436 */
3437static void fc_bsg_softirq_done(struct request *rq)
3438{
3439 struct fc_bsg_job *job = rq->special;
3440 unsigned long flags;
3436 3441
3437 blk_end_request_all(req, err); 3442 spin_lock_irqsave(&job->job_lock, flags);
3443 job->state_flags |= FC_RQST_STATE_DONE;
3444 job->ref_cnt--;
3445 spin_unlock_irqrestore(&job->job_lock, flags);
3438 3446
3447 blk_end_request_all(rq, rq->errors);
3439 fc_destroy_bsgjob(job); 3448 fc_destroy_bsgjob(job);
3440} 3449}
3441 3450
3442
3443/** 3451/**
3444 * fc_bsg_job_timeout - handler for when a bsg request timesout 3452 * fc_bsg_job_timeout - handler for when a bsg request timesout
3445 * @req: request that timed out 3453 * @req: request that timed out
@@ -3471,19 +3479,10 @@ fc_bsg_job_timeout(struct request *req)
3471 "abort failed with status %d\n", err); 3479 "abort failed with status %d\n", err);
3472 } 3480 }
3473 3481
3474 if (!done) {
3475 spin_lock_irqsave(&job->job_lock, flags);
3476 job->ref_cnt--;
3477 spin_unlock_irqrestore(&job->job_lock, flags);
3478 fc_destroy_bsgjob(job);
3479 }
3480
3481 /* the blk_end_sync_io() doesn't check the error */ 3482 /* the blk_end_sync_io() doesn't check the error */
3482 return BLK_EH_HANDLED; 3483 return BLK_EH_HANDLED;
3483} 3484}
3484 3485
3485
3486
3487static int 3486static int
3488fc_bsg_map_buffer(struct fc_bsg_buffer *buf, struct request *req) 3487fc_bsg_map_buffer(struct fc_bsg_buffer *buf, struct request *req)
3489{ 3488{
@@ -3879,6 +3878,7 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host)
3879 3878
3880 q->queuedata = shost; 3879 q->queuedata = shost;
3881 queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q); 3880 queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
3881 blk_queue_softirq_done(q, fc_bsg_softirq_done);
3882 blk_queue_rq_timed_out(q, fc_bsg_job_timeout); 3882 blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
3883 blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT); 3883 blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT);
3884 3884
@@ -3924,6 +3924,7 @@ fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport)
3924 3924
3925 q->queuedata = rport; 3925 q->queuedata = rport;
3926 queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q); 3926 queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
3927 blk_queue_softirq_done(q, fc_bsg_softirq_done);
3927 blk_queue_rq_timed_out(q, fc_bsg_job_timeout); 3928 blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
3928 blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT); 3929 blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);
3929 3930