LCOV - code coverage report
Current view: top level - drivers/base - transport_class.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 0 69 0.0 %
Date: 2021-04-22 12:43:58 Functions: 0 15 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * transport_class.c - implementation of generic transport classes
       4             :  *                     using attribute_containers
       5             :  *
       6             :  * Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com>
       7             :  *
       8             :  * The basic idea here is to allow any "device controller" (which
       9             :  * would most often be a Host Bus Adapter to use the services of one
      10             :  * or more tranport classes for performing transport specific
      11             :  * services.  Transport specific services are things that the generic
      12             :  * command layer doesn't want to know about (speed settings, line
      13             :  * condidtioning, etc), but which the user might be interested in.
      14             :  * Thus, the HBA's use the routines exported by the transport classes
      15             :  * to perform these functions.  The transport classes export certain
      16             :  * values to the user via sysfs using attribute containers.
      17             :  *
      18             :  * Note: because not every HBA will care about every transport
      19             :  * attribute, there's a many to one relationship that goes like this:
      20             :  *
      21             :  * transport class<-----attribute container<----class device
      22             :  *
      23             :  * Usually the attribute container is per-HBA, but the design doesn't
      24             :  * mandate that.  Although most of the services will be specific to
      25             :  * the actual external storage connection used by the HBA, the generic
      26             :  * transport class is framed entirely in terms of generic devices to
      27             :  * allow it to be used by any physical HBA in the system.
      28             :  */
      29             : #include <linux/export.h>
      30             : #include <linux/attribute_container.h>
      31             : #include <linux/transport_class.h>
      32             : 
      33             : static int transport_remove_classdev(struct attribute_container *cont,
      34             :                                      struct device *dev,
      35             :                                      struct device *classdev);
      36             : 
      37             : /**
      38             :  * transport_class_register - register an initial transport class
      39             :  *
      40             :  * @tclass:     a pointer to the transport class structure to be initialised
      41             :  *
      42             :  * The transport class contains an embedded class which is used to
      43             :  * identify it.  The caller should initialise this structure with
      44             :  * zeros and then generic class must have been initialised with the
      45             :  * actual transport class unique name.  There's a macro
      46             :  * DECLARE_TRANSPORT_CLASS() to do this (declared classes still must
      47             :  * be registered).
      48             :  *
      49             :  * Returns 0 on success or error on failure.
      50             :  */
      51           0 : int transport_class_register(struct transport_class *tclass)
      52             : {
      53           0 :         return class_register(&tclass->class);
      54             : }
      55             : EXPORT_SYMBOL_GPL(transport_class_register);
      56             : 
      57             : /**
      58             :  * transport_class_unregister - unregister a previously registered class
      59             :  *
      60             :  * @tclass: The transport class to unregister
      61             :  *
      62             :  * Must be called prior to deallocating the memory for the transport
      63             :  * class.
      64             :  */
      65           0 : void transport_class_unregister(struct transport_class *tclass)
      66             : {
      67           0 :         class_unregister(&tclass->class);
      68           0 : }
      69             : EXPORT_SYMBOL_GPL(transport_class_unregister);
      70             : 
      71           0 : static int anon_transport_dummy_function(struct transport_container *tc,
      72             :                                          struct device *dev,
      73             :                                          struct device *cdev)
      74             : {
      75             :         /* do nothing */
      76           0 :         return 0;
      77             : }
      78             : 
      79             : /**
      80             :  * anon_transport_class_register - register an anonymous class
      81             :  *
      82             :  * @atc: The anon transport class to register
      83             :  *
      84             :  * The anonymous transport class contains both a transport class and a
      85             :  * container.  The idea of an anonymous class is that it never
      86             :  * actually has any device attributes associated with it (and thus
      87             :  * saves on container storage).  So it can only be used for triggering
      88             :  * events.  Use prezero and then use DECLARE_ANON_TRANSPORT_CLASS() to
      89             :  * initialise the anon transport class storage.
      90             :  */
      91           0 : int anon_transport_class_register(struct anon_transport_class *atc)
      92             : {
      93           0 :         int error;
      94           0 :         atc->container.class = &atc->tclass.class;
      95           0 :         attribute_container_set_no_classdevs(&atc->container);
      96           0 :         error = attribute_container_register(&atc->container);
      97           0 :         if (error)
      98             :                 return error;
      99           0 :         atc->tclass.setup = anon_transport_dummy_function;
     100           0 :         atc->tclass.remove = anon_transport_dummy_function;
     101           0 :         return 0;
     102             : }
     103             : EXPORT_SYMBOL_GPL(anon_transport_class_register);
     104             : 
     105             : /**
     106             :  * anon_transport_class_unregister - unregister an anon class
     107             :  *
     108             :  * @atc: Pointer to the anon transport class to unregister
     109             :  *
     110             :  * Must be called prior to deallocating the memory for the anon
     111             :  * transport class.
     112             :  */
     113           0 : void anon_transport_class_unregister(struct anon_transport_class *atc)
     114             : {
     115           0 :         if (unlikely(attribute_container_unregister(&atc->container)))
     116           0 :                 BUG();
     117           0 : }
     118             : EXPORT_SYMBOL_GPL(anon_transport_class_unregister);
     119             : 
     120           0 : static int transport_setup_classdev(struct attribute_container *cont,
     121             :                                     struct device *dev,
     122             :                                     struct device *classdev)
     123             : {
     124           0 :         struct transport_class *tclass = class_to_transport_class(cont->class);
     125           0 :         struct transport_container *tcont = attribute_container_to_transport_container(cont);
     126             : 
     127           0 :         if (tclass->setup)
     128           0 :                 tclass->setup(tcont, dev, classdev);
     129             : 
     130           0 :         return 0;
     131             : }
     132             : 
     133             : /**
     134             :  * transport_setup_device - declare a new dev for transport class association but don't make it visible yet.
     135             :  * @dev: the generic device representing the entity being added
     136             :  *
     137             :  * Usually, dev represents some component in the HBA system (either
     138             :  * the HBA itself or a device remote across the HBA bus).  This
     139             :  * routine is simply a trigger point to see if any set of transport
     140             :  * classes wishes to associate with the added device.  This allocates
     141             :  * storage for the class device and initialises it, but does not yet
     142             :  * add it to the system or add attributes to it (you do this with
     143             :  * transport_add_device).  If you have no need for a separate setup
     144             :  * and add operations, use transport_register_device (see
     145             :  * transport_class.h).
     146             :  */
     147             : 
     148           0 : void transport_setup_device(struct device *dev)
     149             : {
     150           0 :         attribute_container_add_device(dev, transport_setup_classdev);
     151           0 : }
     152             : EXPORT_SYMBOL_GPL(transport_setup_device);
     153             : 
     154           0 : static int transport_add_class_device(struct attribute_container *cont,
     155             :                                       struct device *dev,
     156             :                                       struct device *classdev)
     157             : {
     158           0 :         int error = attribute_container_add_class_device(classdev);
     159           0 :         struct transport_container *tcont = 
     160           0 :                 attribute_container_to_transport_container(cont);
     161             : 
     162           0 :         if (!error && tcont->statistics)
     163           0 :                 error = sysfs_create_group(&classdev->kobj, tcont->statistics);
     164             : 
     165           0 :         return error;
     166             : }
     167             : 
     168             : 
     169             : /**
     170             :  * transport_add_device - declare a new dev for transport class association
     171             :  *
     172             :  * @dev: the generic device representing the entity being added
     173             :  *
     174             :  * Usually, dev represents some component in the HBA system (either
     175             :  * the HBA itself or a device remote across the HBA bus).  This
     176             :  * routine is simply a trigger point used to add the device to the
     177             :  * system and register attributes for it.
     178             :  */
     179           0 : int transport_add_device(struct device *dev)
     180             : {
     181           0 :         return attribute_container_device_trigger_safe(dev,
     182             :                                         transport_add_class_device,
     183             :                                         transport_remove_classdev);
     184             : }
     185             : EXPORT_SYMBOL_GPL(transport_add_device);
     186             : 
     187           0 : static int transport_configure(struct attribute_container *cont,
     188             :                                struct device *dev,
     189             :                                struct device *cdev)
     190             : {
     191           0 :         struct transport_class *tclass = class_to_transport_class(cont->class);
     192           0 :         struct transport_container *tcont = attribute_container_to_transport_container(cont);
     193             : 
     194           0 :         if (tclass->configure)
     195           0 :                 tclass->configure(tcont, dev, cdev);
     196             : 
     197           0 :         return 0;
     198             : }
     199             : 
     200             : /**
     201             :  * transport_configure_device - configure an already set up device
     202             :  *
     203             :  * @dev: generic device representing device to be configured
     204             :  *
     205             :  * The idea of configure is simply to provide a point within the setup
     206             :  * process to allow the transport class to extract information from a
     207             :  * device after it has been setup.  This is used in SCSI because we
     208             :  * have to have a setup device to begin using the HBA, but after we
     209             :  * send the initial inquiry, we use configure to extract the device
     210             :  * parameters.  The device need not have been added to be configured.
     211             :  */
     212           0 : void transport_configure_device(struct device *dev)
     213             : {
     214           0 :         attribute_container_device_trigger(dev, transport_configure);
     215           0 : }
     216             : EXPORT_SYMBOL_GPL(transport_configure_device);
     217             : 
     218           0 : static int transport_remove_classdev(struct attribute_container *cont,
     219             :                                      struct device *dev,
     220             :                                      struct device *classdev)
     221             : {
     222           0 :         struct transport_container *tcont = 
     223           0 :                 attribute_container_to_transport_container(cont);
     224           0 :         struct transport_class *tclass = class_to_transport_class(cont->class);
     225             : 
     226           0 :         if (tclass->remove)
     227           0 :                 tclass->remove(tcont, dev, classdev);
     228             : 
     229           0 :         if (tclass->remove != anon_transport_dummy_function) {
     230           0 :                 if (tcont->statistics)
     231           0 :                         sysfs_remove_group(&classdev->kobj, tcont->statistics);
     232           0 :                 attribute_container_class_device_del(classdev);
     233             :         }
     234             : 
     235           0 :         return 0;
     236             : }
     237             : 
     238             : 
     239             : /**
     240             :  * transport_remove_device - remove the visibility of a device
     241             :  *
     242             :  * @dev: generic device to remove
     243             :  *
     244             :  * This call removes the visibility of the device (to the user from
     245             :  * sysfs), but does not destroy it.  To eliminate a device entirely
     246             :  * you must also call transport_destroy_device.  If you don't need to
     247             :  * do remove and destroy as separate operations, use
     248             :  * transport_unregister_device() (see transport_class.h) which will
     249             :  * perform both calls for you.
     250             :  */
     251           0 : void transport_remove_device(struct device *dev)
     252             : {
     253           0 :         attribute_container_device_trigger(dev, transport_remove_classdev);
     254           0 : }
     255             : EXPORT_SYMBOL_GPL(transport_remove_device);
     256             : 
     257           0 : static void transport_destroy_classdev(struct attribute_container *cont,
     258             :                                       struct device *dev,
     259             :                                       struct device *classdev)
     260             : {
     261           0 :         struct transport_class *tclass = class_to_transport_class(cont->class);
     262             : 
     263           0 :         if (tclass->remove != anon_transport_dummy_function)
     264           0 :                 put_device(classdev);
     265           0 : }
     266             : 
     267             : 
     268             : /**
     269             :  * transport_destroy_device - destroy a removed device
     270             :  *
     271             :  * @dev: device to eliminate from the transport class.
     272             :  *
     273             :  * This call triggers the elimination of storage associated with the
     274             :  * transport classdev.  Note: all it really does is relinquish a
     275             :  * reference to the classdev.  The memory will not be freed until the
     276             :  * last reference goes to zero.  Note also that the classdev retains a
     277             :  * reference count on dev, so dev too will remain for as long as the
     278             :  * transport class device remains around.
     279             :  */
     280           0 : void transport_destroy_device(struct device *dev)
     281             : {
     282           0 :         attribute_container_remove_device(dev, transport_destroy_classdev);
     283           0 : }
     284             : EXPORT_SYMBOL_GPL(transport_destroy_device);

Generated by: LCOV version 1.14