aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/wd719x.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-11 18:14:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-11 18:14:01 -0400
commitba6d10ab8014ac10d25ca513352b6665e73b5785 (patch)
tree3b7aaa3f2d76d0c0e9612bc87e1da45577465528 /drivers/scsi/wd719x.c
parent64b08df460cfdfc2b010263043a057cdd33500ed (diff)
parentbaf23eddbf2a4ba9bf2bdb342686c71a8042e39b (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 mostly update of the usual drivers: qla2xxx, hpsa, lpfc, ufs, mpt3sas, ibmvscsi, megaraid_sas, bnx2fc and hisi_sas as well as the removal of the osst driver (I heard from Willem privately that he would like the driver removed because all his test hardware has failed). Plus number of minor changes, spelling fixes and other trivia. The big merge conflict this time around is the SPDX licence tags. Following discussion on linux-next, we believe our version to be more accurate than the one in the tree, so the resolution is to take our version for all the SPDX conflicts" Note on the SPDX license tag conversion conflicts: the SCSI tree had done its own SPDX conversion, which in some cases conflicted with the treewide ones done by Thomas & co. In almost all cases, the conflicts were purely syntactic: the SCSI tree used the old-style SPDX tags ("GPL-2.0" and "GPL-2.0+") while the treewide conversion had used the new-style ones ("GPL-2.0-only" and "GPL-2.0-or-later"). In these cases I picked the new-style one. In a few cases, the SPDX conversion was actually different, though. As explained by James above, and in more detail in a pre-pull-request thread: "The other problem is actually substantive: In the libsas code Luben Tuikov originally specified gpl 2.0 only by dint of stating: * This file is licensed under GPLv2. In all the libsas files, but then muddied the water by quoting GPLv2 verbatim (which includes the or later than language). So for these files Christoph did the conversion to v2 only SPDX tags and Thomas converted to v2 or later tags" So in those cases, where the spdx tag substantially mattered, I took the SCSI tree conversion of it, but then also took the opportunity to turn the old-style "GPL-2.0" into a new-style "GPL-2.0-only" tag. Similarly, when there were whitespace differences or other differences to the comments around the copyright notices, I took the version from the SCSI tree as being the more specific conversion. Finally, in the spdx conversions that had no conflicts (because the treewide ones hadn't been done for those files), I just took the SCSI tree version as-is, even if it was old-style. The old-style conversions are perfectly valid, even if the "-only" and "-or-later" versions are perhaps more descriptive. * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (185 commits) scsi: qla2xxx: move IO flush to the front of NVME rport unregistration scsi: qla2xxx: Fix NVME cmd and LS cmd timeout race condition scsi: qla2xxx: on session delete, return nvme cmd scsi: qla2xxx: Fix kernel crash after disconnecting NVMe devices scsi: megaraid_sas: Update driver version to 07.710.06.00-rc1 scsi: megaraid_sas: Introduce various Aero performance modes scsi: megaraid_sas: Use high IOPS queues based on IO workload scsi: megaraid_sas: Set affinity for high IOPS reply queues scsi: megaraid_sas: Enable coalescing for high IOPS queues scsi: megaraid_sas: Add support for High IOPS queues scsi: megaraid_sas: Add support for MPI toolbox commands scsi: megaraid_sas: Offload Aero RAID5/6 division calculations to driver scsi: megaraid_sas: RAID1 PCI bandwidth limit algorithm is applicable for only Ventura scsi: megaraid_sas: megaraid_sas: Add check for count returned by HOST_DEVICE_LIST DCMD scsi: megaraid_sas: Handle sequence JBOD map failure at driver level scsi: megaraid_sas: Don't send FPIO to RL Bypass queue scsi: megaraid_sas: In probe context, retry IOC INIT once if firmware is in fault scsi: megaraid_sas: Release Mutex lock before OCR in case of DCMD timeout scsi: megaraid_sas: Call disable_irq from process IRQ poll scsi: megaraid_sas: Remove few debug counters from IO path ...
Diffstat (limited to 'drivers/scsi/wd719x.c')
-rw-r--r--drivers/scsi/wd719x.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/drivers/scsi/wd719x.c b/drivers/scsi/wd719x.c
index c2f40068f235..edc8a139a60d 100644
--- a/drivers/scsi/wd719x.c
+++ b/drivers/scsi/wd719x.c
@@ -108,8 +108,15 @@ static inline int wd719x_wait_done(struct wd719x *wd, int timeout)
108 } 108 }
109 109
110 if (status != WD719X_INT_NOERRORS) { 110 if (status != WD719X_INT_NOERRORS) {
111 u8 sue = wd719x_readb(wd, WD719X_AMR_SCB_ERROR);
112 /* we get this after wd719x_dev_reset, it's not an error */
113 if (sue == WD719X_SUE_TERM)
114 return 0;
115 /* we get this after wd719x_bus_reset, it's not an error */
116 if (sue == WD719X_SUE_RESET)
117 return 0;
111 dev_err(&wd->pdev->dev, "direct command failed, status 0x%02x, SUE 0x%02x\n", 118 dev_err(&wd->pdev->dev, "direct command failed, status 0x%02x, SUE 0x%02x\n",
112 status, wd719x_readb(wd, WD719X_AMR_SCB_ERROR)); 119 status, sue);
113 return -EIO; 120 return -EIO;
114 } 121 }
115 122
@@ -128,8 +135,10 @@ static int wd719x_direct_cmd(struct wd719x *wd, u8 opcode, u8 dev, u8 lun,
128 if (wd719x_wait_ready(wd)) 135 if (wd719x_wait_ready(wd))
129 return -ETIMEDOUT; 136 return -ETIMEDOUT;
130 137
131 /* make sure we get NO interrupts */ 138 /* disable interrupts except for RESET/ABORT (it breaks them) */
132 dev |= WD719X_DISABLE_INT; 139 if (opcode != WD719X_CMD_BUSRESET && opcode != WD719X_CMD_ABORT &&
140 opcode != WD719X_CMD_ABORT_TAG && opcode != WD719X_CMD_RESET)
141 dev |= WD719X_DISABLE_INT;
133 wd719x_writeb(wd, WD719X_AMR_CMD_PARAM, dev); 142 wd719x_writeb(wd, WD719X_AMR_CMD_PARAM, dev);
134 wd719x_writeb(wd, WD719X_AMR_CMD_PARAM_2, lun); 143 wd719x_writeb(wd, WD719X_AMR_CMD_PARAM_2, lun);
135 wd719x_writeb(wd, WD719X_AMR_CMD_PARAM_3, tag); 144 wd719x_writeb(wd, WD719X_AMR_CMD_PARAM_3, tag);
@@ -465,6 +474,7 @@ static int wd719x_abort(struct scsi_cmnd *cmd)
465 spin_lock_irqsave(wd->sh->host_lock, flags); 474 spin_lock_irqsave(wd->sh->host_lock, flags);
466 result = wd719x_direct_cmd(wd, action, cmd->device->id, 475 result = wd719x_direct_cmd(wd, action, cmd->device->id,
467 cmd->device->lun, cmd->tag, scb->phys, 0); 476 cmd->device->lun, cmd->tag, scb->phys, 0);
477 wd719x_finish_cmd(scb, DID_ABORT);
468 spin_unlock_irqrestore(wd->sh->host_lock, flags); 478 spin_unlock_irqrestore(wd->sh->host_lock, flags);
469 if (result) 479 if (result)
470 return FAILED; 480 return FAILED;
@@ -477,6 +487,7 @@ static int wd719x_reset(struct scsi_cmnd *cmd, u8 opcode, u8 device)
477 int result; 487 int result;
478 unsigned long flags; 488 unsigned long flags;
479 struct wd719x *wd = shost_priv(cmd->device->host); 489 struct wd719x *wd = shost_priv(cmd->device->host);
490 struct wd719x_scb *scb, *tmp;
480 491
481 dev_info(&wd->pdev->dev, "%s reset requested\n", 492 dev_info(&wd->pdev->dev, "%s reset requested\n",
482 (opcode == WD719X_CMD_BUSRESET) ? "bus" : "device"); 493 (opcode == WD719X_CMD_BUSRESET) ? "bus" : "device");
@@ -484,6 +495,12 @@ static int wd719x_reset(struct scsi_cmnd *cmd, u8 opcode, u8 device)
484 spin_lock_irqsave(wd->sh->host_lock, flags); 495 spin_lock_irqsave(wd->sh->host_lock, flags);
485 result = wd719x_direct_cmd(wd, opcode, device, 0, 0, 0, 496 result = wd719x_direct_cmd(wd, opcode, device, 0, 0, 0,
486 WD719X_WAIT_FOR_SCSI_RESET); 497 WD719X_WAIT_FOR_SCSI_RESET);
498 /* flush all SCBs (or all for a device if dev_reset) */
499 list_for_each_entry_safe(scb, tmp, &wd->active_scbs, list) {
500 if (opcode == WD719X_CMD_BUSRESET ||
501 scb->cmd->device->id == device)
502 wd719x_finish_cmd(scb, DID_RESET);
503 }
487 spin_unlock_irqrestore(wd->sh->host_lock, flags); 504 spin_unlock_irqrestore(wd->sh->host_lock, flags);
488 if (result) 505 if (result)
489 return FAILED; 506 return FAILED;
@@ -506,22 +523,23 @@ static int wd719x_host_reset(struct scsi_cmnd *cmd)
506 struct wd719x *wd = shost_priv(cmd->device->host); 523 struct wd719x *wd = shost_priv(cmd->device->host);
507 struct wd719x_scb *scb, *tmp; 524 struct wd719x_scb *scb, *tmp;
508 unsigned long flags; 525 unsigned long flags;
509 int result;
510 526
511 dev_info(&wd->pdev->dev, "host reset requested\n"); 527 dev_info(&wd->pdev->dev, "host reset requested\n");
512 spin_lock_irqsave(wd->sh->host_lock, flags); 528 spin_lock_irqsave(wd->sh->host_lock, flags);
513 /* Try to reinit the RISC */ 529 /* stop the RISC */
514 if (wd719x_chip_init(wd) == 0) 530 if (wd719x_direct_cmd(wd, WD719X_CMD_SLEEP, 0, 0, 0, 0,
515 result = SUCCESS; 531 WD719X_WAIT_FOR_RISC))
516 else 532 dev_warn(&wd->pdev->dev, "RISC sleep command failed\n");
517 result = FAILED; 533 /* disable RISC */
534 wd719x_writeb(wd, WD719X_PCI_MODE_SELECT, 0);
518 535
519 /* flush all SCBs */ 536 /* flush all SCBs */
520 list_for_each_entry_safe(scb, tmp, &wd->active_scbs, list) 537 list_for_each_entry_safe(scb, tmp, &wd->active_scbs, list)
521 wd719x_finish_cmd(scb, result); 538 wd719x_finish_cmd(scb, DID_RESET);
522 spin_unlock_irqrestore(wd->sh->host_lock, flags); 539 spin_unlock_irqrestore(wd->sh->host_lock, flags);
523 540
524 return result; 541 /* Try to reinit the RISC */
542 return wd719x_chip_init(wd) == 0 ? SUCCESS : FAILED;
525} 543}
526 544
527static int wd719x_biosparam(struct scsi_device *sdev, struct block_device *bdev, 545static int wd719x_biosparam(struct scsi_device *sdev, struct block_device *bdev,
@@ -673,7 +691,7 @@ static irqreturn_t wd719x_interrupt(int irq, void *dev_id)
673 else 691 else
674 dev_err(&wd->pdev->dev, "card returned invalid SCB pointer\n"); 692 dev_err(&wd->pdev->dev, "card returned invalid SCB pointer\n");
675 } else 693 } else
676 dev_warn(&wd->pdev->dev, "direct command 0x%x completed\n", 694 dev_dbg(&wd->pdev->dev, "direct command 0x%x completed\n",
677 regs.bytes.OPC); 695 regs.bytes.OPC);
678 break; 696 break;
679 case WD719X_INT_PIOREADY: 697 case WD719X_INT_PIOREADY: