|
@@ -94,12 +94,12 @@ static int pcie_port_resume_service(struct device *dev)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * release_pcie_device
|
|
|
- *
|
|
|
- * Being invoked automatically when device is being removed
|
|
|
- * in response to device_unregister(dev) call.
|
|
|
- * Release all resources being claimed.
|
|
|
+/**
|
|
|
+ * release_pcie_device - free PCI Express port service device structure
|
|
|
+ * @dev: Port service device to release
|
|
|
+ *
|
|
|
+ * Invoked automatically when device is being removed in response to
|
|
|
+ * device_unregister(dev). Release all resources being claimed.
|
|
|
*/
|
|
|
static void release_pcie_device(struct device *dev)
|
|
|
{
|
|
@@ -127,7 +127,16 @@ static int is_msi_quirked(struct pci_dev *dev)
|
|
|
}
|
|
|
return quirk;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+/**
|
|
|
+ * assign_interrupt_mode - choose interrupt mode for PCI Express port services
|
|
|
+ * (INTx, MSI-X, MSI) and set up vectors
|
|
|
+ * @dev: PCI Express port to handle
|
|
|
+ * @vectors: Array of interrupt vectors to populate
|
|
|
+ * @mask: Bitmask of port capabilities returned by get_port_device_capability()
|
|
|
+ *
|
|
|
+ * Return value: Interrupt mode associated with the port
|
|
|
+ */
|
|
|
static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
|
|
|
{
|
|
|
int i, pos, nvec, status = -EINVAL;
|
|
@@ -174,6 +183,16 @@ static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
|
|
|
return interrupt_mode;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * get_port_device_capability - discover capabilities of a PCI Express port
|
|
|
+ * @dev: PCI Express port to examine
|
|
|
+ *
|
|
|
+ * The capabilities are read from the port's PCI Express configuration registers
|
|
|
+ * as described in PCI Express Base Specification 1.0a sections 7.8.2, 7.8.9 and
|
|
|
+ * 7.9 - 7.11.
|
|
|
+ *
|
|
|
+ * Return value: Bitmask of discovered port capabilities
|
|
|
+ */
|
|
|
static int get_port_device_capability(struct pci_dev *dev)
|
|
|
{
|
|
|
int services = 0, pos;
|
|
@@ -201,6 +220,15 @@ static int get_port_device_capability(struct pci_dev *dev)
|
|
|
return services;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * pcie_device_init - initialize PCI Express port service device
|
|
|
+ * @dev: Port service device to initialize
|
|
|
+ * @parent: PCI Express port to associate the service device with
|
|
|
+ * @port_type: Type of the port
|
|
|
+ * @service_type: Type of service to associate with the service device
|
|
|
+ * @irq: Interrupt vector to associate with the service device
|
|
|
+ * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI)
|
|
|
+ */
|
|
|
static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
|
|
|
int port_type, int service_type, int irq, int irq_mode)
|
|
|
{
|
|
@@ -226,6 +254,14 @@ static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
|
|
|
device->parent = &parent->dev;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * alloc_pcie_device - allocate PCI Express port service device structure
|
|
|
+ * @parent: PCI Express port to associate the service device with
|
|
|
+ * @port_type: Type of the port
|
|
|
+ * @service_type: Type of service to associate with the service device
|
|
|
+ * @irq: Interrupt vector to associate with the service device
|
|
|
+ * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI)
|
|
|
+ */
|
|
|
static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
|
|
|
int port_type, int service_type, int irq, int irq_mode)
|
|
|
{
|
|
@@ -239,6 +275,10 @@ static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
|
|
|
return device;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * pcie_port_device_probe - check if device is a PCI Express port
|
|
|
+ * @dev: Device to check
|
|
|
+ */
|
|
|
int pcie_port_device_probe(struct pci_dev *dev)
|
|
|
{
|
|
|
int pos, type;
|
|
@@ -256,6 +296,13 @@ int pcie_port_device_probe(struct pci_dev *dev)
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * pcie_port_device_register - register PCI Express port
|
|
|
+ * @dev: PCI Express port to register
|
|
|
+ *
|
|
|
+ * Allocate the port extension structure and register services associated with
|
|
|
+ * the port.
|
|
|
+ */
|
|
|
int pcie_port_device_register(struct pci_dev *dev)
|
|
|
{
|
|
|
struct pcie_port_device_ext *p_ext;
|
|
@@ -319,6 +366,11 @@ static int suspend_iter(struct device *dev, void *data)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * pcie_port_device_suspend - suspend port services associated with a PCIe port
|
|
|
+ * @dev: PCI Express port to handle
|
|
|
+ * @state: Representation of system power management transition in progress
|
|
|
+ */
|
|
|
int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state)
|
|
|
{
|
|
|
return device_for_each_child(&dev->dev, &state, suspend_iter);
|
|
@@ -337,6 +389,10 @@ static int resume_iter(struct device *dev, void *data)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * pcie_port_device_suspend - resume port services associated with a PCIe port
|
|
|
+ * @dev: PCI Express port to handle
|
|
|
+ */
|
|
|
int pcie_port_device_resume(struct pci_dev *dev)
|
|
|
{
|
|
|
return device_for_each_child(&dev->dev, NULL, resume_iter);
|
|
@@ -359,6 +415,13 @@ static int remove_iter(struct device *dev, void *data)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * pcie_port_device_remove - unregister PCI Express port service devices
|
|
|
+ * @dev: PCI Express port the service devices to unregister are associated with
|
|
|
+ *
|
|
|
+ * Remove PCI Express port service devices associated with given port and
|
|
|
+ * disable MSI-X or MSI for the port.
|
|
|
+ */
|
|
|
void pcie_port_device_remove(struct pci_dev *dev)
|
|
|
{
|
|
|
struct device *device;
|