aboutsummaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-pci.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie.c24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h21
4 files changed, 48 insertions, 30 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index b42be3084507..1a4ba9de99b0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1783,12 +1783,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
priv->shrd = bus->shrd;
priv->shrd->priv = priv;
- priv->shrd->trans = trans_ops->alloc(priv->shrd);
- if (priv->shrd->trans == NULL) {
- err = -ENOMEM;
- goto out_free_traffic_mem;
- }
-
/* At this point both hw and priv are allocated. */
SET_IEEE80211_DEV(hw, bus(priv)->dev);
@@ -1835,12 +1829,12 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
err = iwl_trans_request_irq(trans(priv));
if (err)
- goto out_free_trans;
+ goto out_free_traffic_mem;
if (iwl_trans_prepare_card_hw(trans(priv))) {
err = -EIO;
IWL_WARN(priv, "Failed, HW not ready\n");
- goto out_free_trans;
+ goto out_free_traffic_mem;
}
/*****************
@@ -1854,7 +1848,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
iwl_apm_stop(priv);
if (err) {
IWL_ERR(priv, "Unable to init EEPROM\n");
- goto out_free_trans;
+ goto out_free_traffic_mem;
}
err = iwl_eeprom_check_version(priv);
if (err)
@@ -1935,8 +1929,6 @@ out_destroy_workqueue:
iwl_uninit_drv(priv);
out_free_eeprom:
iwl_eeprom_free(priv->shrd);
-out_free_trans:
- iwl_trans_free(trans(priv));
out_free_traffic_mem:
iwl_free_traffic_mem(priv);
ieee80211_free_hw(priv->hw);
@@ -1980,8 +1972,6 @@ void __devexit iwl_remove(struct iwl_priv * priv)
priv->shrd->workqueue = NULL;
iwl_free_traffic_mem(priv);
- iwl_trans_free(trans(priv));
-
iwl_uninit_drv(priv);
dev_kfree_skb(priv->beacon_skb);
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c
index a3ca0a78336f..c0d62e724956 100644
--- a/drivers/net/wireless/iwlwifi/iwl-pci.c
+++ b/drivers/net/wireless/iwlwifi/iwl-pci.c
@@ -463,14 +463,28 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
bus->ops = &bus_ops_pci;
#ifdef CONFIG_IWLWIFI_IDI
+ trans(bus) = iwl_trans_idi_alloc(bus->shrd, pdev, ent);
+ if (trans(bus) == NULL) {
+ err = -ENOMEM;
+ goto out_disable_msi;
+ }
+
err = iwl_probe(bus, &trans_ops_idi, cfg);
#else
+ trans(bus) = iwl_trans_pcie_alloc(bus->shrd, pdev, ent);
+ if (trans(bus) == NULL) {
+ err = -ENOMEM;
+ goto out_disable_msi;
+ }
+
err = iwl_probe(bus, &trans_ops_pcie, cfg);
#endif
if (err)
- goto out_disable_msi;
+ goto out_free_trans;
return 0;
+out_free_trans:
+ iwl_trans_free(trans(bus));
out_disable_msi:
pci_disable_msi(pdev);
pci_iounmap(pdev, pci_bus->hw_base);
@@ -493,6 +507,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
struct iwl_shared *shrd = bus->shrd;
iwl_remove(shrd->priv);
+ iwl_trans_free(shrd->trans);
pci_disable_msi(pci_dev);
pci_iounmap(pci_dev, pci_bus->hw_base);
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index 0b4280c92584..f0d8cccbcb11 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -1376,19 +1376,24 @@ static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans,
const struct iwl_trans_ops trans_ops_pcie;
-static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd)
+struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
+ struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
+ struct iwl_trans_pcie *trans_pcie;
struct iwl_trans *iwl_trans = kzalloc(sizeof(struct iwl_trans) +
sizeof(struct iwl_trans_pcie),
GFP_KERNEL);
- if (iwl_trans) {
- struct iwl_trans_pcie *trans_pcie =
- IWL_TRANS_GET_PCIE_TRANS(iwl_trans);
- iwl_trans->ops = &trans_ops_pcie;
- iwl_trans->shrd = shrd;
- trans_pcie->trans = iwl_trans;
- spin_lock_init(&iwl_trans->hcmd_lock);
- }
+
+ if (WARN_ON(!iwl_trans))
+ return NULL;
+
+ trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans);
+
+ iwl_trans->ops = &trans_ops_pcie;
+ iwl_trans->shrd = shrd;
+ trans_pcie->trans = iwl_trans;
+ spin_lock_init(&iwl_trans->hcmd_lock);
return iwl_trans;
}
@@ -1912,7 +1917,6 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
#endif /*CONFIG_IWLWIFI_DEBUGFS */
const struct iwl_trans_ops trans_ops_pcie = {
- .alloc = iwl_trans_pcie_alloc,
.request_irq = iwl_trans_pcie_request_irq,
.fw_alive = iwl_trans_pcie_fw_alive,
.start_device = iwl_trans_pcie_start_device,
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 2a6649c9ca42..b1a7af26c570 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -133,7 +133,6 @@ struct iwl_host_cmd {
/**
* struct iwl_trans_ops - transport specific operations
- * @alloc: allocates the meta data (not the queues themselves)
* @request_irq: requests IRQ - will be called before the FW load in probe flow
* @start_device: allocates and inits all the resources for the transport
* layer.
@@ -162,7 +161,6 @@ struct iwl_host_cmd {
*/
struct iwl_trans_ops {
- struct iwl_trans *(*alloc)(struct iwl_shared *shrd);
int (*request_irq)(struct iwl_trans *iwl_trans);
int (*start_device)(struct iwl_trans *trans);
void (*fw_alive)(struct iwl_trans *trans);
@@ -380,11 +378,8 @@ static inline int iwl_trans_resume(struct iwl_trans *trans)
#endif
/*****************************************************
-* Transport layers implementations
+* Utils functions
******************************************************/
-extern const struct iwl_trans_ops trans_ops_pcie;
-extern const struct iwl_trans_ops trans_ops_idi;
-
int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc,
const void *data, size_t len);
void iwl_dealloc_ucode(struct iwl_trans *trans);
@@ -394,4 +389,18 @@ int iwl_calib_set(struct iwl_trans *trans,
const struct iwl_calib_hdr *cmd, int len);
void iwl_calib_free_results(struct iwl_trans *trans);
+/*****************************************************
+* Transport layers implementations + their allocation function
+******************************************************/
+struct pci_dev;
+struct pci_device_id;
+extern const struct iwl_trans_ops trans_ops_pcie;
+struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
+ struct pci_dev *pdev,
+ const struct pci_device_id *ent);
+
+extern const struct iwl_trans_ops trans_ops_idi;
+struct iwl_trans *iwl_trans_idi_alloc(struct iwl_shared *shrd,
+ void *pdev_void,
+ const void *ent_void);
#endif /* __iwl_trans_h__ */