Conditional statements are faster than indirect calls. Hence call scsi_done() and reset_done() directly. The changes in this patch are as follows: - Remove the 'done' argument from aha152x_internal_queue(). - Change ptr->scsi_done(ptr) into aha152x_scsi_done(ptr). - Inside aha152x_scsi_done(), check the 'resetting' flag of SCp.phase since aha152x_internal_queue() specifies the 'reset_done' function pointer if and only if the third argument has the value 'resetting'. Signed-off-by: Bart Van Assche <bvanassche@xxxxxxx> --- drivers/scsi/aha152x.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index b13b5c85f3de..f07de9912790 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -905,13 +905,11 @@ static int setup_expected_interrupts(struct Scsi_Host *shpnt) * Queue a command and setup interrupts for a free bus. */ static int aha152x_internal_queue(struct scsi_cmnd *SCpnt, - struct completion *complete, - int phase, void (*done)(struct scsi_cmnd *)) + struct completion *complete, int phase) { struct Scsi_Host *shpnt = SCpnt->device->host; unsigned long flags; - SCpnt->scsi_done = done; SCpnt->SCp.phase = not_issued | phase; SCpnt->SCp.Status = 0x1; /* Ilegal status by SCSI standard */ SCpnt->SCp.Message = 0; @@ -980,7 +978,8 @@ static int aha152x_internal_queue(struct scsi_cmnd *SCpnt, static int aha152x_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) { - return aha152x_internal_queue(SCpnt, NULL, 0, done); + WARN_ON_ONCE(done != scsi_done); + return aha152x_internal_queue(SCpnt, NULL, 0); } static DEF_SCSI_QCMD(aha152x_queue) @@ -998,6 +997,14 @@ static void reset_done(struct scsi_cmnd *SCpnt) } } +static void aha152x_scsi_done(struct scsi_cmnd *SCpnt) +{ + if (SCpnt->SCp.phase & resetting) + reset_done(SCpnt); + else + scsi_done(SCpnt); +} + /* * Abort a command * @@ -1064,7 +1071,7 @@ static int aha152x_device_reset(struct scsi_cmnd * SCpnt) SCpnt->cmd_len = 0; - aha152x_internal_queue(SCpnt, &done, resetting, reset_done); + aha152x_internal_queue(SCpnt, &done, resetting); timeleft = wait_for_completion_timeout(&done, 100*HZ); if (!timeleft) { @@ -1439,12 +1446,12 @@ static void busfree_run(struct Scsi_Host *shpnt) scsi_eh_prep_cmnd(ptr, &sc->ses, NULL, 0, ~0); DO_UNLOCK(flags); - aha152x_internal_queue(ptr, NULL, check_condition, ptr->scsi_done); + aha152x_internal_queue(ptr, NULL, check_condition); DO_LOCK(flags); } } - if(DONE_SC && DONE_SC->scsi_done) { + if (DONE_SC) { struct scsi_cmnd *ptr = DONE_SC; DONE_SC=NULL; @@ -1453,13 +1460,13 @@ static void busfree_run(struct Scsi_Host *shpnt) if (!HOSTDATA(shpnt)->commands) SETPORT(PORTA, 0); /* turn led off */ - if(ptr->scsi_done != reset_done) { + if (!(ptr->SCp.phase & resetting)) { kfree(ptr->host_scribble); ptr->host_scribble=NULL; } DO_UNLOCK(flags); - ptr->scsi_done(ptr); + aha152x_scsi_done(ptr); DO_LOCK(flags); } @@ -2258,7 +2265,7 @@ static void rsti_run(struct Scsi_Host *shpnt) ptr->host_scribble=NULL; set_host_byte(ptr, DID_RESET); - ptr->scsi_done(ptr); + aha152x_scsi_done(ptr); } ptr = next;