Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI fixes from James Bottomley:
"Fixes all in drivers. The largest is the mpi3mr which corrects a phy
count limit that should only apply to the controller but was being
incorrectly applied to expander phys"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
scsi: target: core: Fix null-ptr-deref in target_alloc_device()
scsi: mpi3mr: Validate SAS port assignments
scsi: ufs: core: Set SDEV_OFFLINE when UFS is shut down
scsi: ufs: core: Requeue aborted request
scsi: ufs: core: Fix the issue of ICU failure

+45 -42
+2 -2
drivers/scsi/mpi3mr/mpi3mr.h
··· 542 542 * @port_list: List of ports belonging to a SAS node 543 543 * @num_phys: Number of phys associated with port 544 544 * @marked_responding: used while refresing the sas ports 545 - * @lowest_phy: lowest phy ID of current sas port 546 - * @phy_mask: phy_mask of current sas port 545 + * @lowest_phy: lowest phy ID of current sas port, valid for controller port 546 + * @phy_mask: phy_mask of current sas port, valid for controller port 547 547 * @hba_port: HBA port entry 548 548 * @remote_identify: Attached device identification 549 549 * @rphy: SAS transport layer rphy object
+27 -15
drivers/scsi/mpi3mr/mpi3mr_transport.c
··· 590 590 * @mrioc: Adapter instance reference 591 591 * @mr_sas_port: Internal Port object 592 592 * @mr_sas_phy: Internal Phy object 593 + * @host_node: Flag to indicate this is a host_node 593 594 * 594 595 * Return: None. 595 596 */ 596 597 static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc, 597 598 struct mpi3mr_sas_port *mr_sas_port, 598 - struct mpi3mr_sas_phy *mr_sas_phy) 599 + struct mpi3mr_sas_phy *mr_sas_phy, u8 host_node) 599 600 { 600 601 u64 sas_address = mr_sas_port->remote_identify.sas_address; 601 602 ··· 606 605 607 606 list_del(&mr_sas_phy->port_siblings); 608 607 mr_sas_port->num_phys--; 609 - mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id); 610 - if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id) 611 - mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; 608 + 609 + if (host_node) { 610 + mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id); 611 + 612 + if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id) 613 + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; 614 + } 612 615 sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy); 613 616 mr_sas_phy->phy_belongs_to_port = 0; 614 617 } ··· 622 617 * @mrioc: Adapter instance reference 623 618 * @mr_sas_port: Internal Port object 624 619 * @mr_sas_phy: Internal Phy object 620 + * @host_node: Flag to indicate this is a host_node 625 621 * 626 622 * Return: None. 627 623 */ 628 624 static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc, 629 625 struct mpi3mr_sas_port *mr_sas_port, 630 - struct mpi3mr_sas_phy *mr_sas_phy) 626 + struct mpi3mr_sas_phy *mr_sas_phy, u8 host_node) 631 627 { 632 628 u64 sas_address = mr_sas_port->remote_identify.sas_address; 633 629 ··· 638 632 639 633 list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list); 640 634 mr_sas_port->num_phys++; 641 - mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); 642 - if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy) 643 - mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; 635 + if (host_node) { 636 + mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); 637 + 638 + if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy) 639 + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; 640 + } 644 641 sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy); 645 642 mr_sas_phy->phy_belongs_to_port = 1; 646 643 } ··· 684 675 if (srch_phy == mr_sas_phy) 685 676 return; 686 677 } 687 - mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy); 678 + mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy, mr_sas_node->host_node); 688 679 return; 689 680 } 690 681 } ··· 745 736 mpi3mr_delete_sas_port(mrioc, mr_sas_port); 746 737 else 747 738 mpi3mr_delete_sas_phy(mrioc, mr_sas_port, 748 - mr_sas_phy); 739 + mr_sas_phy, mr_sas_node->host_node); 749 740 return; 750 741 } 751 742 } ··· 1037 1028 /** 1038 1029 * mpi3mr_get_hba_port_by_id - find hba port by id 1039 1030 * @mrioc: Adapter instance reference 1040 - * @port_id - Port ID to search 1031 + * @port_id: Port ID to search 1041 1032 * 1042 1033 * Return: mpi3mr_hba_port reference for the matched port 1043 1034 */ ··· 1376 1367 mpi3mr_sas_port_sanity_check(mrioc, mr_sas_node, 1377 1368 mr_sas_port->remote_identify.sas_address, hba_port); 1378 1369 1379 - if (mr_sas_node->num_phys >= sizeof(mr_sas_port->phy_mask) * 8) 1370 + if (mr_sas_node->host_node && mr_sas_node->num_phys >= 1371 + sizeof(mr_sas_port->phy_mask) * 8) 1380 1372 ioc_info(mrioc, "max port count %u could be too high\n", 1381 1373 mr_sas_node->num_phys); 1382 1374 ··· 1387 1377 (mr_sas_node->phy[i].hba_port != hba_port)) 1388 1378 continue; 1389 1379 1390 - if (i >= sizeof(mr_sas_port->phy_mask) * 8) { 1380 + if (mr_sas_node->host_node && (i >= sizeof(mr_sas_port->phy_mask) * 8)) { 1391 1381 ioc_warn(mrioc, "skipping port %u, max allowed value is %zu\n", 1392 1382 i, sizeof(mr_sas_port->phy_mask) * 8); 1393 1383 goto out_fail; ··· 1395 1385 list_add_tail(&mr_sas_node->phy[i].port_siblings, 1396 1386 &mr_sas_port->phy_list); 1397 1387 mr_sas_port->num_phys++; 1398 - mr_sas_port->phy_mask |= (1 << i); 1388 + if (mr_sas_node->host_node) 1389 + mr_sas_port->phy_mask |= (1 << i); 1399 1390 } 1400 1391 1401 1392 if (!mr_sas_port->num_phys) { ··· 1405 1394 goto out_fail; 1406 1395 } 1407 1396 1408 - mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; 1397 + if (mr_sas_node->host_node) 1398 + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; 1409 1399 1410 1400 if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { 1411 1401 tgtdev = mpi3mr_get_tgtdev_by_addr(mrioc,
+1 -1
drivers/target/target_core_device.c
··· 691 691 692 692 dev->queues = kcalloc(nr_cpu_ids, sizeof(*dev->queues), GFP_KERNEL); 693 693 if (!dev->queues) { 694 - dev->transport->free_device(dev); 694 + hba->backend->ops->free_device(dev); 695 695 return NULL; 696 696 } 697 697
+8 -7
drivers/ufs/core/ufs-mcq.c
··· 539 539 struct scsi_cmnd *cmd = lrbp->cmd; 540 540 struct ufs_hw_queue *hwq; 541 541 void __iomem *reg, *opr_sqd_base; 542 - u32 nexus, id, val; 542 + u32 nexus, id, val, rtc; 543 543 int err; 544 544 545 545 if (hba->quirks & UFSHCD_QUIRK_MCQ_BROKEN_RTC) ··· 569 569 opr_sqd_base = mcq_opr_base(hba, OPR_SQD, id); 570 570 writel(nexus, opr_sqd_base + REG_SQCTI); 571 571 572 - /* SQRTCy.ICU = 1 */ 573 - writel(SQ_ICU, opr_sqd_base + REG_SQRTC); 572 + /* Initiate Cleanup */ 573 + writel(readl(opr_sqd_base + REG_SQRTC) | SQ_ICU, 574 + opr_sqd_base + REG_SQRTC); 574 575 575 576 /* Poll SQRTSy.CUS = 1. Return result from SQRTSy.RTC */ 576 577 reg = opr_sqd_base + REG_SQRTS; 577 578 err = read_poll_timeout(readl, val, val & SQ_CUS, 20, 578 579 MCQ_POLL_US, false, reg); 579 - if (err) 580 - dev_err(hba->dev, "%s: failed. hwq=%d, tag=%d err=%ld\n", 581 - __func__, id, task_tag, 582 - FIELD_GET(SQ_ICU_ERR_CODE_MASK, readl(reg))); 580 + rtc = FIELD_GET(SQ_ICU_ERR_CODE_MASK, readl(reg)); 581 + if (err || rtc) 582 + dev_err(hba->dev, "%s: failed. hwq=%d, tag=%d err=%d RTC=%d\n", 583 + __func__, id, task_tag, err, rtc); 583 584 584 585 if (ufshcd_mcq_sq_start(hba, hwq)) 585 586 err = -ETIMEDOUT;
+7 -17
drivers/ufs/core/ufshcd.c
··· 5416 5416 } 5417 5417 break; 5418 5418 case OCS_ABORTED: 5419 - result |= DID_ABORT << 16; 5420 - break; 5421 5419 case OCS_INVALID_COMMAND_STATUS: 5422 5420 result |= DID_REQUEUE << 16; 5421 + dev_warn(hba->dev, 5422 + "OCS %s from controller for tag %d\n", 5423 + (ocs == OCS_ABORTED ? "aborted" : "invalid"), 5424 + lrbp->task_tag); 5423 5425 break; 5424 5426 case OCS_INVALID_CMD_TABLE_ATTR: 5425 5427 case OCS_INVALID_PRDT_ATTR: ··· 6467 6465 struct scsi_device *sdev = cmd->device; 6468 6466 struct Scsi_Host *shost = sdev->host; 6469 6467 struct ufs_hba *hba = shost_priv(shost); 6470 - struct ufshcd_lrb *lrbp = &hba->lrb[tag]; 6471 - struct ufs_hw_queue *hwq; 6472 - unsigned long flags; 6473 6468 6474 6469 *ret = ufshcd_try_to_abort_task(hba, tag); 6475 6470 dev_err(hba->dev, "Aborting tag %d / CDB %#02x %s\n", tag, 6476 6471 hba->lrb[tag].cmd ? hba->lrb[tag].cmd->cmnd[0] : -1, 6477 6472 *ret ? "failed" : "succeeded"); 6478 - 6479 - /* Release cmd in MCQ mode if abort succeeds */ 6480 - if (hba->mcq_enabled && (*ret == 0)) { 6481 - hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(lrbp->cmd)); 6482 - if (!hwq) 6483 - return 0; 6484 - spin_lock_irqsave(&hwq->cq_lock, flags); 6485 - if (ufshcd_cmd_inflight(lrbp->cmd)) 6486 - ufshcd_release_scsi_cmd(hba, lrbp); 6487 - spin_unlock_irqrestore(&hwq->cq_lock, flags); 6488 - } 6489 6473 6490 6474 return *ret == 0; 6491 6475 } ··· 10197 10209 shost_for_each_device(sdev, hba->host) { 10198 10210 if (sdev == hba->ufs_device_wlun) 10199 10211 continue; 10200 - scsi_device_quiesce(sdev); 10212 + mutex_lock(&sdev->state_mutex); 10213 + scsi_device_set_state(sdev, SDEV_OFFLINE); 10214 + mutex_unlock(&sdev->state_mutex); 10201 10215 } 10202 10216 __ufshcd_wl_suspend(hba, UFS_SHUTDOWN_PM); 10203 10217