LCOV - code coverage report
Current view: top level - drivers/pci/hotplug - cpci_hotplug_pci.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 121 0.0 %
Date: 2022-04-01 14:58:12 Functions: 0 10 0.0 %
Branches: 0 86 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0+
       2                 :            : /*
       3                 :            :  * CompactPCI Hot Plug Driver PCI functions
       4                 :            :  *
       5                 :            :  * Copyright (C) 2002,2005 by SOMA Networks, Inc.
       6                 :            :  *
       7                 :            :  * All rights reserved.
       8                 :            :  *
       9                 :            :  * Send feedback to <scottm@somanetworks.com>
      10                 :            :  */
      11                 :            : 
      12                 :            : #include <linux/module.h>
      13                 :            : #include <linux/kernel.h>
      14                 :            : #include <linux/pci.h>
      15                 :            : #include <linux/pci_hotplug.h>
      16                 :            : #include <linux/proc_fs.h>
      17                 :            : #include "../pci.h"
      18                 :            : #include "cpci_hotplug.h"
      19                 :            : 
      20                 :            : #define MY_NAME "cpci_hotplug"
      21                 :            : 
      22                 :            : extern int cpci_debug;
      23                 :            : 
      24                 :            : #define dbg(format, arg...)                                     \
      25                 :            :         do {                                                    \
      26                 :            :                 if (cpci_debug)                                 \
      27                 :            :                         printk(KERN_DEBUG "%s: " format "\n",       \
      28                 :            :                                 MY_NAME, ## arg);               \
      29                 :            :         } while (0)
      30                 :            : #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME, ## arg)
      31                 :            : #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME, ## arg)
      32                 :            : #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME, ## arg)
      33                 :            : 
      34                 :            : 
      35                 :          0 : u8 cpci_get_attention_status(struct slot *slot)
      36                 :            : {
      37                 :          0 :         int hs_cap;
      38                 :          0 :         u16 hs_csr;
      39                 :            : 
      40                 :          0 :         hs_cap = pci_bus_find_capability(slot->bus,
      41                 :            :                                          slot->devfn,
      42                 :            :                                          PCI_CAP_ID_CHSWP);
      43         [ #  # ]:          0 :         if (!hs_cap)
      44                 :            :                 return 0;
      45                 :            : 
      46         [ #  # ]:          0 :         if (pci_bus_read_config_word(slot->bus,
      47                 :            :                                      slot->devfn,
      48                 :            :                                      hs_cap + 2,
      49                 :            :                                      &hs_csr))
      50                 :            :                 return 0;
      51                 :            : 
      52                 :          0 :         return hs_csr & 0x0008 ? 1 : 0;
      53                 :            : }
      54                 :            : 
      55                 :          0 : int cpci_set_attention_status(struct slot *slot, int status)
      56                 :            : {
      57                 :          0 :         int hs_cap;
      58                 :          0 :         u16 hs_csr;
      59                 :            : 
      60                 :          0 :         hs_cap = pci_bus_find_capability(slot->bus,
      61                 :            :                                          slot->devfn,
      62                 :            :                                          PCI_CAP_ID_CHSWP);
      63         [ #  # ]:          0 :         if (!hs_cap)
      64                 :            :                 return 0;
      65         [ #  # ]:          0 :         if (pci_bus_read_config_word(slot->bus,
      66                 :            :                                      slot->devfn,
      67                 :            :                                      hs_cap + 2,
      68                 :            :                                      &hs_csr))
      69                 :            :                 return 0;
      70         [ #  # ]:          0 :         if (status)
      71                 :          0 :                 hs_csr |= HS_CSR_LOO;
      72                 :            :         else
      73                 :          0 :                 hs_csr &= ~HS_CSR_LOO;
      74         [ #  # ]:          0 :         if (pci_bus_write_config_word(slot->bus,
      75                 :            :                                       slot->devfn,
      76                 :            :                                       hs_cap + 2,
      77                 :            :                                       hs_csr))
      78                 :          0 :                 return 0;
      79                 :            :         return 1;
      80                 :            : }
      81                 :            : 
      82                 :          0 : u16 cpci_get_hs_csr(struct slot *slot)
      83                 :            : {
      84                 :          0 :         int hs_cap;
      85                 :          0 :         u16 hs_csr;
      86                 :            : 
      87                 :          0 :         hs_cap = pci_bus_find_capability(slot->bus,
      88                 :            :                                          slot->devfn,
      89                 :            :                                          PCI_CAP_ID_CHSWP);
      90         [ #  # ]:          0 :         if (!hs_cap)
      91                 :            :                 return 0xFFFF;
      92         [ #  # ]:          0 :         if (pci_bus_read_config_word(slot->bus,
      93                 :            :                                      slot->devfn,
      94                 :            :                                      hs_cap + 2,
      95                 :            :                                      &hs_csr))
      96                 :            :                 return 0xFFFF;
      97                 :          0 :         return hs_csr;
      98                 :            : }
      99                 :            : 
     100                 :          0 : int cpci_check_and_clear_ins(struct slot *slot)
     101                 :            : {
     102                 :          0 :         int hs_cap;
     103                 :          0 :         u16 hs_csr;
     104                 :          0 :         int ins = 0;
     105                 :            : 
     106                 :          0 :         hs_cap = pci_bus_find_capability(slot->bus,
     107                 :            :                                          slot->devfn,
     108                 :            :                                          PCI_CAP_ID_CHSWP);
     109         [ #  # ]:          0 :         if (!hs_cap)
     110                 :            :                 return 0;
     111         [ #  # ]:          0 :         if (pci_bus_read_config_word(slot->bus,
     112                 :            :                                      slot->devfn,
     113                 :            :                                      hs_cap + 2,
     114                 :            :                                      &hs_csr))
     115                 :            :                 return 0;
     116         [ #  # ]:          0 :         if (hs_csr & HS_CSR_INS) {
     117                 :            :                 /* Clear INS (by setting it) */
     118         [ #  # ]:          0 :                 if (pci_bus_write_config_word(slot->bus,
     119                 :            :                                               slot->devfn,
     120                 :            :                                               hs_cap + 2,
     121                 :            :                                               hs_csr))
     122                 :            :                         ins = 0;
     123                 :            :                 else
     124                 :          0 :                         ins = 1;
     125                 :            :         }
     126                 :            :         return ins;
     127                 :            : }
     128                 :            : 
     129                 :          0 : int cpci_check_ext(struct slot *slot)
     130                 :            : {
     131                 :          0 :         int hs_cap;
     132                 :          0 :         u16 hs_csr;
     133                 :          0 :         int ext = 0;
     134                 :            : 
     135                 :          0 :         hs_cap = pci_bus_find_capability(slot->bus,
     136                 :            :                                          slot->devfn,
     137                 :            :                                          PCI_CAP_ID_CHSWP);
     138         [ #  # ]:          0 :         if (!hs_cap)
     139                 :            :                 return 0;
     140         [ #  # ]:          0 :         if (pci_bus_read_config_word(slot->bus,
     141                 :            :                                      slot->devfn,
     142                 :            :                                      hs_cap + 2,
     143                 :            :                                      &hs_csr))
     144                 :            :                 return 0;
     145         [ #  # ]:          0 :         if (hs_csr & HS_CSR_EXT)
     146                 :          0 :                 ext = 1;
     147                 :            :         return ext;
     148                 :            : }
     149                 :            : 
     150                 :          0 : int cpci_clear_ext(struct slot *slot)
     151                 :            : {
     152                 :          0 :         int hs_cap;
     153                 :          0 :         u16 hs_csr;
     154                 :            : 
     155                 :          0 :         hs_cap = pci_bus_find_capability(slot->bus,
     156                 :            :                                          slot->devfn,
     157                 :            :                                          PCI_CAP_ID_CHSWP);
     158         [ #  # ]:          0 :         if (!hs_cap)
     159                 :            :                 return -ENODEV;
     160         [ #  # ]:          0 :         if (pci_bus_read_config_word(slot->bus,
     161                 :            :                                      slot->devfn,
     162                 :            :                                      hs_cap + 2,
     163                 :            :                                      &hs_csr))
     164                 :            :                 return -ENODEV;
     165         [ #  # ]:          0 :         if (hs_csr & HS_CSR_EXT) {
     166                 :            :                 /* Clear EXT (by setting it) */
     167         [ #  # ]:          0 :                 if (pci_bus_write_config_word(slot->bus,
     168                 :            :                                               slot->devfn,
     169                 :            :                                               hs_cap + 2,
     170                 :            :                                               hs_csr))
     171                 :          0 :                         return -ENODEV;
     172                 :            :         }
     173                 :            :         return 0;
     174                 :            : }
     175                 :            : 
     176                 :          0 : int cpci_led_on(struct slot *slot)
     177                 :            : {
     178                 :          0 :         int hs_cap;
     179                 :          0 :         u16 hs_csr;
     180                 :            : 
     181                 :          0 :         hs_cap = pci_bus_find_capability(slot->bus,
     182                 :            :                                          slot->devfn,
     183                 :            :                                          PCI_CAP_ID_CHSWP);
     184         [ #  # ]:          0 :         if (!hs_cap)
     185                 :            :                 return -ENODEV;
     186         [ #  # ]:          0 :         if (pci_bus_read_config_word(slot->bus,
     187                 :            :                                      slot->devfn,
     188                 :            :                                      hs_cap + 2,
     189                 :            :                                      &hs_csr))
     190                 :            :                 return -ENODEV;
     191         [ #  # ]:          0 :         if ((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) {
     192                 :          0 :                 hs_csr |= HS_CSR_LOO;
     193         [ #  # ]:          0 :                 if (pci_bus_write_config_word(slot->bus,
     194                 :            :                                               slot->devfn,
     195                 :            :                                               hs_cap + 2,
     196                 :            :                                               hs_csr)) {
     197                 :          0 :                         err("Could not set LOO for slot %s", slot_name(slot));
     198                 :          0 :                         return -ENODEV;
     199                 :            :                 }
     200                 :            :         }
     201                 :            :         return 0;
     202                 :            : }
     203                 :            : 
     204                 :          0 : int cpci_led_off(struct slot *slot)
     205                 :            : {
     206                 :          0 :         int hs_cap;
     207                 :          0 :         u16 hs_csr;
     208                 :            : 
     209                 :          0 :         hs_cap = pci_bus_find_capability(slot->bus,
     210                 :            :                                          slot->devfn,
     211                 :            :                                          PCI_CAP_ID_CHSWP);
     212         [ #  # ]:          0 :         if (!hs_cap)
     213                 :            :                 return -ENODEV;
     214         [ #  # ]:          0 :         if (pci_bus_read_config_word(slot->bus,
     215                 :            :                                      slot->devfn,
     216                 :            :                                      hs_cap + 2,
     217                 :            :                                      &hs_csr))
     218                 :            :                 return -ENODEV;
     219         [ #  # ]:          0 :         if (hs_csr & HS_CSR_LOO) {
     220                 :          0 :                 hs_csr &= ~HS_CSR_LOO;
     221         [ #  # ]:          0 :                 if (pci_bus_write_config_word(slot->bus,
     222                 :            :                                               slot->devfn,
     223                 :            :                                               hs_cap + 2,
     224                 :            :                                               hs_csr)) {
     225                 :          0 :                         err("Could not clear LOO for slot %s", slot_name(slot));
     226                 :          0 :                         return -ENODEV;
     227                 :            :                 }
     228                 :            :         }
     229                 :            :         return 0;
     230                 :            : }
     231                 :            : 
     232                 :            : 
     233                 :            : /*
     234                 :            :  * Device configuration functions
     235                 :            :  */
     236                 :            : 
     237                 :          0 : int cpci_configure_slot(struct slot *slot)
     238                 :            : {
     239                 :          0 :         struct pci_dev *dev;
     240                 :          0 :         struct pci_bus *parent;
     241                 :          0 :         int ret = 0;
     242                 :            : 
     243         [ #  # ]:          0 :         dbg("%s - enter", __func__);
     244                 :            : 
     245                 :          0 :         pci_lock_rescan_remove();
     246                 :            : 
     247         [ #  # ]:          0 :         if (slot->dev == NULL) {
     248         [ #  # ]:          0 :                 dbg("pci_dev null, finding %02x:%02x:%x",
     249                 :            :                     slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn));
     250                 :          0 :                 slot->dev = pci_get_slot(slot->bus, slot->devfn);
     251                 :            :         }
     252                 :            : 
     253                 :            :         /* Still NULL? Well then scan for it! */
     254         [ #  # ]:          0 :         if (slot->dev == NULL) {
     255                 :          0 :                 int n;
     256         [ #  # ]:          0 :                 dbg("pci_dev still null");
     257                 :            : 
     258                 :            :                 /*
     259                 :            :                  * This will generate pci_dev structures for all functions, but
     260                 :            :                  * we will only call this case when lookup fails.
     261                 :            :                  */
     262                 :          0 :                 n = pci_scan_slot(slot->bus, slot->devfn);
     263         [ #  # ]:          0 :                 dbg("%s: pci_scan_slot returned %d", __func__, n);
     264                 :          0 :                 slot->dev = pci_get_slot(slot->bus, slot->devfn);
     265         [ #  # ]:          0 :                 if (slot->dev == NULL) {
     266                 :          0 :                         err("Could not find PCI device for slot %02x", slot->number);
     267                 :          0 :                         ret = -ENODEV;
     268                 :          0 :                         goto out;
     269                 :            :                 }
     270                 :            :         }
     271                 :          0 :         parent = slot->dev->bus;
     272                 :            : 
     273   [ #  #  #  # ]:          0 :         for_each_pci_bridge(dev, parent) {
     274         [ #  # ]:          0 :                 if (PCI_SLOT(dev->devfn) == PCI_SLOT(slot->devfn))
     275                 :          0 :                         pci_hp_add_bridge(dev);
     276                 :            :         }
     277                 :            : 
     278                 :          0 :         pci_assign_unassigned_bridge_resources(parent->self);
     279                 :            : 
     280                 :          0 :         pci_bus_add_devices(parent);
     281                 :            : 
     282                 :          0 :  out:
     283                 :          0 :         pci_unlock_rescan_remove();
     284         [ #  # ]:          0 :         dbg("%s - exit", __func__);
     285                 :          0 :         return ret;
     286                 :            : }
     287                 :            : 
     288                 :          0 : int cpci_unconfigure_slot(struct slot *slot)
     289                 :            : {
     290                 :          0 :         struct pci_dev *dev, *temp;
     291                 :            : 
     292         [ #  # ]:          0 :         dbg("%s - enter", __func__);
     293         [ #  # ]:          0 :         if (!slot->dev) {
     294                 :          0 :                 err("No device for slot %02x\n", slot->number);
     295                 :          0 :                 return -ENODEV;
     296                 :            :         }
     297                 :            : 
     298                 :          0 :         pci_lock_rescan_remove();
     299                 :            : 
     300         [ #  # ]:          0 :         list_for_each_entry_safe(dev, temp, &slot->bus->devices, bus_list) {
     301         [ #  # ]:          0 :                 if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn))
     302                 :          0 :                         continue;
     303                 :          0 :                 pci_dev_get(dev);
     304                 :          0 :                 pci_stop_and_remove_bus_device(dev);
     305                 :          0 :                 pci_dev_put(dev);
     306                 :            :         }
     307                 :          0 :         pci_dev_put(slot->dev);
     308                 :          0 :         slot->dev = NULL;
     309                 :            : 
     310                 :          0 :         pci_unlock_rescan_remove();
     311                 :            : 
     312         [ #  # ]:          0 :         dbg("%s - exit", __func__);
     313                 :            :         return 0;
     314                 :            : }

Generated by: LCOV version 1.14