mirror of https://gitee.com/openkylin/linux.git
iwlagn: introduce iwl_bus and iwl_bus_ops
iwl_bus will represent a bus, and iwl_bus_ops all the operations that can be done on this bus. For the moment only set_prv_data is implemented. More to come... Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
This commit is contained in:
parent
c6ca8bc46c
commit
a48709c5d0
|
@ -3479,7 +3479,8 @@ static void iwl_init_context(struct iwl_priv *priv)
|
||||||
BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
|
BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg)
|
int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
|
||||||
|
struct iwl_cfg *cfg)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
struct iwl_priv *priv;
|
struct iwl_priv *priv;
|
||||||
|
@ -3490,12 +3491,23 @@ int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg)
|
||||||
/************************
|
/************************
|
||||||
* 1. Allocating HW data
|
* 1. Allocating HW data
|
||||||
************************/
|
************************/
|
||||||
|
/* TODO: remove this nasty hack when PCI encapsulation is done
|
||||||
|
* assumes that struct pci_dev * is at the very beginning of whatever
|
||||||
|
* is pointed by bus_specific */
|
||||||
|
unsigned long *ppdev = bus_specific;
|
||||||
|
struct pci_dev *pdev = (struct pci_dev *) *ppdev;
|
||||||
|
|
||||||
hw = iwl_alloc_all(cfg);
|
hw = iwl_alloc_all(cfg);
|
||||||
if (!hw) {
|
if (!hw) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out; }
|
goto out; }
|
||||||
priv = hw->priv;
|
priv = hw->priv;
|
||||||
|
|
||||||
|
priv->bus.priv = priv;
|
||||||
|
priv->bus.bus_specific = bus_specific;
|
||||||
|
priv->bus.ops = bus_ops;
|
||||||
|
priv->bus.ops->set_drv_data(&priv->bus, priv);
|
||||||
|
|
||||||
/* At this point both hw and priv are allocated. */
|
/* At this point both hw and priv are allocated. */
|
||||||
|
|
||||||
SET_IEEE80211_DEV(hw, &pdev->dev);
|
SET_IEEE80211_DEV(hw, &pdev->dev);
|
||||||
|
@ -3549,9 +3561,6 @@ int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg)
|
||||||
if (err)
|
if (err)
|
||||||
goto out_pci_disable_device;
|
goto out_pci_disable_device;
|
||||||
|
|
||||||
pci_set_drvdata(pdev, priv);
|
|
||||||
|
|
||||||
|
|
||||||
/***********************
|
/***********************
|
||||||
* 3. Read REV register
|
* 3. Read REV register
|
||||||
***********************/
|
***********************/
|
||||||
|
@ -3705,7 +3714,7 @@ int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg)
|
||||||
out_iounmap:
|
out_iounmap:
|
||||||
pci_iounmap(pdev, priv->hw_base);
|
pci_iounmap(pdev, priv->hw_base);
|
||||||
out_pci_release_regions:
|
out_pci_release_regions:
|
||||||
pci_set_drvdata(pdev, NULL);
|
priv->bus.ops->set_drv_data(&priv->bus, NULL);
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
out_pci_disable_device:
|
out_pci_disable_device:
|
||||||
pci_disable_device(pdev);
|
pci_disable_device(pdev);
|
||||||
|
@ -3716,14 +3725,11 @@ int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __devexit iwl_remove(struct pci_dev *pdev)
|
void __devexit iwl_remove(struct iwl_priv * priv)
|
||||||
{
|
{
|
||||||
struct iwl_priv *priv = pci_get_drvdata(pdev);
|
struct pci_dev *pdev = priv->pci_dev;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (!priv)
|
|
||||||
return;
|
|
||||||
|
|
||||||
wait_for_completion(&priv->_agn.firmware_loading_complete);
|
wait_for_completion(&priv->_agn.firmware_loading_complete);
|
||||||
|
|
||||||
IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
|
IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
|
||||||
|
@ -3783,7 +3789,7 @@ void __devexit iwl_remove(struct pci_dev *pdev)
|
||||||
pci_iounmap(pdev, priv->hw_base);
|
pci_iounmap(pdev, priv->hw_base);
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
pci_disable_device(pdev);
|
pci_disable_device(pdev);
|
||||||
pci_set_drvdata(pdev, NULL);
|
priv->bus.ops->set_drv_data(&priv->bus, NULL);
|
||||||
|
|
||||||
iwl_uninit_drv(priv);
|
iwl_uninit_drv(priv);
|
||||||
|
|
||||||
|
|
|
@ -379,7 +379,8 @@ void iwl_testmode_cleanup(struct iwl_priv *priv)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg);
|
int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
|
||||||
void iwl_remove(struct pci_dev *pdev);
|
struct iwl_cfg *cfg);
|
||||||
|
void __devexit iwl_remove(struct iwl_priv * priv);
|
||||||
|
|
||||||
#endif /* __iwl_agn_h__ */
|
#endif /* __iwl_agn_h__ */
|
||||||
|
|
|
@ -1188,6 +1188,26 @@ struct iwl_testmode_trace {
|
||||||
bool trace_enabled;
|
bool trace_enabled;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct iwl_bus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct iwl_bus_ops - bus specific operations
|
||||||
|
* @set_drv_data: set the priv pointer to the bus layer
|
||||||
|
*/
|
||||||
|
struct iwl_bus_ops {
|
||||||
|
void (*set_drv_data)(struct iwl_bus *bus, void *priv);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iwl_bus {
|
||||||
|
/* pointer to bus specific struct */
|
||||||
|
void *bus_specific;
|
||||||
|
|
||||||
|
/* Common data to all buses */
|
||||||
|
struct iwl_priv *priv; /* driver's context */
|
||||||
|
struct iwl_bus_ops *ops;
|
||||||
|
};
|
||||||
|
|
||||||
struct iwl_priv {
|
struct iwl_priv {
|
||||||
|
|
||||||
/* ieee device used by generic ieee processing code */
|
/* ieee device used by generic ieee processing code */
|
||||||
|
@ -1255,12 +1275,15 @@ struct iwl_priv {
|
||||||
spinlock_t reg_lock; /* protect hw register access */
|
spinlock_t reg_lock; /* protect hw register access */
|
||||||
struct mutex mutex;
|
struct mutex mutex;
|
||||||
|
|
||||||
|
/* TODO: remove this after PCI abstraction is done */
|
||||||
/* basic pci-network driver stuff */
|
/* basic pci-network driver stuff */
|
||||||
struct pci_dev *pci_dev;
|
struct pci_dev *pci_dev;
|
||||||
|
|
||||||
/* pci hardware address support */
|
/* pci hardware address support */
|
||||||
void __iomem *hw_base;
|
void __iomem *hw_base;
|
||||||
|
|
||||||
|
struct iwl_bus bus; /* bus specific data */
|
||||||
|
|
||||||
/* microcode/device supports multiple contexts */
|
/* microcode/device supports multiple contexts */
|
||||||
u8 valid_contexts;
|
u8 valid_contexts;
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,29 @@
|
||||||
#include "iwl-agn.h"
|
#include "iwl-agn.h"
|
||||||
#include "iwl-core.h"
|
#include "iwl-core.h"
|
||||||
|
|
||||||
|
struct iwl_pci_bus {
|
||||||
|
/* basic pci-network driver stuff */
|
||||||
|
struct pci_dev *pci_dev;
|
||||||
|
|
||||||
|
/* pci hardware address support */
|
||||||
|
void __iomem *hw_base;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define IWL_BUS_GET_PCI_BUS(_iwl_bus) \
|
||||||
|
((struct iwl_pci_bus *) ((_iwl_bus)->bus_specific))
|
||||||
|
|
||||||
|
#define IWL_BUS_GET_PCI_DEV(_iwl_bus) \
|
||||||
|
((IWL_BUS_GET_PCI_BUS(_iwl_bus))->pci_dev)
|
||||||
|
|
||||||
|
static void iwl_pci_set_drv_data(struct iwl_bus *bus, void *drv_priv)
|
||||||
|
{
|
||||||
|
pci_set_drvdata(IWL_BUS_GET_PCI_DEV(bus), drv_priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct iwl_bus_ops pci_ops = {
|
||||||
|
.set_drv_data = iwl_pci_set_drv_data,
|
||||||
|
};
|
||||||
|
|
||||||
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
|
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
|
||||||
.vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
|
.vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
|
||||||
.subvendor = PCI_ANY_ID, .subdevice = (subdev), \
|
.subvendor = PCI_ANY_ID, .subdevice = (subdev), \
|
||||||
|
@ -266,13 +289,38 @@ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
|
||||||
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
|
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
|
||||||
|
struct iwl_pci_bus *bus;
|
||||||
|
int err;
|
||||||
|
|
||||||
return iwl_probe(pdev, cfg);
|
bus = kzalloc(sizeof(*bus), GFP_KERNEL);
|
||||||
|
if (!bus) {
|
||||||
|
pr_err("Couldn't allocate iwl_pci_bus");
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto out_no_pci;
|
||||||
|
}
|
||||||
|
|
||||||
|
bus->pci_dev = pdev;
|
||||||
|
|
||||||
|
err = iwl_probe((void *) bus, &pci_ops, cfg);
|
||||||
|
if (err)
|
||||||
|
goto out_no_pci;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out_no_pci:
|
||||||
|
kfree(bus);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit iwl_pci_remove(struct pci_dev *pdev)
|
static void __devexit iwl_pci_remove(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
iwl_remove(pdev);
|
struct iwl_priv *priv = pci_get_drvdata(pdev);
|
||||||
|
|
||||||
|
/* This can happen if probe failed */
|
||||||
|
if (unlikely(!priv))
|
||||||
|
return;
|
||||||
|
|
||||||
|
iwl_remove(priv);
|
||||||
|
kfree(IWL_BUS_GET_PCI_BUS(&priv->bus));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
Loading…
Reference in New Issue