1. 07 12月, 2022 1 次提交
    • A
      ata: libahci_platform: ahci_platform_find_clk: oops, NULL pointer · d95d140e
      Anders Roxell 提交于
      When booting a arm 32-bit kernel with config CONFIG_AHCI_DWC enabled on
      a am57xx-evm board. This happens when the clock references are unnamed
      in DT, the strcmp() produces a NULL pointer dereference, see the
      following oops, NULL pointer dereference:
      
      [    4.673950] Unable to handle kernel NULL pointer dereference at virtual address 00000000
      [    4.682098] [00000000] *pgd=00000000
      [    4.685699] Internal error: Oops: 5 [#1] SMP ARM
      [    4.690338] Modules linked in:
      [    4.693420] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.1.0-rc7 #1
      [    4.699615] Hardware name: Generic DRA74X (Flattened Device Tree)
      [    4.705749] PC is at strcmp+0x0/0x34
      [    4.709350] LR is at ahci_platform_find_clk+0x3c/0x5c
      [    4.714416] pc : [<c130c494>]    lr : [<c0c230e0>]    psr: 20000013
      [    4.720703] sp : f000dda8  ip : 00000001  fp : c29b1840
      [    4.725952] r10: 00000020  r9 : c1b23380  r8 : c1b23368
      [    4.731201] r7 : c1ab4cc4  r6 : 00000001  r5 : c3c66040  r4 : 00000000
      [    4.737762] r3 : 00000080  r2 : 00000080  r1 : c1ab4cc4  r0 : 00000000
      [...]
      [    4.998870]  strcmp from ahci_platform_find_clk+0x3c/0x5c
      [    5.004302]  ahci_platform_find_clk from ahci_dwc_probe+0x1f0/0x54c
      [    5.010589]  ahci_dwc_probe from platform_probe+0x64/0xc0
      [    5.016021]  platform_probe from really_probe+0xe8/0x41c
      [    5.021362]  really_probe from __driver_probe_device+0xa4/0x204
      [    5.027313]  __driver_probe_device from driver_probe_device+0x38/0xc8
      [    5.033782]  driver_probe_device from __driver_attach+0xb4/0x1ec
      [    5.039825]  __driver_attach from bus_for_each_dev+0x78/0xb8
      [    5.045532]  bus_for_each_dev from bus_add_driver+0x17c/0x220
      [    5.051300]  bus_add_driver from driver_register+0x90/0x124
      [    5.056915]  driver_register from do_one_initcall+0x48/0x1e8
      [    5.062591]  do_one_initcall from kernel_init_freeable+0x1cc/0x234
      [    5.068817]  kernel_init_freeable from kernel_init+0x20/0x13c
      [    5.074584]  kernel_init from ret_from_fork+0x14/0x2c
      [    5.079681] Exception stack(0xf000dfb0 to 0xf000dff8)
      [    5.084747] dfa0:                                     00000000 00000000 00000000 00000000
      [    5.092956] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      [    5.101165] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000
      [    5.107818] Code: e5e32001 e3520000 1afffffb e12fff1e (e4d03001)
      [    5.114013] ---[ end trace 0000000000000000 ]---
      
      Add an extra check in the if-statement if hpriv-clks[i].id.
      
      Fixes: 6ce73f3a ("ata: libahci_platform: Add function returning a clock-handle by id")
      Suggested-by: NArnd Bergmann <arnd@arndb.de>
      Signed-off-by: NAnders Roxell <anders.roxell@linaro.org>
      Reviewed-by: NSerge Semin <fancer.lancer@gmail.com>
      Signed-off-by: NDamien Le Moal <damien.lemoal@opensource.wdc.com>
      d95d140e
  2. 17 9月, 2022 8 次提交
    • S
      ata: libahci_platform: Add function returning a clock-handle by id · 6ce73f3a
      Serge Semin 提交于
      Since all the clocks are retrieved by the method
      ahci_platform_get_resources() there is no need for the LLD (glue) drivers
      to be looking for some particular of them in the kernel clocks table
      again. Instead we suggest to add a simple method returning a
      device-specific clock with passed connection ID if it is managed to be
      found. Otherwise the function will return NULL. Thus the glue-drivers
      won't need to either manually touching the hpriv->clks array or calling
      clk_get()-friends. The AHCI platform drivers will be able to use the new
      function right after the ahci_platform_get_resources() method invocation
      and up to the device removal.
      
      Note the method is left unused here, but will be utilized in the framework
      of the DWC AHCI SATA driver being added in the next commit.
      Signed-off-by: NSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Signed-off-by: NDamien Le Moal <damien.lemoal@opensource.wdc.com>
      6ce73f3a
    • S
      ata: ahci: Introduce firmware-specific caps initialization · 18ee7c49
      Serge Semin 提交于
      There are systems with no BIOS or comprehensive embedded firmware which
      could be able to properly initialize the SATA AHCI controller
      platform-specific capabilities. In that case a good alternative to having
      a clever bootloader is to create a device tree node with the properties
      well describing all the AHCI-related platform specifics. All the settings
      which are normally detected and marked as available in the HBA and its
      ports capabilities fields [1] could be defined in the platform DTB by
      means of a set of the dedicated properties. Such approach perfectly fits
      to the DTB-philosophy - to provide hardware/platform description.
      
      So here we suggest to extend the SATA AHCI device tree bindings with two
      additional DT-properties:
      1) "hba-cap" - HBA platform generic capabilities like:
         - SSS - Staggered Spin-up support.
         - SMPS - Mechanical Presence Switch support.
      2) "hba-port-cap" - HBA platform port capabilities like:
         - HPCP - Hot Plug Capable Port.
         - MPSP - Mechanical Presence Switch Attached to Port.
         - CPD - Cold Presence Detection.
         - ESP - External SATA Port.
         - FBSCP - FIS-based Switching Capable Port.
      All of these capabilities require to have a corresponding hardware
      configuration. Thus it's ok to have them defined in DTB.
      
      Even though the driver currently takes into account the state of the ESP
      and FBSCP flags state only, there is nothing wrong with having all of them
      supported by the generic AHCI library in order to have a complete OF-based
      platform-capabilities initialization procedure. These properties will be
      parsed in the ahci_platform_get_resources() method and their values will
      be stored in the saved_* fields of the ahci_host_priv structure, which in
      its turn then will be used to restore the H.CAP, H.PI and P#.CMD
      capability fields on device init and after HBA reset.
      
      Please note this modification concerns the HW-init HBA and its ports flags
      only, which are by specification [1] are supposed to be initialized by the
      BIOS/platform firmware/expansion ROM and which are normally declared in
      the one-time-writable-after-reset register fields. Even though these flags
      aren't supposed to be cleared after HBA reset some AHCI instances may
      violate that rule so we still need to perform the fields resetting after
      each reset. Luckily the corresponding functionality has already been
      partly implemented in the framework of the ahci_save_initial_config() and
      ahci_restore_initial_config() methods.
      
      [1] Serial ATA AHCI 1.3.1 Specification, p. 103
      Signed-off-by: NSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Signed-off-by: NDamien Le Moal <damien.lemoal@opensource.wdc.com>
      18ee7c49
    • S
      ata: libahci: Discard redundant force_port_map parameter · 88589772
      Serge Semin 提交于
      Currently there are four port-map-related fields declared in the
      ahci_host_priv structure and used to setup the HBA ports mapping. First
      the ports-mapping is read from the PI register and immediately stored in
      the saved_port_map field. If forced_port_map is initialized with non-zero
      value then its value will have greater priority over the value read from
      PI, thus it will override the saved_port_map field. That value will be
      then masked by a non-zero mask_port_map field and after some sanity checks
      it will be stored in the ahci_host_priv.port_map field as a final port
      mapping.
      
      As you can see the logic is a bit too complicated for such a simple task.
      We can freely get rid from at least one of the fields with no change to
      the implemented semantic. The force_port_map field can be replaced with
      taking non-zero saved_port_map value into account. So if saved_port_map is
      pre-initialized by the low level drivers (platform drivers) then it will
      have greater priority over the value read from PI register and will be
      used as actual HBA ports mapping later on. Thus the ports map forcing task
      will be just transferred from force_port_map to the saved_port_map field.
      
      This modification will perfectly fit into the feature of having OF-based
      initialization of the HW-init HBA CSR fields we are about to introduce in
      the next commit.
      Signed-off-by: NSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NDamien Le Moal <damien.lemoal@opensource.wdc.com>
      88589772
    • S
      ata: libahci_platform: Introduce reset assertion/deassertion methods · f67f12ff
      Serge Semin 提交于
      Currently the ACHI-platform library supports only the assert and deassert
      reset signals and ignores the platforms with self-deasserting reset lines.
      That prone to having the platforms with self-deasserting reset method
      misbehaviour when it comes to resuming from sleep state after the clocks
      have been fully disabled. For such cases the controller needs to be fully
      reset all over after the reference clocks are enabled and stable,
      otherwise the controller state machine might be in an undetermined state.
      
      The best solution would be to auto-detect which reset method is supported
      by the particular platform and use it implicitly in the framework of the
      ahci_platform_enable_resources()/ahci_platform_disable_resources()
      methods. Alas it can't be implemented due to the AHCI-platform library
      already supporting the shared reset control lines. As [1] says in such
      case we have to use only one of the next methods:
      + reset_control_assert()/reset_control_deassert();
      + reset_control_reset()/reset_control_rearm().
      If the driver had an exclusive control over the reset lines we could have
      been able to manipulate the lines with no much limitation and just used
      the combination of the methods above to cover all the possible
      reset-control cases. Since the shared reset control has already been
      advertised and couldn't be changed with no risk to breaking the platforms
      relying on it, we have no choice but to make the platform drivers to
      determine which reset methods the platform reset system supports.
      
      In order to implement both types of reset control support we suggest to
      introduce the new AHCI-platform flag: AHCI_PLATFORM_RST_TRIGGER, which
      when passed to the ahci_platform_get_resources() method together with the
      AHCI_PLATFORM_GET_RESETS flag will indicate that the reset lines are
      self-deasserting thus the reset_control_reset()/reset_control_rearm() will
      be used to control the reset state. Otherwise the
      reset_control_deassert()/reset_control_assert() methods will be utilized.
      
      [1] Documentation/driver-api/reset.rst
      Signed-off-by: NSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NDamien Le Moal <damien.lemoal@opensource.wdc.com>
      f67f12ff
    • S
      ata: libahci_platform: Parse ports-implemented property in resources getter · 3f74cd04
      Serge Semin 提交于
      The ports-implemented property is mainly used on the OF-based platforms
      with no ports mapping initialized by a bootloader/BIOS firmware. Seeing
      the same of_property_read_u32()-based pattern has already been implemented
      in the generic AHCI LLDD (glue) driver and in the Mediatek, St AHCI
      drivers let's move the property read procedure to the generic
      ahci_platform_get_resources() method. Thus we'll have the forced ports
      mapping feature supported for each OF-based platform which requires that,
      and stop re-implementing the same pattern in there a bit simplifying the
      code.
      Signed-off-by: NSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Signed-off-by: NDamien Le Moal <damien.lemoal@opensource.wdc.com>
      3f74cd04
    • S
      ata: libahci_platform: Sanity check the DT child nodes number · 3c132ea6
      Serge Semin 提交于
      Having greater than AHCI_MAX_PORTS (32) ports detected isn't that critical
      from the further AHCI-platform initialization point of view since
      exceeding the ports upper limit will cause allocating more resources than
      will be used afterwards. But detecting too many child DT-nodes doesn't
      seem right since it's very unlikely to have it on an ordinary platform. In
      accordance with the AHCI specification there can't be more than 32 ports
      implemented at least due to having the CAP.NP field of 5 bits wide and the
      PI register of dword size. Thus if such situation is found the DTB must
      have been corrupted and the data read from it shouldn't be reliable. Let's
      consider that as an erroneous situation and halt further resources
      allocation.
      
      Note it's logically more correct to have the nports set only after the
      initialization value is checked for being sane. So while at it let's make
      sure nports is assigned with a correct value.
      Signed-off-by: NSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NDamien Le Moal <damien.lemoal@opensource.wdc.com>
      3c132ea6
    • S
      ata: libahci_platform: Convert to using devm bulk clocks API · e28b3abf
      Serge Semin 提交于
      In order to simplify the clock-related code there is a way to convert the
      current fixed clocks array into using the common bulk clocks kernel API
      with dynamic set of the clock handlers and device-managed clock-resource
      tracking. It's a bit tricky due to the complication coming from the
      requirement to support the platforms (da850, spear13xx) with the
      non-OF-based clock source, but still doable.
      
      Before this modification there are two methods have been used to get the
      clocks connected to an AHCI device: clk_get() - to get the very first
      clock in the list and of_clk_get() - to get the rest of them. Basically
      the platforms with non-OF-based clocks definition could specify only a
      single reference clock source. The platforms with OF-hw clocks have been
      luckier and could setup up to AHCI_MAX_CLKS clocks. Such semantic can be
      retained with using devm_clk_bulk_get_all() to retrieve the clocks defined
      via the DT firmware and devm_clk_get_optional() otherwise. In both cases
      using the device-managed version of the methods will cause the automatic
      resources deallocation on the AHCI device removal event. The only
      complicated part in the suggested approach is the explicit allocation and
      initialization of the clk_bulk_data structure instance for the non-OF
      reference clocks. It's required in order to use the Bulk Clocks API for
      the both denoted cases of the clocks definition.
      
      Note aside with the clock-related code reduction and natural
      simplification, there are several bonuses the suggested modification
      provides. First of all the limitation of having no greater than
      AHCI_MAX_CLKS clocks is now removed, since the devm_clk_bulk_get_all()
      method will allocate as many reference clocks data descriptors as there
      are clocks specified for the device. Secondly the clock names are
      auto-detected. So the LLDD (glue) drivers can make sure that the required
      clocks are specified just by checking the clock IDs in the clk_bulk_data
      array.  Thirdly using the handy Bulk Clocks kernel API improves the
      clocks-handling code readability. And the last but not least this
      modification implements a true optional clocks support to the
      ahci_platform_get_resources() method. Indeed the previous clocks getting
      procedure just stopped getting the clocks on any errors (aside from
      non-critical -EPROBE_DEFER) in a way so the callee wasn't even informed
      about abnormal loop termination. The new implementation lacks of such
      problem. The ahci_platform_get_resources() will return an error code if
      the corresponding clocks getting method ends execution abnormally.
      Signed-off-by: NSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NDamien Le Moal <damien.lemoal@opensource.wdc.com>
      e28b3abf
    • S
      ata: libahci_platform: Convert to using platform devm-ioremap methods · 82d437e6
      Serge Semin 提交于
      Currently the IOMEM AHCI registers space is mapped by means of the
      two functions invocation: platform_get_resource() is used to get the very
      first memory resource and devm_ioremap_resource() is called to remap that
      resource. Device-managed kernel API provides a handy wrapper to perform
      the same in single function call: devm_platform_ioremap_resource().
      
      While at it seeing many AHCI platform drivers rely on having the AHCI CSR
      space marked with "ahci" name let's first try to find and remap the CSR
      IO-mem with that name and only if it fails fallback to getting the very
      first registers space platform resource.
      Signed-off-by: NSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NDamien Le Moal <damien.lemoal@opensource.wdc.com>
      82d437e6
  3. 25 2月, 2022 1 次提交
  4. 19 2月, 2022 1 次提交
  5. 04 1月, 2022 2 次提交
  6. 14 10月, 2021 1 次提交
    • W
      ata: ahci_platform: fix null-ptr-deref in ahci_platform_enable_regulators() · 776c7501
      Wang Hai 提交于
      I got a null-ptr-deref report:
      
      KASAN: null-ptr-deref in range [0x0000000000000090-0x0000000000000097]
      ...
      RIP: 0010:regulator_enable+0x84/0x260
      ...
      Call Trace:
       ahci_platform_enable_regulators+0xae/0x320
       ahci_platform_enable_resources+0x1a/0x120
       ahci_probe+0x4f/0x1b9
       platform_probe+0x10b/0x280
      ...
       entry_SYSCALL_64_after_hwframe+0x44/0xae
      
      If devm_regulator_get() in ahci_platform_get_resources() fails,
      hpriv->phy_regulator will point to NULL, when enabling or disabling it,
      null-ptr-deref will occur.
      
      ahci_probe()
      	ahci_platform_get_resources()
      		devm_regulator_get(, "phy") // failed, let phy_regulator = NULL
      	ahci_platform_enable_resources()
      		ahci_platform_enable_regulators()
      			regulator_enable(hpriv->phy_regulator) // null-ptr-deref
      
      commit 962399bb ("ata: libahci_platform: Fix regulator_get_optional()
      misuse") replaces devm_regulator_get_optional() with devm_regulator_get(),
      but PHY regulator omits to delete "hpriv->phy_regulator = NULL;" like AHCI.
      Delete it like AHCI regulator to fix this bug.
      
      Fixes: commit 962399bb ("ata: libahci_platform: Fix regulator_get_optional() misuse")
      Reported-by: NHulk Robot <hulkci@huawei.com>
      Signed-off-by: NWang Hai <wanghai38@huawei.com>
      Reviewed-by: NHans de Goede <hdegoede@redhat.com>
      Signed-off-by: NDamien Le Moal <damien.lemoal@wdc.com>
      776c7501
  7. 31 3月, 2021 1 次提交
  8. 10 10月, 2020 1 次提交
    • P
      ata: ahci: mvebu: Make SATA PHY optional for Armada 3720 · 45aefe3d
      Pali Rohár 提交于
      Older ATF does not provide SMC call for SATA phy power on functionality and
      therefore initialization of ahci_mvebu is failing when older version of ATF
      is using. In this case phy_power_on() function returns -EOPNOTSUPP.
      
      This patch adds a new hflag AHCI_HFLAG_IGN_NOTSUPP_POWER_ON which cause
      that ahci_platform_enable_phys() would ignore -EOPNOTSUPP errors from
      phy_power_on() call.
      
      It fixes initialization of ahci_mvebu on Espressobin boards where is older
      Marvell's Arm Trusted Firmware without SMC call for SATA phy power.
      
      This is regression introduced in commit 8e18c8e5 ("arm64: dts: marvell:
      armada-3720-espressobin: declare SATA PHY property") where SATA phy was
      defined and therefore ahci_platform_enable_phys() on Espressobin started
      failing.
      
      Fixes: 8e18c8e5 ("arm64: dts: marvell: armada-3720-espressobin: declare SATA PHY property")
      Signed-off-by: NPali Rohár <pali@kernel.org>
      Tested-by: NTomasz Maciej Nowak <tmn505@gmail.com>
      Cc: <stable@vger.kernel.org> # 5.1+: ea17a0f1: phy: marvell: comphy: Convert internal SMCC firmware return codes to errno
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      45aefe3d
  9. 24 8月, 2020 1 次提交
  10. 26 12月, 2019 1 次提交
  11. 26 10月, 2019 1 次提交
    • M
      ata: libahci_platform: Fix regulator_get_optional() misuse · 962399bb
      Mark Brown 提交于
      This driver is using regulator_get_optional() to handle all the supplies
      that it handles, and only ever enables and disables all supplies en masse
      without ever doing any other configuration of the device to handle missing
      power. These are clear signs that the API is being misused - it should only
      be used for supplies that may be physically absent from the system and in
      these cases the hardware usually needs different configuration if the
      supply is missing. Instead use normal regualtor_get(), if the supply is
      not described in DT then the framework will substitute a dummy regulator in
      so no special handling is needed by the consumer driver.
      
      In the case of the PHY regulator the handling in the driver is a hack to
      deal with integrated PHYs; the supplies are only optional in the sense
      that that there's some confusion in the code about where they're bound to.
      From a code point of view they function exactly as normal supplies so can
      be treated as such. It'd probably be better to model this by instantiating
      a PHY object for integrated PHYs.
      Reviewed-by: NHans de Goede <hdegoede@redhat.com>
      Signed-off-by: NMark Brown <broonie@kernel.org>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      962399bb
  12. 20 9月, 2019 1 次提交
  13. 31 7月, 2019 1 次提交
  14. 16 7月, 2019 1 次提交
  15. 24 5月, 2019 1 次提交
  16. 12 1月, 2019 1 次提交
  17. 03 9月, 2018 2 次提交
  18. 28 8月, 2018 1 次提交
  19. 22 8月, 2018 2 次提交
  20. 07 8月, 2018 1 次提交
  21. 25 7月, 2018 1 次提交
  22. 13 7月, 2018 3 次提交
  23. 19 6月, 2018 1 次提交
  24. 10 4月, 2018 1 次提交
  25. 26 3月, 2018 1 次提交
  26. 13 2月, 2018 1 次提交
  27. 23 10月, 2017 1 次提交
  28. 05 8月, 2017 1 次提交