}
 }
 
+static void
+qla2x00_async_done(struct srb *sp, int res)
+{
+       if (del_timer(&sp->u.iocb_cmd.timer)) {
+               /*
+                * Successfully cancelled the timeout handler
+                * ref: TMR
+                */
+               if (kref_put(&sp->cmd_kref, qla2x00_sp_release))
+                       return;
+       }
+       sp->async_done(sp, res);
+}
+
 void
 qla2x00_sp_release(struct kref *kref)
 {
                     void (*done)(struct srb *sp, int res))
 {
        timer_setup(&sp->u.iocb_cmd.timer, qla2x00_sp_timeout, 0);
-       sp->done = done;
+       sp->done = qla2x00_async_done;
+       sp->async_done = done;
        sp->free = qla2x00_sp_free;
        sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
        sp->u.iocb_cmd.timer.expires = jiffies + tmo * HZ;