Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 255786
b: refs/heads/master
c: a48709c
h: refs/heads/master
v: v3
  • Loading branch information
Emmanuel Grumbach authored and Wey-Yi Guy committed Jun 18, 2011
1 parent 0b06af6 commit 54bdfa7
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c6ca8bc46cc320e31e8fcb8b104eeed044febd6f
refs/heads/master: a48709c5d076aa3a3f9b6426f462abe6bf432b11
28 changes: 17 additions & 11 deletions trunk/drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -3479,7 +3479,8 @@ static void iwl_init_context(struct iwl_priv *priv)
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;
struct iwl_priv *priv;
Expand All @@ -3490,12 +3491,23 @@ int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg)
/************************
* 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);
if (!hw) {
err = -ENOMEM;
goto out; }
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. */

SET_IEEE80211_DEV(hw, &pdev->dev);
Expand Down Expand Up @@ -3549,9 +3561,6 @@ int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg)
if (err)
goto out_pci_disable_device;

pci_set_drvdata(pdev, priv);


/***********************
* 3. Read REV register
***********************/
Expand Down Expand Up @@ -3705,7 +3714,7 @@ int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg)
out_iounmap:
pci_iounmap(pdev, priv->hw_base);
out_pci_release_regions:
pci_set_drvdata(pdev, NULL);
priv->bus.ops->set_drv_data(&priv->bus, NULL);
pci_release_regions(pdev);
out_pci_disable_device:
pci_disable_device(pdev);
Expand All @@ -3716,14 +3725,11 @@ int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg)
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;

if (!priv)
return;

wait_for_completion(&priv->_agn.firmware_loading_complete);

IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
Expand Down Expand Up @@ -3783,7 +3789,7 @@ void __devexit iwl_remove(struct pci_dev *pdev)
pci_iounmap(pdev, priv->hw_base);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
priv->bus.ops->set_drv_data(&priv->bus, NULL);

iwl_uninit_drv(priv);

Expand Down
5 changes: 3 additions & 2 deletions trunk/drivers/net/wireless/iwlwifi/iwl-agn.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,8 @@ void iwl_testmode_cleanup(struct iwl_priv *priv)
}
#endif

int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg);
void iwl_remove(struct pci_dev *pdev);
int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
struct iwl_cfg *cfg);
void __devexit iwl_remove(struct iwl_priv * priv);

#endif /* __iwl_agn_h__ */
23 changes: 23 additions & 0 deletions trunk/drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -1188,6 +1188,26 @@ struct iwl_testmode_trace {
bool trace_enabled;
};
#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 {

/* ieee device used by generic ieee processing code */
Expand Down Expand Up @@ -1255,12 +1275,15 @@ struct iwl_priv {
spinlock_t reg_lock; /* protect hw register access */
struct mutex mutex;

/* TODO: remove this after PCI abstraction is done */
/* basic pci-network driver stuff */
struct pci_dev *pci_dev;

/* pci hardware address support */
void __iomem *hw_base;

struct iwl_bus bus; /* bus specific data */

/* microcode/device supports multiple contexts */
u8 valid_contexts;

Expand Down
54 changes: 51 additions & 3 deletions trunk/drivers/net/wireless/iwlwifi/iwl-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,29 @@
#include "iwl-agn.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) \
.vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
.subvendor = PCI_ANY_ID, .subdevice = (subdev), \
Expand Down Expand Up @@ -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)
{
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);

return iwl_probe(pdev, cfg);
struct iwl_pci_bus *bus;
int err;

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)
{
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
Expand Down

0 comments on commit 54bdfa7

Please sign in to comment.