Index: ipr.c =================================================================== RCS file: /cvsroot/eserverio/ipr_2/ipr.c,v retrieving revision 1.7 diff -u -r1.7 ipr.c --- ipr.c 16 Jan 2004 23:56:45 -0000 1.7 +++ ipr.c 19 Jan 2004 16:11:32 -0000 @@ -596,140 +596,6 @@ }; /** - * ipr_sleep_no_lock - Sleep for the specified amount of time - * @delay: time to sleep - * - * Sleep for the specified amount of time - * - * Return value: - * none - **/ -static void ipr_sleep_no_lock(signed long delay) -{ - DECLARE_WAIT_QUEUE_HEAD(internal_wait); - - sleep_on_timeout(&internal_wait, (delay * HZ) / 1000); -} - -/** - * ipr_sleep - Sleep for the specified amount of time - * @ioa_cfg: ioa config struct - * @delay: time to sleep in msecs - * - * Release the host lock and sleep for the specified amount of time - * - * Return value: - * none - **/ -static void ipr_sleep(struct ipr_ioa_cfg *ioa_cfg, signed long delay) -{ - spin_unlock_irq(ioa_cfg->host->host_lock); - ipr_sleep_no_lock(delay); - spin_lock_irq(ioa_cfg->host->host_lock); -} - -/** - * ipr_interruptible_sleep_on - Sleep on the wait queue - * @ioa_cfg: ioa config struct - * @wait_head: wait queue to sleep on - * - * Sleep interruptibly on the wait queue. - * - * Return value: - * 0 on success / -EINTR if woken due to a signal - **/ -static int ipr_interruptible_sleep_on(struct ipr_ioa_cfg *ioa_cfg, - wait_queue_head_t *wait_head) -{ - DECLARE_WAITQUEUE(wait_q_entry, current); - - set_current_state(TASK_INTERRUPTIBLE); - - add_wait_queue(wait_head, &wait_q_entry); - - spin_unlock_irq(ioa_cfg->host->host_lock); - schedule(); - spin_lock_irq(ioa_cfg->host->host_lock); - - remove_wait_queue(wait_head, &wait_q_entry); - - if (signal_pending(current)) { - flush_signals(current); - return -EINTR; - } - - return 0; -} - -/** - * ipr_sleep_on - Sleep on the wait queue - * @ioa_cfg: ioa config struct - * @wait_head: wait queue to sleep on - * - * Sleep uninterruptibly on the wait queue. - * - * Return value: - * none - **/ -static void ipr_sleep_on(struct ipr_ioa_cfg *ioa_cfg, - wait_queue_head_t *wait_head) -{ - wait_queue_t wait_q_entry; - - init_waitqueue_entry(&wait_q_entry, current); - - set_current_state(TASK_UNINTERRUPTIBLE); - - add_wait_queue(wait_head, &wait_q_entry); - - spin_unlock_irq(ioa_cfg->host->host_lock); - - schedule(); - - spin_lock_irq(ioa_cfg->host->host_lock); - - remove_wait_queue(wait_head, &wait_q_entry); -} - -/** - * ipr_block_requests - Stop the host from issuing new requests. - * @ioa_cfg: ioa config struct - * - * This function blocks host requests. - * - * Return value: - * none - **/ -static void ipr_block_requests(struct ipr_ioa_cfg *ioa_cfg) -{ - if (0 == ioa_cfg->block_host_ops++) { - ioa_cfg->allow_cmds = 0; - - /* Stop new requests from coming in */ - scsi_block_requests(ioa_cfg->host); - } -} - -/** - * ipr_unblock_requests - Allow the host to send requests again. - * @ioa_cfg: ioa config struct - * - * This function unblocks requests. - * - * Return value: - * none - **/ -static void ipr_unblock_requests(struct ipr_ioa_cfg *ioa_cfg) -{ - if (0 == --ioa_cfg->block_host_ops) { - ioa_cfg->allow_cmds = 1; - spin_unlock_irq(ioa_cfg->host->host_lock); - scsi_unblock_requests(ioa_cfg->host); - spin_lock_irq(ioa_cfg->host->host_lock); - } -} - -/** * ipr_get_mode_page - Locate specified mode page * @mode_pages: mode page buffer * @page_code: page code to find @@ -1230,7 +1096,7 @@ INIT_LIST_HEAD(&ioa_cfg->used_res_q); INIT_WORK(&ioa_cfg->low_pri_work, ipr_worker_thread, ioa_cfg); init_waitqueue_head(&ioa_cfg->reset_wait_q); - init_waitqueue_head(&ioa_cfg->sdt_wait_q); + init_completion(&ioa_cfg->sdt_completion); ioa_cfg->sdt_state = INACTIVE; ipr_initialize_bus_attr(ioa_cfg); @@ -1544,7 +1410,7 @@ ioa_cfg->chip_cfg->cache_line_size); if (rc != PCIBIOS_SUCCESSFUL) { - dev_err(&pdev->dev, "Read of config space failed\n"); + dev_err(&pdev->dev, "Write of config space failed\n"); rc = -EIO; goto cleanup_nomem; } @@ -1561,9 +1427,6 @@ if ((rc = ipr_save_pcix_cmd_reg(ioa_cfg))) goto cleanup_nomem; - if ((rc = ipr_set_pcix_cmd_reg(ioa_cfg))) - goto cleanup_nomem; - if ((rc = ipr_alloc_mem(ioa_cfg))) goto cleanup; @@ -1624,7 +1487,9 @@ ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); - ipr_sleep_on(ioa_cfg, &ioa_cfg->reset_wait_q); + spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); + wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); + spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); if (ioa_cfg->ioa_is_dead) { rc = -EIO; @@ -1890,8 +1755,6 @@ dev_err(&ioa_cfg->pdev->dev, "Adapter being reset due to command timeout.\n"); - ipr_block_requests(ioa_cfg); - if (WAIT_FOR_DUMP == ioa_cfg->sdt_state) ioa_cfg->sdt_state = GET_DUMP; @@ -1920,6 +1783,10 @@ ioa_cfg->reset_retries = 0; list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); wake_up_all(&ioa_cfg->reset_wait_q); + + spin_unlock_irq(ioa_cfg->host->host_lock); + scsi_unblock_requests(ioa_cfg->host); + spin_lock_irq(ioa_cfg->host->host_lock); LEAVE; return IPR_RC_JOB_RETURN; @@ -1970,7 +1837,14 @@ wake_up_all(&ioa_cfg->reset_wait_q); if (ioa_cfg->sdt_state == DUMP_OBTAINED) - wake_up_interruptible(&ioa_cfg->sdt_wait_q); + complete(&ioa_cfg->sdt_completion); + + spin_unlock_irq(ioa_cfg->host->host_lock); + scsi_unblock_requests(ioa_cfg->host); + spin_lock_irq(ioa_cfg->host->host_lock); + + if (!ioa_cfg->allow_cmds) + scsi_block_requests(ioa_cfg->host); LEAVE; return IPR_RC_JOB_RETURN; @@ -2811,7 +2685,7 @@ if (GET_DUMP == ioa_cfg->sdt_state) { ipr_reset_start_timer(ipr_cmd, IPR_DUMP_TIMEOUT); ipr_cmd->job_step = ipr_reset_wait_for_dump; - wake_up_interruptible(&ioa_cfg->sdt_wait_q); + complete(&ioa_cfg->sdt_completion); return IPR_RC_JOB_RETURN; } } @@ -3050,6 +2924,10 @@ ioa_cfg->in_reset_reload = 0; ipr_fail_all_ops(ioa_cfg); wake_up_all(&ioa_cfg->reset_wait_q); + + spin_unlock_irq(ioa_cfg->host->host_lock); + scsi_unblock_requests(ioa_cfg->host); + spin_lock_irq(ioa_cfg->host->host_lock); return; } else { ioa_cfg->in_ioa_bringdown = 1; @@ -3059,6 +2937,7 @@ ioa_cfg->in_reset_reload = 1; ioa_cfg->allow_cmds = 0; + scsi_block_requests(ioa_cfg->host); list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) ipr_cmd->parent = NULL; @@ -3129,7 +3008,6 @@ if (WAIT_FOR_DUMP == ioa_cfg->sdt_state) ioa_cfg->sdt_state = GET_DUMP; - ipr_block_requests(ioa_cfg); ipr_mask_and_clear_all_interrupts(ioa_cfg); ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); } else { @@ -3195,7 +3073,6 @@ if (WAIT_FOR_DUMP == ioa_cfg->sdt_state) ioa_cfg->sdt_state = GET_DUMP; - ipr_block_requests(ioa_cfg); ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); return IRQ_HANDLED; } @@ -3944,7 +3821,7 @@ scsi_cmd->result = (DID_OK << 16); - if (unlikely(ioa_cfg->block_host_ops)) { + if (unlikely(!ioa_cfg->allow_cmds)) { /* * We are currently blocking all devices due to a host reset * We have told the host to stop giving us new requests, but @@ -4249,7 +4126,9 @@ return FAILED; if (ioa_cfg->in_reset_reload) { - ipr_sleep_on(ioa_cfg, &ioa_cfg->reset_wait_q); + spin_unlock_irq(ioa_cfg->host->host_lock); + wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); + spin_lock_irq(ioa_cfg->host->host_lock); /* If we got hit with a host reset while we were already resetting the adapter for some reason, and the reset failed. */ @@ -4260,8 +4139,11 @@ } else { ipr_initiate_ioa_reset(ioa_cfg, shutdown_type); - if (ioa_cfg->in_reset_reload) - ipr_sleep_on(ioa_cfg, &ioa_cfg->reset_wait_q); + if (ioa_cfg->in_reset_reload) { + spin_unlock_irq(ioa_cfg->host->host_lock); + wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); + spin_lock_irq(ioa_cfg->host->host_lock); + } if (ioa_cfg->ioa_is_dead) { ipr_trace; @@ -4353,9 +4235,8 @@ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); ipr_initiate_ioa_bringdown(ioa_cfg, IPR_SHUTDOWN_NORMAL); - if (ioa_cfg->in_reset_reload) - ipr_sleep_on(ioa_cfg, &ioa_cfg->reset_wait_q); spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); } /** @@ -5697,8 +5578,12 @@ { int rc = 0; - if (ioa_cfg->in_reset_reload) - rc = ipr_interruptible_sleep_on(ioa_cfg, &ioa_cfg->reset_wait_q); + if (ioa_cfg->in_reset_reload) { + spin_unlock_irq(ioa_cfg->host->host_lock); + rc = wait_event_interruptible(ioa_cfg->reset_wait_q, + !ioa_cfg->in_reset_reload); + spin_lock_irq(ioa_cfg->host->host_lock); + } if (!ioa_cfg->allow_cmds) rc = -EIO; @@ -5965,15 +5850,10 @@ list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); - if (ioasc != IPR_IOASC_IOA_WAS_RESET) { - ipr_block_requests(ioa_cfg); - + if (ioasc != IPR_IOASC_IOA_WAS_RESET) if (ipr_reset_reload(ioa_cfg, IPR_SHUTDOWN_NORMAL) != SUCCESS) result = -EIO; - ipr_unblock_requests(ioa_cfg); - } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); return result; @@ -6164,19 +6044,17 @@ return rc; } - ipr_block_requests(ioa_cfg); - ioa_cfg->errors_logged = 0; if (ipr_reset_reload(ioa_cfg, IPR_SHUTDOWN_NORMAL) != SUCCESS) rc = -EIO; - ipr_unblock_requests(ioa_cfg); - /* Wait for a second for any errors to be logged */ - ipr_sleep(ioa_cfg, 1000); + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + schedule_timeout(HZ); + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - if (ioa_cfg->errors_logged) + if (ioa_cfg->in_reset_reload || ioa_cfg->errors_logged) rc = -EIO; spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); @@ -6311,7 +6189,10 @@ ioa_cfg->dump_taken = 1; } else { ioa_cfg->sdt_state = WAIT_FOR_DUMP; - (void) ipr_interruptible_sleep_on(ioa_cfg, &ioa_cfg->sdt_wait_q); + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + (void) wait_event_interruptible(ioa_cfg->sdt_completion.wait, + ioa_cfg->sdt_completion.done); + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); if (ioa_cfg->sdt_state == GET_DUMP) ipr_get_ioa_smart_dump(ioa_cfg); @@ -6359,13 +6240,9 @@ return result; } - ipr_block_requests(ioa_cfg); - if (ipr_reset_reload(ioa_cfg, IPR_SHUTDOWN_NORMAL) != SUCCESS) result = -EIO; - ipr_unblock_requests(ioa_cfg); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); return result; @@ -6615,7 +6492,8 @@ return result; } - ipr_block_requests(ioa_cfg); + ioa_cfg->allow_cmds = 0; + scsi_block_requests(ioa_cfg->host); if ((result = ipr_shutdown_ioa(ioa_cfg))) { spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); @@ -6655,8 +6533,6 @@ if (ipr_reset_reload(ioa_cfg, IPR_SHUTDOWN_NONE) != SUCCESS) result = -EIO; - ipr_unblock_requests(ioa_cfg); - ipr_free_ucode_buffer(sglist); spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); @@ -7500,12 +7376,13 @@ scsi_remove_host(ioa_cfg->host); spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); - ipr_initiate_ioa_bringdown(ioa_cfg, IPR_SHUTDOWN_NORMAL); - if (ioa_cfg->in_reset_reload) - ipr_sleep_on(ioa_cfg, &ioa_cfg->reset_wait_q); - wake_up_interruptible(&ioa_cfg->sdt_wait_q); + spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); + wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); + spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); + + complete(&ioa_cfg->sdt_completion); spin_lock(&ipr_driver_lock); list_del(&ioa_cfg->queue); Index: ipr.h =================================================================== RCS file: /cvsroot/eserverio/ipr_2/ipr.h,v retrieving revision 1.7 diff -u -r1.7 ipr.h --- ipr.h 16 Jan 2004 23:56:45 -0000 1.7 +++ ipr.h 19 Jan 2004 16:11:32 -0000 @@ -1382,7 +1382,6 @@ struct work_struct low_pri_work; int minor_num; - int block_host_ops; struct semaphore ioctl_semaphore; @@ -1390,7 +1389,7 @@ struct ipr_dump_ioa_entry *ioa_dump; struct ipr_dump_driver_header *dump; - wait_queue_head_t sdt_wait_q; + struct completion sdt_completion; enum ipr_sdt_state sdt_state; struct ipr_vpd_cbs *vpd_cbs;