aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/ipr.c160
-rw-r--r--drivers/scsi/ipr.h6
2 files changed, 157 insertions, 9 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 9219953ee949..190d0ae0193f 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -99,6 +99,7 @@ static unsigned int ipr_debug = 0;
99static unsigned int ipr_max_devs = IPR_DEFAULT_SIS64_DEVS; 99static unsigned int ipr_max_devs = IPR_DEFAULT_SIS64_DEVS;
100static unsigned int ipr_dual_ioa_raid = 1; 100static unsigned int ipr_dual_ioa_raid = 1;
101static unsigned int ipr_number_of_msix = 2; 101static unsigned int ipr_number_of_msix = 2;
102static unsigned int ipr_fast_reboot;
102static DEFINE_SPINLOCK(ipr_driver_lock); 103static DEFINE_SPINLOCK(ipr_driver_lock);
103 104
104/* This table describes the differences between DMA controller chips */ 105/* This table describes the differences between DMA controller chips */
@@ -221,6 +222,8 @@ MODULE_PARM_DESC(max_devs, "Specify the maximum number of physical devices. "
221 "[Default=" __stringify(IPR_DEFAULT_SIS64_DEVS) "]"); 222 "[Default=" __stringify(IPR_DEFAULT_SIS64_DEVS) "]");
222module_param_named(number_of_msix, ipr_number_of_msix, int, 0); 223module_param_named(number_of_msix, ipr_number_of_msix, int, 0);
223MODULE_PARM_DESC(number_of_msix, "Specify the number of MSIX interrupts to use on capable adapters (1 - 16). (default:2)"); 224MODULE_PARM_DESC(number_of_msix, "Specify the number of MSIX interrupts to use on capable adapters (1 - 16). (default:2)");
225module_param_named(fast_reboot, ipr_fast_reboot, int, S_IRUGO | S_IWUSR);
226MODULE_PARM_DESC(fast_reboot, "Skip adapter shutdown during reboot. Set to 1 to enable. (default: 0)");
224MODULE_LICENSE("GPL"); 227MODULE_LICENSE("GPL");
225MODULE_VERSION(IPR_DRIVER_VERSION); 228MODULE_VERSION(IPR_DRIVER_VERSION);
226 229
@@ -1462,7 +1465,8 @@ static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd)
1462 list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); 1465 list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
1463 1466
1464 if (ioasc) { 1467 if (ioasc) {
1465 if (ioasc != IPR_IOASC_IOA_WAS_RESET) 1468 if (ioasc != IPR_IOASC_IOA_WAS_RESET &&
1469 ioasc != IPR_IOASC_ABORTED_CMD_TERM_BY_HOST)
1466 dev_err(&ioa_cfg->pdev->dev, 1470 dev_err(&ioa_cfg->pdev->dev,
1467 "Host RCB failed with IOASC: 0x%08X\n", ioasc); 1471 "Host RCB failed with IOASC: 0x%08X\n", ioasc);
1468 1472
@@ -2566,7 +2570,8 @@ static void ipr_process_error(struct ipr_cmnd *ipr_cmd)
2566 ipr_handle_log_data(ioa_cfg, hostrcb); 2570 ipr_handle_log_data(ioa_cfg, hostrcb);
2567 if (fd_ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED) 2571 if (fd_ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED)
2568 ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_ABBREV); 2572 ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_ABBREV);
2569 } else if (ioasc != IPR_IOASC_IOA_WAS_RESET) { 2573 } else if (ioasc != IPR_IOASC_IOA_WAS_RESET &&
2574 ioasc != IPR_IOASC_ABORTED_CMD_TERM_BY_HOST) {
2570 dev_err(&ioa_cfg->pdev->dev, 2575 dev_err(&ioa_cfg->pdev->dev,
2571 "Host RCB failed with IOASC: 0x%08X\n", ioasc); 2576 "Host RCB failed with IOASC: 0x%08X\n", ioasc);
2572 } 2577 }
@@ -5379,9 +5384,6 @@ static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg,
5379 if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { 5384 if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) {
5380 /* Mask the interrupt */ 5385 /* Mask the interrupt */
5381 writel(IPR_PCII_IOA_TRANS_TO_OPER, ioa_cfg->regs.set_interrupt_mask_reg); 5386 writel(IPR_PCII_IOA_TRANS_TO_OPER, ioa_cfg->regs.set_interrupt_mask_reg);
5382
5383 /* Clear the interrupt */
5384 writel(IPR_PCII_IOA_TRANS_TO_OPER, ioa_cfg->regs.clr_interrupt_reg);
5385 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); 5387 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
5386 5388
5387 list_del(&ioa_cfg->reset_cmd->queue); 5389 list_del(&ioa_cfg->reset_cmd->queue);
@@ -8479,6 +8481,122 @@ static int ipr_reset_alert(struct ipr_cmnd *ipr_cmd)
8479} 8481}
8480 8482
8481/** 8483/**
8484 * ipr_reset_quiesce_done - Complete IOA disconnect
8485 * @ipr_cmd: ipr command struct
8486 *
8487 * Description: Freeze the adapter to complete quiesce processing
8488 *
8489 * Return value:
8490 * IPR_RC_JOB_CONTINUE
8491 **/
8492static int ipr_reset_quiesce_done(struct ipr_cmnd *ipr_cmd)
8493{
8494 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
8495
8496 ENTER;
8497 ipr_cmd->job_step = ipr_ioa_bringdown_done;
8498 ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
8499 LEAVE;
8500 return IPR_RC_JOB_CONTINUE;
8501}
8502
8503/**
8504 * ipr_reset_cancel_hcam_done - Check for outstanding commands
8505 * @ipr_cmd: ipr command struct
8506 *
8507 * Description: Ensure nothing is outstanding to the IOA and
8508 * proceed with IOA disconnect. Otherwise reset the IOA.
8509 *
8510 * Return value:
8511 * IPR_RC_JOB_RETURN / IPR_RC_JOB_CONTINUE
8512 **/
8513static int ipr_reset_cancel_hcam_done(struct ipr_cmnd *ipr_cmd)
8514{
8515 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
8516 struct ipr_cmnd *loop_cmd;
8517 struct ipr_hrr_queue *hrrq;
8518 int rc = IPR_RC_JOB_CONTINUE;
8519 int count = 0;
8520
8521 ENTER;
8522 ipr_cmd->job_step = ipr_reset_quiesce_done;
8523
8524 for_each_hrrq(hrrq, ioa_cfg) {
8525 spin_lock(&hrrq->_lock);
8526 list_for_each_entry(loop_cmd, &hrrq->hrrq_pending_q, queue) {
8527 count++;
8528 ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
8529 list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
8530 rc = IPR_RC_JOB_RETURN;
8531 break;
8532 }
8533 spin_unlock(&hrrq->_lock);
8534
8535 if (count)
8536 break;
8537 }
8538
8539 LEAVE;
8540 return rc;
8541}
8542
8543/**
8544 * ipr_reset_cancel_hcam - Cancel outstanding HCAMs
8545 * @ipr_cmd: ipr command struct
8546 *
8547 * Description: Cancel any oustanding HCAMs to the IOA.
8548 *
8549 * Return value:
8550 * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
8551 **/
8552static int ipr_reset_cancel_hcam(struct ipr_cmnd *ipr_cmd)
8553{
8554 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
8555 int rc = IPR_RC_JOB_CONTINUE;
8556 struct ipr_cmd_pkt *cmd_pkt;
8557 struct ipr_cmnd *hcam_cmd;
8558 struct ipr_hrr_queue *hrrq = &ioa_cfg->hrrq[IPR_INIT_HRRQ];
8559
8560 ENTER;
8561 ipr_cmd->job_step = ipr_reset_cancel_hcam_done;
8562
8563 if (!hrrq->ioa_is_dead) {
8564 if (!list_empty(&ioa_cfg->hostrcb_pending_q)) {
8565 list_for_each_entry(hcam_cmd, &hrrq->hrrq_pending_q, queue) {
8566 if (hcam_cmd->ioarcb.cmd_pkt.cdb[0] != IPR_HOST_CONTROLLED_ASYNC)
8567 continue;
8568
8569 ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
8570 ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
8571 cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt;
8572 cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
8573 cmd_pkt->cdb[0] = IPR_CANCEL_REQUEST;
8574 cmd_pkt->cdb[1] = IPR_CANCEL_64BIT_IOARCB;
8575 cmd_pkt->cdb[10] = ((u64) hcam_cmd->dma_addr >> 56) & 0xff;
8576 cmd_pkt->cdb[11] = ((u64) hcam_cmd->dma_addr >> 48) & 0xff;
8577 cmd_pkt->cdb[12] = ((u64) hcam_cmd->dma_addr >> 40) & 0xff;
8578 cmd_pkt->cdb[13] = ((u64) hcam_cmd->dma_addr >> 32) & 0xff;
8579 cmd_pkt->cdb[2] = ((u64) hcam_cmd->dma_addr >> 24) & 0xff;
8580 cmd_pkt->cdb[3] = ((u64) hcam_cmd->dma_addr >> 16) & 0xff;
8581 cmd_pkt->cdb[4] = ((u64) hcam_cmd->dma_addr >> 8) & 0xff;
8582 cmd_pkt->cdb[5] = ((u64) hcam_cmd->dma_addr) & 0xff;
8583
8584 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout,
8585 IPR_CANCEL_TIMEOUT);
8586
8587 rc = IPR_RC_JOB_RETURN;
8588 ipr_cmd->job_step = ipr_reset_cancel_hcam;
8589 break;
8590 }
8591 }
8592 } else
8593 ipr_cmd->job_step = ipr_reset_alert;
8594
8595 LEAVE;
8596 return rc;
8597}
8598
8599/**
8482 * ipr_reset_ucode_download_done - Microcode download completion 8600 * ipr_reset_ucode_download_done - Microcode download completion
8483 * @ipr_cmd: ipr command struct 8601 * @ipr_cmd: ipr command struct
8484 * 8602 *
@@ -8560,7 +8678,9 @@ static int ipr_reset_shutdown_ioa(struct ipr_cmnd *ipr_cmd)
8560 int rc = IPR_RC_JOB_CONTINUE; 8678 int rc = IPR_RC_JOB_CONTINUE;
8561 8679
8562 ENTER; 8680 ENTER;
8563 if (shutdown_type != IPR_SHUTDOWN_NONE && 8681 if (shutdown_type == IPR_SHUTDOWN_QUIESCE)
8682 ipr_cmd->job_step = ipr_reset_cancel_hcam;
8683 else if (shutdown_type != IPR_SHUTDOWN_NONE &&
8564 !ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead) { 8684 !ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead) {
8565 ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); 8685 ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
8566 ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD; 8686 ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
@@ -10035,6 +10155,7 @@ static void ipr_shutdown(struct pci_dev *pdev)
10035{ 10155{
10036 struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); 10156 struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);
10037 unsigned long lock_flags = 0; 10157 unsigned long lock_flags = 0;
10158 enum ipr_shutdown_type shutdown_type = IPR_SHUTDOWN_NORMAL;
10038 int i; 10159 int i;
10039 10160
10040 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); 10161 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
@@ -10050,9 +10171,31 @@ static void ipr_shutdown(struct pci_dev *pdev)
10050 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); 10171 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
10051 } 10172 }
10052 10173
10053 ipr_initiate_ioa_bringdown(ioa_cfg, IPR_SHUTDOWN_NORMAL); 10174 if (ipr_fast_reboot && system_state == SYSTEM_RESTART && ioa_cfg->sis64)
10175 shutdown_type = IPR_SHUTDOWN_QUIESCE;
10176
10177 ipr_initiate_ioa_bringdown(ioa_cfg, shutdown_type);
10054 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 10178 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
10055 wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); 10179 wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
10180 if (ipr_fast_reboot && system_state == SYSTEM_RESTART && ioa_cfg->sis64) {
10181 if (ioa_cfg->intr_flag == IPR_USE_MSI ||
10182 ioa_cfg->intr_flag == IPR_USE_MSIX) {
10183 int i;
10184 for (i = 0; i < ioa_cfg->nvectors; i++)
10185 free_irq(ioa_cfg->vectors_info[i].vec,
10186 &ioa_cfg->hrrq[i]);
10187 }
10188
10189 if (ioa_cfg->intr_flag == IPR_USE_MSI) {
10190 pci_disable_msi(ioa_cfg->pdev);
10191 ioa_cfg->intr_flag &= ~IPR_USE_MSI;
10192 } else if (ioa_cfg->intr_flag == IPR_USE_MSIX) {
10193 pci_disable_msix(ioa_cfg->pdev);
10194 ioa_cfg->intr_flag &= ~IPR_USE_MSIX;
10195 }
10196
10197 pci_disable_device(ioa_cfg->pdev);
10198 }
10056} 10199}
10057 10200
10058static struct pci_device_id ipr_pci_table[] = { 10201static struct pci_device_id ipr_pci_table[] = {
@@ -10210,7 +10353,8 @@ static int ipr_halt(struct notifier_block *nb, ulong event, void *buf)
10210 10353
10211 list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) { 10354 list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) {
10212 spin_lock_irqsave(ioa_cfg->host->host_lock, flags); 10355 spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
10213 if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) { 10356 if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds ||
10357 (ipr_fast_reboot && event == SYS_RESTART && ioa_cfg->sis64)) {
10214 spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); 10358 spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
10215 continue; 10359 continue;
10216 } 10360 }
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index ec03b42fa2b9..34eec5bcdce0 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -196,6 +196,8 @@
196/* 196/*
197 * Adapter Commands 197 * Adapter Commands
198 */ 198 */
199#define IPR_CANCEL_REQUEST 0xC0
200#define IPR_CANCEL_64BIT_IOARCB 0x01
199#define IPR_QUERY_RSRC_STATE 0xC2 201#define IPR_QUERY_RSRC_STATE 0xC2
200#define IPR_RESET_DEVICE 0xC3 202#define IPR_RESET_DEVICE 0xC3
201#define IPR_RESET_TYPE_SELECT 0x80 203#define IPR_RESET_TYPE_SELECT 0x80
@@ -222,6 +224,7 @@
222#define IPR_ABBREV_SHUTDOWN_TIMEOUT (10 * HZ) 224#define IPR_ABBREV_SHUTDOWN_TIMEOUT (10 * HZ)
223#define IPR_DUAL_IOA_ABBR_SHUTDOWN_TO (2 * 60 * HZ) 225#define IPR_DUAL_IOA_ABBR_SHUTDOWN_TO (2 * 60 * HZ)
224#define IPR_DEVICE_RESET_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ) 226#define IPR_DEVICE_RESET_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ)
227#define IPR_CANCEL_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ)
225#define IPR_CANCEL_ALL_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ) 228#define IPR_CANCEL_ALL_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ)
226#define IPR_ABORT_TASK_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ) 229#define IPR_ABORT_TASK_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ)
227#define IPR_INTERNAL_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ) 230#define IPR_INTERNAL_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ)
@@ -1402,7 +1405,8 @@ enum ipr_shutdown_type {
1402 IPR_SHUTDOWN_NORMAL = 0x00, 1405 IPR_SHUTDOWN_NORMAL = 0x00,
1403 IPR_SHUTDOWN_PREPARE_FOR_NORMAL = 0x40, 1406 IPR_SHUTDOWN_PREPARE_FOR_NORMAL = 0x40,
1404 IPR_SHUTDOWN_ABBREV = 0x80, 1407 IPR_SHUTDOWN_ABBREV = 0x80,
1405 IPR_SHUTDOWN_NONE = 0x100 1408 IPR_SHUTDOWN_NONE = 0x100,
1409 IPR_SHUTDOWN_QUIESCE = 0x101,
1406}; 1410};
1407 1411
1408struct ipr_trace_entry { 1412struct ipr_trace_entry {