diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-16 19:02:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-16 19:02:04 -0400 |
commit | 7d69cff26ceadce8638cb65191285932a3de3d4c (patch) | |
tree | 7a23eb561e6a25fbd111af2d0152cc6f34c2cecd /drivers/scsi/ipr.c | |
parent | 8fa6f4974d55ad1fb0a9522c5a5cfd050a517048 (diff) | |
parent | 0351b8f81392c6dbbbb036e5c8f73ceff68726e9 (diff) |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This is the usual grab bag of driver updates (lpfc, qla2xxx, storvsc,
aacraid, ipr) plus an assortment of minor updates. There's also a
major update to aic1542 which moves the driver into this millenium"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (106 commits)
change SCSI Maintainer email
sd, mmc, virtio_blk, string_helpers: fix block size units
ufs: add support to allow non standard behaviours (quirks)
ufs-qcom: save controller revision info in internal structure
qla2xxx: Update driver version to 8.07.00.18-k
qla2xxx: Restore physical port WWPN only, when port down detected for FA-WWPN port.
qla2xxx: Fix virtual port configuration, when switch port is disabled/enabled.
qla2xxx: Prevent multiple firmware dump collection for ISP27XX.
qla2xxx: Disable Interrupt handshake for ISP27XX.
qla2xxx: Add debugging info for MBX timeout.
qla2xxx: Add serdes read/write support for ISP27XX
qla2xxx: Add udev notification to save fw dump for ISP27XX
qla2xxx: Add message for sucessful FW dump collected for ISP27XX.
qla2xxx: Add support to load firmware from file for ISP 26XX/27XX.
qla2xxx: Fix beacon blink for ISP27XX.
qla2xxx: Increase the wait time for firmware to be ready for P3P.
qla2xxx: Fix crash due to wrong casting of reg for ISP27XX.
qla2xxx: Fix warnings reported by static checker.
lpfc: Update version to 10.5.0.0 for upstream patch set
lpfc: Update copyright to 2015
...
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r-- | drivers/scsi/ipr.c | 319 |
1 files changed, 294 insertions, 25 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index d9afc51af7d3..882744852aac 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -99,6 +99,7 @@ static unsigned int ipr_debug = 0; | |||
99 | static unsigned int ipr_max_devs = IPR_DEFAULT_SIS64_DEVS; | 99 | static unsigned int ipr_max_devs = IPR_DEFAULT_SIS64_DEVS; |
100 | static unsigned int ipr_dual_ioa_raid = 1; | 100 | static unsigned int ipr_dual_ioa_raid = 1; |
101 | static unsigned int ipr_number_of_msix = 2; | 101 | static unsigned int ipr_number_of_msix = 2; |
102 | static unsigned int ipr_fast_reboot; | ||
102 | static DEFINE_SPINLOCK(ipr_driver_lock); | 103 | static 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) "]"); |
222 | module_param_named(number_of_msix, ipr_number_of_msix, int, 0); | 223 | module_param_named(number_of_msix, ipr_number_of_msix, int, 0); |
223 | MODULE_PARM_DESC(number_of_msix, "Specify the number of MSIX interrupts to use on capable adapters (1 - 16). (default:2)"); | 224 | MODULE_PARM_DESC(number_of_msix, "Specify the number of MSIX interrupts to use on capable adapters (1 - 16). (default:2)"); |
225 | module_param_named(fast_reboot, ipr_fast_reboot, int, S_IRUGO | S_IWUSR); | ||
226 | MODULE_PARM_DESC(fast_reboot, "Skip adapter shutdown during reboot. Set to 1 to enable. (default: 0)"); | ||
224 | MODULE_LICENSE("GPL"); | 227 | MODULE_LICENSE("GPL"); |
225 | MODULE_VERSION(IPR_DRIVER_VERSION); | 228 | MODULE_VERSION(IPR_DRIVER_VERSION); |
226 | 229 | ||
@@ -495,6 +498,10 @@ struct ipr_error_table_t ipr_error_table[] = { | |||
495 | "4061: Multipath redundancy level got better"}, | 498 | "4061: Multipath redundancy level got better"}, |
496 | {0x066B9200, 0, IPR_DEFAULT_LOG_LEVEL, | 499 | {0x066B9200, 0, IPR_DEFAULT_LOG_LEVEL, |
497 | "4060: Multipath redundancy level got worse"}, | 500 | "4060: Multipath redundancy level got worse"}, |
501 | {0x06808100, 0, IPR_DEFAULT_LOG_LEVEL, | ||
502 | "9083: Device raw mode enabled"}, | ||
503 | {0x06808200, 0, IPR_DEFAULT_LOG_LEVEL, | ||
504 | "9084: Device raw mode disabled"}, | ||
498 | {0x07270000, 0, 0, | 505 | {0x07270000, 0, 0, |
499 | "Failure due to other device"}, | 506 | "Failure due to other device"}, |
500 | {0x07278000, 0, IPR_DEFAULT_LOG_LEVEL, | 507 | {0x07278000, 0, IPR_DEFAULT_LOG_LEVEL, |
@@ -1462,7 +1469,8 @@ static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd) | |||
1462 | list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); | 1469 | list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); |
1463 | 1470 | ||
1464 | if (ioasc) { | 1471 | if (ioasc) { |
1465 | if (ioasc != IPR_IOASC_IOA_WAS_RESET) | 1472 | if (ioasc != IPR_IOASC_IOA_WAS_RESET && |
1473 | ioasc != IPR_IOASC_ABORTED_CMD_TERM_BY_HOST) | ||
1466 | dev_err(&ioa_cfg->pdev->dev, | 1474 | dev_err(&ioa_cfg->pdev->dev, |
1467 | "Host RCB failed with IOASC: 0x%08X\n", ioasc); | 1475 | "Host RCB failed with IOASC: 0x%08X\n", ioasc); |
1468 | 1476 | ||
@@ -2566,7 +2574,8 @@ static void ipr_process_error(struct ipr_cmnd *ipr_cmd) | |||
2566 | ipr_handle_log_data(ioa_cfg, hostrcb); | 2574 | ipr_handle_log_data(ioa_cfg, hostrcb); |
2567 | if (fd_ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED) | 2575 | if (fd_ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED) |
2568 | ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_ABBREV); | 2576 | ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_ABBREV); |
2569 | } else if (ioasc != IPR_IOASC_IOA_WAS_RESET) { | 2577 | } else if (ioasc != IPR_IOASC_IOA_WAS_RESET && |
2578 | ioasc != IPR_IOASC_ABORTED_CMD_TERM_BY_HOST) { | ||
2570 | dev_err(&ioa_cfg->pdev->dev, | 2579 | dev_err(&ioa_cfg->pdev->dev, |
2571 | "Host RCB failed with IOASC: 0x%08X\n", ioasc); | 2580 | "Host RCB failed with IOASC: 0x%08X\n", ioasc); |
2572 | } | 2581 | } |
@@ -4491,11 +4500,83 @@ static struct device_attribute ipr_resource_type_attr = { | |||
4491 | .show = ipr_show_resource_type | 4500 | .show = ipr_show_resource_type |
4492 | }; | 4501 | }; |
4493 | 4502 | ||
4503 | /** | ||
4504 | * ipr_show_raw_mode - Show the adapter's raw mode | ||
4505 | * @dev: class device struct | ||
4506 | * @buf: buffer | ||
4507 | * | ||
4508 | * Return value: | ||
4509 | * number of bytes printed to buffer | ||
4510 | **/ | ||
4511 | static ssize_t ipr_show_raw_mode(struct device *dev, | ||
4512 | struct device_attribute *attr, char *buf) | ||
4513 | { | ||
4514 | struct scsi_device *sdev = to_scsi_device(dev); | ||
4515 | struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata; | ||
4516 | struct ipr_resource_entry *res; | ||
4517 | unsigned long lock_flags = 0; | ||
4518 | ssize_t len; | ||
4519 | |||
4520 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | ||
4521 | res = (struct ipr_resource_entry *)sdev->hostdata; | ||
4522 | if (res) | ||
4523 | len = snprintf(buf, PAGE_SIZE, "%d\n", res->raw_mode); | ||
4524 | else | ||
4525 | len = -ENXIO; | ||
4526 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
4527 | return len; | ||
4528 | } | ||
4529 | |||
4530 | /** | ||
4531 | * ipr_store_raw_mode - Change the adapter's raw mode | ||
4532 | * @dev: class device struct | ||
4533 | * @buf: buffer | ||
4534 | * | ||
4535 | * Return value: | ||
4536 | * number of bytes printed to buffer | ||
4537 | **/ | ||
4538 | static ssize_t ipr_store_raw_mode(struct device *dev, | ||
4539 | struct device_attribute *attr, | ||
4540 | const char *buf, size_t count) | ||
4541 | { | ||
4542 | struct scsi_device *sdev = to_scsi_device(dev); | ||
4543 | struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata; | ||
4544 | struct ipr_resource_entry *res; | ||
4545 | unsigned long lock_flags = 0; | ||
4546 | ssize_t len; | ||
4547 | |||
4548 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | ||
4549 | res = (struct ipr_resource_entry *)sdev->hostdata; | ||
4550 | if (res) { | ||
4551 | if (ioa_cfg->sis64 && ipr_is_af_dasd_device(res)) { | ||
4552 | res->raw_mode = simple_strtoul(buf, NULL, 10); | ||
4553 | len = strlen(buf); | ||
4554 | if (res->sdev) | ||
4555 | sdev_printk(KERN_INFO, res->sdev, "raw mode is %s\n", | ||
4556 | res->raw_mode ? "enabled" : "disabled"); | ||
4557 | } else | ||
4558 | len = -EINVAL; | ||
4559 | } else | ||
4560 | len = -ENXIO; | ||
4561 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
4562 | return len; | ||
4563 | } | ||
4564 | |||
4565 | static struct device_attribute ipr_raw_mode_attr = { | ||
4566 | .attr = { | ||
4567 | .name = "raw_mode", | ||
4568 | .mode = S_IRUGO | S_IWUSR, | ||
4569 | }, | ||
4570 | .show = ipr_show_raw_mode, | ||
4571 | .store = ipr_store_raw_mode | ||
4572 | }; | ||
4573 | |||
4494 | static struct device_attribute *ipr_dev_attrs[] = { | 4574 | static struct device_attribute *ipr_dev_attrs[] = { |
4495 | &ipr_adapter_handle_attr, | 4575 | &ipr_adapter_handle_attr, |
4496 | &ipr_resource_path_attr, | 4576 | &ipr_resource_path_attr, |
4497 | &ipr_device_id_attr, | 4577 | &ipr_device_id_attr, |
4498 | &ipr_resource_type_attr, | 4578 | &ipr_resource_type_attr, |
4579 | &ipr_raw_mode_attr, | ||
4499 | NULL, | 4580 | NULL, |
4500 | }; | 4581 | }; |
4501 | 4582 | ||
@@ -5379,9 +5460,6 @@ static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg, | |||
5379 | if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { | 5460 | if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { |
5380 | /* Mask the interrupt */ | 5461 | /* Mask the interrupt */ |
5381 | writel(IPR_PCII_IOA_TRANS_TO_OPER, ioa_cfg->regs.set_interrupt_mask_reg); | 5462 | 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); | 5463 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); |
5386 | 5464 | ||
5387 | list_del(&ioa_cfg->reset_cmd->queue); | 5465 | list_del(&ioa_cfg->reset_cmd->queue); |
@@ -6150,6 +6228,13 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, | |||
6150 | break; | 6228 | break; |
6151 | case IPR_IOASC_NR_INIT_CMD_REQUIRED: | 6229 | case IPR_IOASC_NR_INIT_CMD_REQUIRED: |
6152 | break; | 6230 | break; |
6231 | case IPR_IOASC_IR_NON_OPTIMIZED: | ||
6232 | if (res->raw_mode) { | ||
6233 | res->raw_mode = 0; | ||
6234 | scsi_cmd->result |= (DID_IMM_RETRY << 16); | ||
6235 | } else | ||
6236 | scsi_cmd->result |= (DID_ERROR << 16); | ||
6237 | break; | ||
6153 | default: | 6238 | default: |
6154 | if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR) | 6239 | if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR) |
6155 | scsi_cmd->result |= (DID_ERROR << 16); | 6240 | scsi_cmd->result |= (DID_ERROR << 16); |
@@ -6289,6 +6374,8 @@ static int ipr_queuecommand(struct Scsi_Host *shost, | |||
6289 | (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) { | 6374 | (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) { |
6290 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | 6375 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; |
6291 | } | 6376 | } |
6377 | if (res->raw_mode && ipr_is_af_dasd_device(res)) | ||
6378 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_PIPE; | ||
6292 | 6379 | ||
6293 | if (ioa_cfg->sis64) | 6380 | if (ioa_cfg->sis64) |
6294 | rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd); | 6381 | rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd); |
@@ -6402,7 +6489,6 @@ static struct scsi_host_template driver_template = { | |||
6402 | .shost_attrs = ipr_ioa_attrs, | 6489 | .shost_attrs = ipr_ioa_attrs, |
6403 | .sdev_attrs = ipr_dev_attrs, | 6490 | .sdev_attrs = ipr_dev_attrs, |
6404 | .proc_name = IPR_NAME, | 6491 | .proc_name = IPR_NAME, |
6405 | .no_write_same = 1, | ||
6406 | .use_blk_tags = 1, | 6492 | .use_blk_tags = 1, |
6407 | }; | 6493 | }; |
6408 | 6494 | ||
@@ -8318,7 +8404,6 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd) | |||
8318 | static int ipr_reset_slot_reset_done(struct ipr_cmnd *ipr_cmd) | 8404 | static int ipr_reset_slot_reset_done(struct ipr_cmnd *ipr_cmd) |
8319 | { | 8405 | { |
8320 | ENTER; | 8406 | ENTER; |
8321 | pci_set_pcie_reset_state(ipr_cmd->ioa_cfg->pdev, pcie_deassert_reset); | ||
8322 | ipr_cmd->job_step = ipr_reset_bist_done; | 8407 | ipr_cmd->job_step = ipr_reset_bist_done; |
8323 | ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT); | 8408 | ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT); |
8324 | LEAVE; | 8409 | LEAVE; |
@@ -8326,6 +8411,32 @@ static int ipr_reset_slot_reset_done(struct ipr_cmnd *ipr_cmd) | |||
8326 | } | 8411 | } |
8327 | 8412 | ||
8328 | /** | 8413 | /** |
8414 | * ipr_reset_reset_work - Pulse a PCIe fundamental reset | ||
8415 | * @work: work struct | ||
8416 | * | ||
8417 | * Description: This pulses warm reset to a slot. | ||
8418 | * | ||
8419 | **/ | ||
8420 | static void ipr_reset_reset_work(struct work_struct *work) | ||
8421 | { | ||
8422 | struct ipr_cmnd *ipr_cmd = container_of(work, struct ipr_cmnd, work); | ||
8423 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
8424 | struct pci_dev *pdev = ioa_cfg->pdev; | ||
8425 | unsigned long lock_flags = 0; | ||
8426 | |||
8427 | ENTER; | ||
8428 | pci_set_pcie_reset_state(pdev, pcie_warm_reset); | ||
8429 | msleep(jiffies_to_msecs(IPR_PCI_RESET_TIMEOUT)); | ||
8430 | pci_set_pcie_reset_state(pdev, pcie_deassert_reset); | ||
8431 | |||
8432 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | ||
8433 | if (ioa_cfg->reset_cmd == ipr_cmd) | ||
8434 | ipr_reset_ioa_job(ipr_cmd); | ||
8435 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
8436 | LEAVE; | ||
8437 | } | ||
8438 | |||
8439 | /** | ||
8329 | * ipr_reset_slot_reset - Reset the PCI slot of the adapter. | 8440 | * ipr_reset_slot_reset - Reset the PCI slot of the adapter. |
8330 | * @ipr_cmd: ipr command struct | 8441 | * @ipr_cmd: ipr command struct |
8331 | * | 8442 | * |
@@ -8337,12 +8448,11 @@ static int ipr_reset_slot_reset_done(struct ipr_cmnd *ipr_cmd) | |||
8337 | static int ipr_reset_slot_reset(struct ipr_cmnd *ipr_cmd) | 8448 | static int ipr_reset_slot_reset(struct ipr_cmnd *ipr_cmd) |
8338 | { | 8449 | { |
8339 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 8450 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
8340 | struct pci_dev *pdev = ioa_cfg->pdev; | ||
8341 | 8451 | ||
8342 | ENTER; | 8452 | ENTER; |
8343 | pci_set_pcie_reset_state(pdev, pcie_warm_reset); | 8453 | INIT_WORK(&ipr_cmd->work, ipr_reset_reset_work); |
8454 | queue_work(ioa_cfg->reset_work_q, &ipr_cmd->work); | ||
8344 | ipr_cmd->job_step = ipr_reset_slot_reset_done; | 8455 | ipr_cmd->job_step = ipr_reset_slot_reset_done; |
8345 | ipr_reset_start_timer(ipr_cmd, IPR_PCI_RESET_TIMEOUT); | ||
8346 | LEAVE; | 8456 | LEAVE; |
8347 | return IPR_RC_JOB_RETURN; | 8457 | return IPR_RC_JOB_RETURN; |
8348 | } | 8458 | } |
@@ -8480,6 +8590,122 @@ static int ipr_reset_alert(struct ipr_cmnd *ipr_cmd) | |||
8480 | } | 8590 | } |
8481 | 8591 | ||
8482 | /** | 8592 | /** |
8593 | * ipr_reset_quiesce_done - Complete IOA disconnect | ||
8594 | * @ipr_cmd: ipr command struct | ||
8595 | * | ||
8596 | * Description: Freeze the adapter to complete quiesce processing | ||
8597 | * | ||
8598 | * Return value: | ||
8599 | * IPR_RC_JOB_CONTINUE | ||
8600 | **/ | ||
8601 | static int ipr_reset_quiesce_done(struct ipr_cmnd *ipr_cmd) | ||
8602 | { | ||
8603 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
8604 | |||
8605 | ENTER; | ||
8606 | ipr_cmd->job_step = ipr_ioa_bringdown_done; | ||
8607 | ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); | ||
8608 | LEAVE; | ||
8609 | return IPR_RC_JOB_CONTINUE; | ||
8610 | } | ||
8611 | |||
8612 | /** | ||
8613 | * ipr_reset_cancel_hcam_done - Check for outstanding commands | ||
8614 | * @ipr_cmd: ipr command struct | ||
8615 | * | ||
8616 | * Description: Ensure nothing is outstanding to the IOA and | ||
8617 | * proceed with IOA disconnect. Otherwise reset the IOA. | ||
8618 | * | ||
8619 | * Return value: | ||
8620 | * IPR_RC_JOB_RETURN / IPR_RC_JOB_CONTINUE | ||
8621 | **/ | ||
8622 | static int ipr_reset_cancel_hcam_done(struct ipr_cmnd *ipr_cmd) | ||
8623 | { | ||
8624 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
8625 | struct ipr_cmnd *loop_cmd; | ||
8626 | struct ipr_hrr_queue *hrrq; | ||
8627 | int rc = IPR_RC_JOB_CONTINUE; | ||
8628 | int count = 0; | ||
8629 | |||
8630 | ENTER; | ||
8631 | ipr_cmd->job_step = ipr_reset_quiesce_done; | ||
8632 | |||
8633 | for_each_hrrq(hrrq, ioa_cfg) { | ||
8634 | spin_lock(&hrrq->_lock); | ||
8635 | list_for_each_entry(loop_cmd, &hrrq->hrrq_pending_q, queue) { | ||
8636 | count++; | ||
8637 | ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); | ||
8638 | list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); | ||
8639 | rc = IPR_RC_JOB_RETURN; | ||
8640 | break; | ||
8641 | } | ||
8642 | spin_unlock(&hrrq->_lock); | ||
8643 | |||
8644 | if (count) | ||
8645 | break; | ||
8646 | } | ||
8647 | |||
8648 | LEAVE; | ||
8649 | return rc; | ||
8650 | } | ||
8651 | |||
8652 | /** | ||
8653 | * ipr_reset_cancel_hcam - Cancel outstanding HCAMs | ||
8654 | * @ipr_cmd: ipr command struct | ||
8655 | * | ||
8656 | * Description: Cancel any oustanding HCAMs to the IOA. | ||
8657 | * | ||
8658 | * Return value: | ||
8659 | * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN | ||
8660 | **/ | ||
8661 | static int ipr_reset_cancel_hcam(struct ipr_cmnd *ipr_cmd) | ||
8662 | { | ||
8663 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
8664 | int rc = IPR_RC_JOB_CONTINUE; | ||
8665 | struct ipr_cmd_pkt *cmd_pkt; | ||
8666 | struct ipr_cmnd *hcam_cmd; | ||
8667 | struct ipr_hrr_queue *hrrq = &ioa_cfg->hrrq[IPR_INIT_HRRQ]; | ||
8668 | |||
8669 | ENTER; | ||
8670 | ipr_cmd->job_step = ipr_reset_cancel_hcam_done; | ||
8671 | |||
8672 | if (!hrrq->ioa_is_dead) { | ||
8673 | if (!list_empty(&ioa_cfg->hostrcb_pending_q)) { | ||
8674 | list_for_each_entry(hcam_cmd, &hrrq->hrrq_pending_q, queue) { | ||
8675 | if (hcam_cmd->ioarcb.cmd_pkt.cdb[0] != IPR_HOST_CONTROLLED_ASYNC) | ||
8676 | continue; | ||
8677 | |||
8678 | ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); | ||
8679 | ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | ||
8680 | cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt; | ||
8681 | cmd_pkt->request_type = IPR_RQTYPE_IOACMD; | ||
8682 | cmd_pkt->cdb[0] = IPR_CANCEL_REQUEST; | ||
8683 | cmd_pkt->cdb[1] = IPR_CANCEL_64BIT_IOARCB; | ||
8684 | cmd_pkt->cdb[10] = ((u64) hcam_cmd->dma_addr >> 56) & 0xff; | ||
8685 | cmd_pkt->cdb[11] = ((u64) hcam_cmd->dma_addr >> 48) & 0xff; | ||
8686 | cmd_pkt->cdb[12] = ((u64) hcam_cmd->dma_addr >> 40) & 0xff; | ||
8687 | cmd_pkt->cdb[13] = ((u64) hcam_cmd->dma_addr >> 32) & 0xff; | ||
8688 | cmd_pkt->cdb[2] = ((u64) hcam_cmd->dma_addr >> 24) & 0xff; | ||
8689 | cmd_pkt->cdb[3] = ((u64) hcam_cmd->dma_addr >> 16) & 0xff; | ||
8690 | cmd_pkt->cdb[4] = ((u64) hcam_cmd->dma_addr >> 8) & 0xff; | ||
8691 | cmd_pkt->cdb[5] = ((u64) hcam_cmd->dma_addr) & 0xff; | ||
8692 | |||
8693 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, | ||
8694 | IPR_CANCEL_TIMEOUT); | ||
8695 | |||
8696 | rc = IPR_RC_JOB_RETURN; | ||
8697 | ipr_cmd->job_step = ipr_reset_cancel_hcam; | ||
8698 | break; | ||
8699 | } | ||
8700 | } | ||
8701 | } else | ||
8702 | ipr_cmd->job_step = ipr_reset_alert; | ||
8703 | |||
8704 | LEAVE; | ||
8705 | return rc; | ||
8706 | } | ||
8707 | |||
8708 | /** | ||
8483 | * ipr_reset_ucode_download_done - Microcode download completion | 8709 | * ipr_reset_ucode_download_done - Microcode download completion |
8484 | * @ipr_cmd: ipr command struct | 8710 | * @ipr_cmd: ipr command struct |
8485 | * | 8711 | * |
@@ -8561,7 +8787,9 @@ static int ipr_reset_shutdown_ioa(struct ipr_cmnd *ipr_cmd) | |||
8561 | int rc = IPR_RC_JOB_CONTINUE; | 8787 | int rc = IPR_RC_JOB_CONTINUE; |
8562 | 8788 | ||
8563 | ENTER; | 8789 | ENTER; |
8564 | if (shutdown_type != IPR_SHUTDOWN_NONE && | 8790 | if (shutdown_type == IPR_SHUTDOWN_QUIESCE) |
8791 | ipr_cmd->job_step = ipr_reset_cancel_hcam; | ||
8792 | else if (shutdown_type != IPR_SHUTDOWN_NONE && | ||
8565 | !ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead) { | 8793 | !ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead) { |
8566 | ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); | 8794 | ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); |
8567 | ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | 8795 | ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD; |
@@ -8917,13 +9145,15 @@ static void ipr_free_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) | |||
8917 | { | 9145 | { |
8918 | int i; | 9146 | int i; |
8919 | 9147 | ||
8920 | for (i = 0; i < IPR_NUM_CMD_BLKS; i++) { | 9148 | if (ioa_cfg->ipr_cmnd_list) { |
8921 | if (ioa_cfg->ipr_cmnd_list[i]) | 9149 | for (i = 0; i < IPR_NUM_CMD_BLKS; i++) { |
8922 | dma_pool_free(ioa_cfg->ipr_cmd_pool, | 9150 | if (ioa_cfg->ipr_cmnd_list[i]) |
8923 | ioa_cfg->ipr_cmnd_list[i], | 9151 | dma_pool_free(ioa_cfg->ipr_cmd_pool, |
8924 | ioa_cfg->ipr_cmnd_list_dma[i]); | 9152 | ioa_cfg->ipr_cmnd_list[i], |
9153 | ioa_cfg->ipr_cmnd_list_dma[i]); | ||
8925 | 9154 | ||
8926 | ioa_cfg->ipr_cmnd_list[i] = NULL; | 9155 | ioa_cfg->ipr_cmnd_list[i] = NULL; |
9156 | } | ||
8927 | } | 9157 | } |
8928 | 9158 | ||
8929 | if (ioa_cfg->ipr_cmd_pool) | 9159 | if (ioa_cfg->ipr_cmd_pool) |
@@ -8973,26 +9203,25 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg) | |||
8973 | } | 9203 | } |
8974 | 9204 | ||
8975 | /** | 9205 | /** |
8976 | * ipr_free_all_resources - Free all allocated resources for an adapter. | 9206 | * ipr_free_irqs - Free all allocated IRQs for the adapter. |
8977 | * @ipr_cmd: ipr command struct | 9207 | * @ioa_cfg: ipr cfg struct |
8978 | * | 9208 | * |
8979 | * This function frees all allocated resources for the | 9209 | * This function frees all allocated IRQs for the |
8980 | * specified adapter. | 9210 | * specified adapter. |
8981 | * | 9211 | * |
8982 | * Return value: | 9212 | * Return value: |
8983 | * none | 9213 | * none |
8984 | **/ | 9214 | **/ |
8985 | static void ipr_free_all_resources(struct ipr_ioa_cfg *ioa_cfg) | 9215 | static void ipr_free_irqs(struct ipr_ioa_cfg *ioa_cfg) |
8986 | { | 9216 | { |
8987 | struct pci_dev *pdev = ioa_cfg->pdev; | 9217 | struct pci_dev *pdev = ioa_cfg->pdev; |
8988 | 9218 | ||
8989 | ENTER; | ||
8990 | if (ioa_cfg->intr_flag == IPR_USE_MSI || | 9219 | if (ioa_cfg->intr_flag == IPR_USE_MSI || |
8991 | ioa_cfg->intr_flag == IPR_USE_MSIX) { | 9220 | ioa_cfg->intr_flag == IPR_USE_MSIX) { |
8992 | int i; | 9221 | int i; |
8993 | for (i = 0; i < ioa_cfg->nvectors; i++) | 9222 | for (i = 0; i < ioa_cfg->nvectors; i++) |
8994 | free_irq(ioa_cfg->vectors_info[i].vec, | 9223 | free_irq(ioa_cfg->vectors_info[i].vec, |
8995 | &ioa_cfg->hrrq[i]); | 9224 | &ioa_cfg->hrrq[i]); |
8996 | } else | 9225 | } else |
8997 | free_irq(pdev->irq, &ioa_cfg->hrrq[0]); | 9226 | free_irq(pdev->irq, &ioa_cfg->hrrq[0]); |
8998 | 9227 | ||
@@ -9003,7 +9232,26 @@ static void ipr_free_all_resources(struct ipr_ioa_cfg *ioa_cfg) | |||
9003 | pci_disable_msix(pdev); | 9232 | pci_disable_msix(pdev); |
9004 | ioa_cfg->intr_flag &= ~IPR_USE_MSIX; | 9233 | ioa_cfg->intr_flag &= ~IPR_USE_MSIX; |
9005 | } | 9234 | } |
9235 | } | ||
9006 | 9236 | ||
9237 | /** | ||
9238 | * ipr_free_all_resources - Free all allocated resources for an adapter. | ||
9239 | * @ipr_cmd: ipr command struct | ||
9240 | * | ||
9241 | * This function frees all allocated resources for the | ||
9242 | * specified adapter. | ||
9243 | * | ||
9244 | * Return value: | ||
9245 | * none | ||
9246 | **/ | ||
9247 | static void ipr_free_all_resources(struct ipr_ioa_cfg *ioa_cfg) | ||
9248 | { | ||
9249 | struct pci_dev *pdev = ioa_cfg->pdev; | ||
9250 | |||
9251 | ENTER; | ||
9252 | ipr_free_irqs(ioa_cfg); | ||
9253 | if (ioa_cfg->reset_work_q) | ||
9254 | destroy_workqueue(ioa_cfg->reset_work_q); | ||
9007 | iounmap(ioa_cfg->hdw_dma_regs); | 9255 | iounmap(ioa_cfg->hdw_dma_regs); |
9008 | pci_release_regions(pdev); | 9256 | pci_release_regions(pdev); |
9009 | ipr_free_mem(ioa_cfg); | 9257 | ipr_free_mem(ioa_cfg); |
@@ -9823,6 +10071,14 @@ static int ipr_probe_ioa(struct pci_dev *pdev, | |||
9823 | (dev_id->device == PCI_DEVICE_ID_IBM_OBSIDIAN_E && !ioa_cfg->revid)) { | 10071 | (dev_id->device == PCI_DEVICE_ID_IBM_OBSIDIAN_E && !ioa_cfg->revid)) { |
9824 | ioa_cfg->needs_warm_reset = 1; | 10072 | ioa_cfg->needs_warm_reset = 1; |
9825 | ioa_cfg->reset = ipr_reset_slot_reset; | 10073 | ioa_cfg->reset = ipr_reset_slot_reset; |
10074 | |||
10075 | ioa_cfg->reset_work_q = alloc_ordered_workqueue("ipr_reset_%d", | ||
10076 | WQ_MEM_RECLAIM, host->host_no); | ||
10077 | |||
10078 | if (!ioa_cfg->reset_work_q) { | ||
10079 | dev_err(&pdev->dev, "Couldn't register reset workqueue\n"); | ||
10080 | goto out_free_irq; | ||
10081 | } | ||
9826 | } else | 10082 | } else |
9827 | ioa_cfg->reset = ipr_reset_start_bist; | 10083 | ioa_cfg->reset = ipr_reset_start_bist; |
9828 | 10084 | ||
@@ -9834,6 +10090,8 @@ static int ipr_probe_ioa(struct pci_dev *pdev, | |||
9834 | out: | 10090 | out: |
9835 | return rc; | 10091 | return rc; |
9836 | 10092 | ||
10093 | out_free_irq: | ||
10094 | ipr_free_irqs(ioa_cfg); | ||
9837 | cleanup_nolog: | 10095 | cleanup_nolog: |
9838 | ipr_free_mem(ioa_cfg); | 10096 | ipr_free_mem(ioa_cfg); |
9839 | out_msi_disable: | 10097 | out_msi_disable: |
@@ -9914,6 +10172,8 @@ static void __ipr_remove(struct pci_dev *pdev) | |||
9914 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); | 10172 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); |
9915 | wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); | 10173 | wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); |
9916 | flush_work(&ioa_cfg->work_q); | 10174 | flush_work(&ioa_cfg->work_q); |
10175 | if (ioa_cfg->reset_work_q) | ||
10176 | flush_workqueue(ioa_cfg->reset_work_q); | ||
9917 | INIT_LIST_HEAD(&ioa_cfg->used_res_q); | 10177 | INIT_LIST_HEAD(&ioa_cfg->used_res_q); |
9918 | spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); | 10178 | spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); |
9919 | 10179 | ||
@@ -10036,6 +10296,7 @@ static void ipr_shutdown(struct pci_dev *pdev) | |||
10036 | { | 10296 | { |
10037 | struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); | 10297 | struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); |
10038 | unsigned long lock_flags = 0; | 10298 | unsigned long lock_flags = 0; |
10299 | enum ipr_shutdown_type shutdown_type = IPR_SHUTDOWN_NORMAL; | ||
10039 | int i; | 10300 | int i; |
10040 | 10301 | ||
10041 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | 10302 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); |
@@ -10051,9 +10312,16 @@ static void ipr_shutdown(struct pci_dev *pdev) | |||
10051 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | 10312 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); |
10052 | } | 10313 | } |
10053 | 10314 | ||
10054 | ipr_initiate_ioa_bringdown(ioa_cfg, IPR_SHUTDOWN_NORMAL); | 10315 | if (ipr_fast_reboot && system_state == SYSTEM_RESTART && ioa_cfg->sis64) |
10316 | shutdown_type = IPR_SHUTDOWN_QUIESCE; | ||
10317 | |||
10318 | ipr_initiate_ioa_bringdown(ioa_cfg, shutdown_type); | ||
10055 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 10319 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
10056 | wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); | 10320 | wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); |
10321 | if (ipr_fast_reboot && system_state == SYSTEM_RESTART && ioa_cfg->sis64) { | ||
10322 | ipr_free_irqs(ioa_cfg); | ||
10323 | pci_disable_device(ioa_cfg->pdev); | ||
10324 | } | ||
10057 | } | 10325 | } |
10058 | 10326 | ||
10059 | static struct pci_device_id ipr_pci_table[] = { | 10327 | static struct pci_device_id ipr_pci_table[] = { |
@@ -10211,7 +10479,8 @@ static int ipr_halt(struct notifier_block *nb, ulong event, void *buf) | |||
10211 | 10479 | ||
10212 | list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) { | 10480 | list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) { |
10213 | spin_lock_irqsave(ioa_cfg->host->host_lock, flags); | 10481 | spin_lock_irqsave(ioa_cfg->host->host_lock, flags); |
10214 | if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) { | 10482 | if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds || |
10483 | (ipr_fast_reboot && event == SYS_RESTART && ioa_cfg->sis64)) { | ||
10215 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); | 10484 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); |
10216 | continue; | 10485 | continue; |
10217 | } | 10486 | } |