Fixes possible memleak.

Signed-off-by: Michal Kazior <michal.kaz...@tieto.com>
---
 drivers/net/wireless/ath/ath10k/hif.h |    4 +--
 drivers/net/wireless/ath/ath10k/htc.c |   23 ++++++++++++-----
 drivers/net/wireless/ath/ath10k/pci.c |   45 ++++++++++++++++++++++++---------
 3 files changed, 52 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/hif.h 
b/drivers/net/wireless/ath/ath10k/hif.h
index 6983a0c..73a24d4 100644
--- a/drivers/net/wireless/ath/ath10k/hif.h
+++ b/drivers/net/wireless/ath/ath10k/hif.h
@@ -46,7 +46,7 @@ struct ath10k_hif_ops {
                                void *request, u32 request_len,
                                void *response, u32 *response_len);
 
-       void (*start)(struct ath10k *ar);
+       int (*start)(struct ath10k *ar);
 
        void (*stop)(struct ath10k *ar);
 
@@ -89,7 +89,7 @@ static inline int ath10k_hif_exchange_bmi_msg(struct ath10k 
*ar,
                                             response, response_len);
 }
 
-static inline void ath10k_hif_start(struct ath10k *ar)
+static inline int ath10k_hif_start(struct ath10k *ar)
 {
        return ar->hif.ops->start(ar);
 }
diff --git a/drivers/net/wireless/ath/ath10k/htc.c 
b/drivers/net/wireless/ath/ath10k/htc.c
index 60f471c..c7ff5c3 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -708,7 +708,11 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
 
        INIT_COMPLETION(htc->ctl_resp);
 
-       ath10k_hif_start(htc->ar);
+       status = ath10k_hif_start(htc->ar);
+       if (status) {
+               ath10k_err("could not start HIF (%d)\n", status);
+               goto err_start;
+       }
 
        status = wait_for_completion_timeout(&htc->ctl_resp,
                                             ATH10K_HTC_WAIT_TIMEOUT_HZ);
@@ -717,7 +721,7 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
                        status = -ETIMEDOUT;
 
                ath10k_err("ctl_resp never came in (%d)\n", status);
-               goto fail_wait_target;
+               goto err_target;
        }
 
        if (htc->control_resp_len < sizeof(msg->hdr) + sizeof(msg->ready)) {
@@ -725,7 +729,7 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
                           htc->control_resp_len);
 
                status = -ECOMM;
-               goto fail_wait_target;
+               goto err_target;
        }
 
        msg = (struct ath10k_htc_msg *)htc->control_resp_buffer;
@@ -736,7 +740,7 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
        if (message_id != ATH10K_HTC_MSG_READY_ID) {
                ath10k_err("Invalid HTC ready msg: 0x%x\n", message_id);
                status = -ECOMM;
-               goto fail_wait_target;
+               goto err_target;
        }
 
        htc->total_transmit_credits = credit_count;
@@ -751,7 +755,7 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
            (htc->target_credit_size == 0)) {
                status = -ECOMM;
                ath10k_err("Invalid credit size received\n");
-               goto fail_wait_target;
+               goto err_target;
        }
 
        ath10k_htc_setup_target_buffer_assignments(htc);
@@ -766,8 +770,15 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
 
        /* connect fake service */
        status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp);
+       if (status) {
+               ath10k_err("could not connect to htc service (%d)\n", status);
+               goto err_target;
+       }
 
-fail_wait_target:
+       return 0;
+err_target:
+       ath10k_hif_stop(htc->ar);
+err_start:
        return status;
 }
 
diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index dc4e2ed..7efdaf1 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -52,6 +52,7 @@ static void ath10k_pci_process_ce(struct ath10k *ar);
 static int ath10k_pci_post_rx(struct ath10k *ar);
 static int ath10k_pci_post_rx_pipe(struct hif_ce_pipe_info *pipe_info,
                                             int num);
+static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info);
 
 static const struct ce_attr host_ce_config_wlan[] = {
        /* host->target HTC control and raw streams */
@@ -1035,9 +1036,10 @@ static int ath10k_pci_post_rx_pipe(struct 
hif_ce_pipe_info *pipe_info,
        for (i = 0; i < num; i++) {
                skb = dev_alloc_skb(pipe_info->buf_sz);
                if (!skb) {
-                       ath10k_warn("%s: Memory allocation failure\n",
-                                   __func__);
-                       return -ENOMEM;
+                       ath10k_warn("could not allocate skbuff for pipe %d\n",
+                                   num);
+                       ret = -ENOMEM;
+                       goto err;
                }
 
                WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb");
@@ -1047,9 +1049,10 @@ static int ath10k_pci_post_rx_pipe(struct 
hif_ce_pipe_info *pipe_info,
                                         DMA_FROM_DEVICE);
 
                if (unlikely(dma_mapping_error(ar->dev, ce_data))) {
-                       ath10k_warn("%s mapping error\n",  __func__);
+                       ath10k_warn("could not dma map skbuff\n");
                        dev_kfree_skb_any(skb);
-                       return -EIO;
+                       ret = -EIO;
+                       goto err;
                }
 
                ATH10K_SKB_CB(skb)->paddr = ce_data;
@@ -1060,11 +1063,18 @@ static int ath10k_pci_post_rx_pipe(struct 
hif_ce_pipe_info *pipe_info,
 
                ret = ath10k_ce_recv_buf_enqueue(ce_state, (void *)skb,
                                                 ce_data);
-               if (ret)
-                       break; /* FIXME: Handle error */
+               if (ret) {
+                       ath10k_warn("could not enqueue to pipe %d (%d)\n",
+                                   num, ret);
+                       goto err;
+               }
        }
 
        return ret;
+
+err:
+       ath10k_pci_rx_pipe_cleanup(pipe_info);
+       return ret;
 }
 
 static int ath10k_pci_post_rx(struct ath10k *ar)
@@ -1086,14 +1096,19 @@ static int ath10k_pci_post_rx(struct ath10k *ar)
                if (ret) {
                        ath10k_warn("Unable to replenish recv buffers for pipe: 
%d\n",
                                    pipe_num);
-                       goto done;
+
+                       for (; pipe_num >= 0; pipe_num--) {
+                               pipe_info = &ar_pci->pipe_info[pipe_num];
+                               ath10k_pci_rx_pipe_cleanup(pipe_info);
+                       }
+                       return ret;
                }
        }
-done:
-       return ret;
+
+       return 0;
 }
 
-static void ath10k_pci_hif_start(struct ath10k *ar)
+static int ath10k_pci_hif_start(struct ath10k *ar)
 {
        struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
        int ret;
@@ -1101,8 +1116,14 @@ static void ath10k_pci_hif_start(struct ath10k *ar)
        ath10k_pci_start_ce(ar);
 
        /* Post buffers once to start things off. */
-       ret = ath10k_pci_post_rx(ar); /* FIXME: Handle error */
+       ret = ath10k_pci_post_rx(ar);
+       if (ret) {
+               ath10k_warn("could not post rx pipes (%d)\n", ret);
+               return ret;
+       }
+
        ar_pci->started = 1;
+       return 0;
 }
 
 static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info)
-- 
1.7.9.5

_______________________________________________
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel

Reply via email to