From b52e7ea109cfe4ea7fea99b1cd20f57ccd95476a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 2 Feb 2012 14:16:59 -0800 Subject: [PATCH] iwlwifi: allocate the transport from the bus layer Change the way we alloc the transport on the way. Since the transport is allocated from a bus specific area, we can give the bus specific parameters (i.e. pci_dev for PCI) to the transport. This will be useful when the bus layer will be killed. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 16 +++---------- drivers/net/wireless/iwlwifi/iwl-pci.c | 17 ++++++++++++- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 24 +++++++++++-------- drivers/net/wireless/iwlwifi/iwl-trans.h | 21 +++++++++++----- 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 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, 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__ */ -- GitLab