#define MBX_INTR_WAIT  2
 #define MBX_UPDATE_FLASH_ACTIVE        3
 
-       struct semaphore mbx_cmd_sem;   /* Serialialize mbx access */
        struct semaphore vport_sem;     /* Virtual port synchronization */
-       struct semaphore mbx_intr_sem;  /* Used for completion notification */
+       struct completion mbx_cmd_comp; /* Serialize mbx access */
+       struct completion mbx_intr_comp;  /* Used for completion notification */
 
        uint32_t        mbx_flags;
 #define  MBX_IN_PROGRESS       BIT_0
 
 extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int);
 extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int);
 
-extern int qla2x00_down_timeout(struct semaphore *, unsigned long);
-
 extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
 
 extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
 
        if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
            (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
                set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
-               up(&ha->mbx_intr_sem);
+               complete(&ha->mbx_intr_comp);
        }
 
        return (IRQ_HANDLED);
        if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
            (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
                set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
-               up(&ha->mbx_intr_sem);
+               complete(&ha->mbx_intr_comp);
        }
 
        return (IRQ_HANDLED);
        if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
            (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
                set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
-               up(&ha->mbx_intr_sem);
+               complete(&ha->mbx_intr_comp);
        }
 
        return IRQ_HANDLED;
        if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
            (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
                set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
-               up(&ha->mbx_intr_sem);
+               complete(&ha->mbx_intr_comp);
        }
 
        return IRQ_HANDLED;
 
 
 #include <linux/delay.h>
 
-static void
-qla2x00_mbx_sem_timeout(unsigned long data)
-{
-       struct semaphore        *sem_ptr = (struct semaphore *)data;
-
-       DEBUG11(printk("qla2x00_sem_timeout: entered.\n"));
-
-       if (sem_ptr != NULL) {
-               up(sem_ptr);
-       }
-
-       DEBUG11(printk("qla2x00_mbx_sem_timeout: exiting.\n"));
-}
 
 /*
  * qla2x00_mailbox_command
        int             rval;
        unsigned long    flags = 0;
        device_reg_t __iomem *reg;
-       struct timer_list       tmp_intr_timer;
        uint8_t         abort_active;
        uint8_t         io_lock_on;
        uint16_t        command;
         * non ISP abort time.
         */
        if (!abort_active) {
-               if (qla2x00_down_timeout(&ha->mbx_cmd_sem, mcp->tov * HZ)) {
+               if (!wait_for_completion_timeout(&ha->mbx_cmd_comp,
+                   mcp->tov * HZ)) {
                        /* Timeout occurred. Return error. */
                        DEBUG2_3_11(printk("%s(%ld): cmd access timeout. "
                            "Exiting.\n", __func__, ha->host_no));
        /* Wait for mbx cmd completion until timeout */
 
        if (!abort_active && io_lock_on) {
-               /* sleep on completion semaphore */
-               DEBUG11(printk("%s(%ld): INTERRUPT MODE. Initializing timer.\n",
-                   __func__, ha->host_no));
-
-               init_timer(&tmp_intr_timer);
-               tmp_intr_timer.data = (unsigned long)&ha->mbx_intr_sem;
-               tmp_intr_timer.expires = jiffies + mcp->tov * HZ;
-               tmp_intr_timer.function =
-                   (void (*)(unsigned long))qla2x00_mbx_sem_timeout;
-
-               DEBUG11(printk("%s(%ld): Adding timer.\n", __func__,
-                   ha->host_no));
-               add_timer(&tmp_intr_timer);
-
-               DEBUG11(printk("%s(%ld): going to unlock & sleep. "
-                   "time=0x%lx.\n", __func__, ha->host_no, jiffies));
 
                set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
 
                        WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT);
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
-               /* Wait for either the timer to expire
-                * or the mbox completion interrupt
-                */
-               down(&ha->mbx_intr_sem);
+               wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ);
 
-               DEBUG11(printk("%s(%ld): waking up. time=0x%lx\n", __func__,
-                   ha->host_no, jiffies));
                clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
 
-               /* delete the timer */
-               del_timer(&tmp_intr_timer);
        } else {
                DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__,
                    ha->host_no, command));
 
        /* Allow next mbx cmd to come in. */
        if (!abort_active)
-               up(&ha->mbx_cmd_sem);
+               complete(&ha->mbx_cmd_comp);
 
        if (rval) {
                DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, "
 
        }
        vha->mgmt_svr_loop_id = 10 + vha->vp_idx;
 
-       init_MUTEX(&vha->mbx_cmd_sem);
-       init_MUTEX_LOCKED(&vha->mbx_intr_sem);
+       init_completion(&vha->mbx_cmd_comp);
+       complete(&vha->mbx_cmd_comp);
+       init_completion(&vha->mbx_intr_comp);
 
        INIT_LIST_HEAD(&vha->list);
        INIT_LIST_HEAD(&vha->fcports);
 
        /* load the F/W, read paramaters, and init the H/W */
        ha->instance = num_hosts;
 
-       init_MUTEX(&ha->mbx_cmd_sem);
        init_MUTEX(&ha->vport_sem);
-       init_MUTEX_LOCKED(&ha->mbx_intr_sem);
+       init_completion(&ha->mbx_cmd_comp);
+       complete(&ha->mbx_cmd_comp);
+       init_completion(&ha->mbx_intr_comp);
 
        INIT_LIST_HEAD(&ha->list);
        INIT_LIST_HEAD(&ha->fcports);
        qla2x00_restart_timer(ha, WATCH_INTERVAL);
 }
 
-/* XXX(hch): crude hack to emulate a down_timeout() */
-int
-qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
-{
-       const unsigned int step = 100; /* msecs */
-       unsigned int iterations = jiffies_to_msecs(timeout)/100;
-
-       do {
-               if (!down_trylock(sema))
-                       return 0;
-               if (msleep_interruptible(step))
-                       break;
-       } while (--iterations > 0);
-
-       return -ETIMEDOUT;
-}
-
 /* Firmware interface routines. */
 
 #define FW_BLOBS       6