diff options
Diffstat (limited to 'drivers/scsi/fnic/fnic_scsi.c')
-rw-r--r-- | drivers/scsi/fnic/fnic_scsi.c | 53 |
1 files changed, 9 insertions, 44 deletions
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index be89ce96df46..9761b2c9db48 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -2168,39 +2168,6 @@ clean_pending_aborts_end: } /* - * fnic_scsi_host_start_tag - * Allocates tagid from host's tag list - **/ -static inline int -fnic_scsi_host_start_tag(struct fnic *fnic, struct scsi_cmnd *sc) -{ - struct request *rq = scsi_cmd_to_rq(sc); - struct request_queue *q = rq->q; - struct request *dummy; - - dummy = blk_mq_alloc_request(q, REQ_OP_WRITE, BLK_MQ_REQ_NOWAIT); - if (IS_ERR(dummy)) - return SCSI_NO_TAG; - - rq->tag = dummy->tag; - sc->host_scribble = (unsigned char *)dummy; - - return dummy->tag; -} - -/* - * fnic_scsi_host_end_tag - * frees tag allocated by fnic_scsi_host_start_tag. - **/ -static inline void -fnic_scsi_host_end_tag(struct fnic *fnic, struct scsi_cmnd *sc) -{ - struct request *dummy = (struct request *)sc->host_scribble; - - blk_mq_free_request(dummy); -} - -/* * SCSI Eh thread issues a Lun Reset when one or more commands on a LUN * fail to get aborted. It calls driver's eh_device_reset with a SCSI command * on the LUN. @@ -2222,7 +2189,6 @@ int fnic_device_reset(struct scsi_cmnd *sc) struct reset_stats *reset_stats; int tag = rq->tag; DECLARE_COMPLETION_ONSTACK(tm_done); - int tag_gen_flag = 0; /*to track tags allocated by fnic driver*/ bool new_sc = 0; /* Wait for rport to unblock */ @@ -2252,17 +2218,17 @@ int fnic_device_reset(struct scsi_cmnd *sc) } fnic_priv(sc)->flags = FNIC_DEVICE_RESET; - /* Allocate tag if not present */ if (unlikely(tag < 0)) { /* - * Really should fix the midlayer to pass in a proper - * request for ioctls... + * For device reset issued through sg3utils, we let + * only one LUN_RESET to go through and use a special + * tag equal to max_tag_id so that we don't have to allocate + * or free it. It won't interact with tags + * allocated by mid layer. */ - tag = fnic_scsi_host_start_tag(fnic, sc); - if (unlikely(tag == SCSI_NO_TAG)) - goto fnic_device_reset_end; - tag_gen_flag = 1; + mutex_lock(&fnic->sgreset_mutex); + tag = fnic->fnic_max_tag_id; new_sc = 1; } io_lock = fnic_io_lock_hash(fnic, sc); @@ -2434,9 +2400,8 @@ fnic_device_reset_end: (u64)sc->cmnd[4] << 8 | sc->cmnd[5]), fnic_flags_and_state(sc)); - /* free tag if it is allocated */ - if (unlikely(tag_gen_flag)) - fnic_scsi_host_end_tag(fnic, sc); + if (new_sc) + mutex_unlock(&fnic->sgreset_mutex); FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "Returning from device reset %s\n", |