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 'ata-6.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux

Pull ata fixes from Damien Le Moal:

- Fix the type of return values to be signed in the ahci_xgen driver
(Qianfeng)

- Add the mask_port_ext module parameter to the ahci driver.

This is to allow a user to ignore ports that are advertized as
external (hotplug capable) in favor of lower link power management
policies instead of the default max_performance for these ports.

This is useful to allow e.g. laptops to go into low power states when
hooked up to docking station with sata slots, connected with an
external port for hotplug (me)

* tag 'ata-6.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux:
ata: ahci_xgene: Use int type for 'rc' to store error codes
ata: ahci: Allow ignoring the external/hotplug capability of ports

+43 -22
+40 -17
drivers/ata/ahci.c
··· 689 689 "where <pci_dev> is the PCI ID of an AHCI controller in the " 690 690 "form \"domain:bus:dev.func\""); 691 691 692 - static void ahci_apply_port_map_mask(struct device *dev, 693 - struct ahci_host_priv *hpriv, char *mask_s) 692 + static char *ahci_mask_port_ext; 693 + module_param_named(mask_port_ext, ahci_mask_port_ext, charp, 0444); 694 + MODULE_PARM_DESC(mask_port_ext, 695 + "32-bits mask to ignore the external/hotplug capability of ports. " 696 + "Valid values are: " 697 + "\"<mask>\" to apply the same mask to all AHCI controller " 698 + "devices, and \"<pci_dev>=<mask>,<pci_dev>=<mask>,...\" to " 699 + "specify different masks for the controllers specified, " 700 + "where <pci_dev> is the PCI ID of an AHCI controller in the " 701 + "form \"domain:bus:dev.func\""); 702 + 703 + static u32 ahci_port_mask(struct device *dev, char *mask_s) 694 704 { 695 705 unsigned int mask; 696 706 697 707 if (kstrtouint(mask_s, 0, &mask)) { 698 708 dev_err(dev, "Invalid port map mask\n"); 699 - return; 709 + return 0; 700 710 } 701 711 702 - hpriv->mask_port_map = mask; 712 + return mask; 703 713 } 704 714 705 - static void ahci_get_port_map_mask(struct device *dev, 706 - struct ahci_host_priv *hpriv) 715 + static u32 ahci_get_port_mask(struct device *dev, char *mask_p) 707 716 { 708 717 char *param, *end, *str, *mask_s; 709 718 char *name; 719 + u32 mask = 0; 710 720 711 - if (!strlen(ahci_mask_port_map)) 712 - return; 721 + if (!mask_p || !strlen(mask_p)) 722 + return 0; 713 723 714 - str = kstrdup(ahci_mask_port_map, GFP_KERNEL); 724 + str = kstrdup(mask_p, GFP_KERNEL); 715 725 if (!str) 716 - return; 726 + return 0; 717 727 718 728 /* Handle single mask case */ 719 729 if (!strchr(str, '=')) { 720 - ahci_apply_port_map_mask(dev, hpriv, str); 730 + mask = ahci_port_mask(dev, str); 721 731 goto free; 722 732 } 723 733 724 734 /* 725 - * Mask list case: parse the parameter to apply the mask only if 735 + * Mask list case: parse the parameter to get the mask only if 726 736 * the device name matches. 727 737 */ 728 738 param = str; ··· 762 752 param++; 763 753 } 764 754 765 - ahci_apply_port_map_mask(dev, hpriv, mask_s); 755 + mask = ahci_port_mask(dev, mask_s); 766 756 } 767 757 768 758 free: 769 759 kfree(str); 760 + 761 + return mask; 770 762 } 771 763 772 764 static void ahci_pci_save_initial_config(struct pci_dev *pdev, ··· 794 782 } 795 783 796 784 /* Handle port map masks passed as module parameter. */ 797 - if (ahci_mask_port_map) 798 - ahci_get_port_map_mask(&pdev->dev, hpriv); 785 + hpriv->mask_port_map = 786 + ahci_get_port_mask(&pdev->dev, ahci_mask_port_map); 787 + hpriv->mask_port_ext = 788 + ahci_get_port_mask(&pdev->dev, ahci_mask_port_ext); 799 789 800 790 ahci_save_initial_config(&pdev->dev, hpriv); 801 791 } ··· 1771 1757 void __iomem *port_mmio = ahci_port_base(ap); 1772 1758 u32 tmp; 1773 1759 1774 - /* mark external ports (hotplug-capable, eSATA) */ 1760 + /* 1761 + * Mark external ports (hotplug-capable, eSATA), unless we were asked to 1762 + * ignore this feature. 1763 + */ 1775 1764 tmp = readl(port_mmio + PORT_CMD); 1776 1765 if (((tmp & PORT_CMD_ESP) && (hpriv->cap & HOST_CAP_SXS)) || 1777 - (tmp & PORT_CMD_HPCP)) 1766 + (tmp & PORT_CMD_HPCP)) { 1767 + if (hpriv->mask_port_ext & (1U << ap->port_no)) { 1768 + ata_port_info(ap, 1769 + "Ignoring external/hotplug capability\n"); 1770 + return; 1771 + } 1778 1772 ap->pflags |= ATA_PFLAG_EXTERNAL; 1773 + } 1779 1774 } 1780 1775 1781 1776 static void ahci_update_initial_lpm_policy(struct ata_port *ap)
+1
drivers/ata/ahci.h
··· 330 330 /* Input fields */ 331 331 unsigned int flags; /* AHCI_HFLAG_* */ 332 332 u32 mask_port_map; /* Mask of valid ports */ 333 + u32 mask_port_ext; /* Mask of ports ext capability */ 333 334 334 335 void __iomem * mmio; /* bus-independent mem map */ 335 336 u32 cap; /* cap to use */
+2 -5
drivers/ata/ahci_xgene.c
··· 450 450 { 451 451 int pmp = sata_srst_pmp(link); 452 452 struct ata_port *ap = link->ap; 453 - u32 rc; 454 453 void __iomem *port_mmio = ahci_port_base(ap); 455 454 u32 port_fbs; 456 455 ··· 462 463 port_fbs |= pmp << PORT_FBS_DEV_OFFSET; 463 464 writel(port_fbs, port_mmio + PORT_FBS); 464 465 465 - rc = ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready); 466 - 467 - return rc; 466 + return ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready); 468 467 } 469 468 470 469 /** ··· 497 500 u32 port_fbs; 498 501 u32 port_fbs_save; 499 502 u32 retry = 1; 500 - u32 rc; 503 + int rc; 501 504 502 505 port_fbs_save = readl(port_mmio + PORT_FBS); 503 506