summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/pcie/trans.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans.c47
1 files changed, 16 insertions, 31 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index d10208075ae5..63e13577aff8 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -2108,18 +2108,29 @@ static void iwl_trans_pcie_removal_wk(struct work_struct *wk)
container_of(wk, struct iwl_trans_pcie_removal, work);
struct pci_dev *pdev = removal->pdev;
static char *prop[] = {"EVENT=INACCESSIBLE", NULL};
- struct pci_bus *bus = pdev->bus;
+ struct pci_bus *bus;
+
+ pci_lock_rescan_remove();
+
+ bus = pdev->bus;
+ /* in this case, something else already removed the device */
+ if (!bus)
+ goto out;
dev_err(&pdev->dev, "Device gone - attempting removal\n");
+
kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, prop);
- pci_lock_rescan_remove();
- pci_dev_put(pdev);
+
pci_stop_and_remove_bus_device(pdev);
- if (removal->rescan && bus) {
+ pci_dev_put(pdev);
+
+ if (removal->rescan) {
if (bus->parent)
bus = bus->parent;
pci_rescan_bus(bus);
}
+
+out:
pci_unlock_rescan_remove();
kfree(removal);
@@ -2134,6 +2145,7 @@ void iwl_trans_pcie_remove(struct iwl_trans *trans, bool rescan)
return;
IWL_ERR(trans, "Device gone - scheduling removal!\n");
+ iwl_pcie_dump_csr(trans);
/*
* get a module reference to avoid doing this
@@ -2366,32 +2378,6 @@ static int iwl_trans_pcie_read_config32(struct iwl_trans *trans, u32 ofs,
ofs, val);
}
-static void iwl_trans_pcie_block_txq_ptrs(struct iwl_trans *trans, bool block)
-{
- int i;
-
- for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) {
- struct iwl_txq *txq = trans->txqs.txq[i];
-
- if (i == trans->txqs.cmd.q_id)
- continue;
-
- spin_lock_bh(&txq->lock);
-
- if (!block && !(WARN_ON_ONCE(!txq->block))) {
- txq->block--;
- if (!txq->block) {
- iwl_write32(trans, HBUS_TARG_WRPTR,
- txq->write_ptr | (i << 8));
- }
- } else if (block) {
- txq->block++;
- }
-
- spin_unlock_bh(&txq->lock);
- }
-}
-
#define IWL_FLUSH_WAIT_MS 2000
static int iwl_trans_pcie_rxq_dma_data(struct iwl_trans *trans, int queue,
@@ -3573,7 +3559,6 @@ static const struct iwl_trans_ops trans_ops_pcie = {
.wait_tx_queues_empty = iwl_trans_pcie_wait_txqs_empty,
.freeze_txq_timer = iwl_trans_txq_freeze_timer,
- .block_txq_ptrs = iwl_trans_pcie_block_txq_ptrs,
#ifdef CONFIG_IWLWIFI_DEBUGFS
.debugfs_cleanup = iwl_trans_pcie_debugfs_cleanup,
#endif