diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index dd0c32379375..cf5807dad5f0 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -74,6 +74,8 @@ static void hif_usb_regout_cb(struct urb *urb) { struct cmd_buf *cmd = (struct cmd_buf *)urb->context; + printk("haley: dev %#llx, urb %#llx. %s, %d\n", cmd->hif_dev, urb, __func__, __LINE__); + switch (urb->status) { case 0: break; @@ -146,6 +148,8 @@ static void hif_usb_mgmt_cb(struct urb *urb) hif_dev = cmd->hif_dev; + printk("haley: dev %#llx, urb %#llx. %s, %d\n", hif_dev, urb, __func__, __LINE__); + switch (urb->status) { case 0: break; @@ -263,6 +267,8 @@ static void hif_usb_tx_cb(struct urb *urb) hif_dev = tx_buf->hif_dev; + printk("haley: dev %#llx, urb %#llx. %s, %d\n", hif_dev, urb, __func__, __LINE__); + switch (urb->status) { case 0: break; @@ -612,6 +618,12 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, hif_dev->remain_skb = nskb; spin_unlock(&hif_dev->rx_lock); } else { + if (pool_index == MAX_PKT_NUM_IN_TRANSFER) { + dev_err(&hif_dev->udev->dev, + "ath9k_htc: over RX MAX_PKT_NUM\n"); + goto err; + } + nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC); if (!nskb) { dev_err(&hif_dev->udev->dev, @@ -638,11 +650,21 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, static void ath9k_hif_usb_rx_cb(struct urb *urb) { - struct sk_buff *skb = (struct sk_buff *) urb->context; - struct hif_device_usb *hif_dev = - usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); + struct rx_buf *rx_buf = (struct rx_buf*) urb->context; + struct sk_buff *skb = rx_buf->skb; + struct hif_device_usb *hif_dev = rx_buf->skb; int ret; + if (!urb->dev) { + printk("haley: catch dev null, urb %#llx. %s, %d\n", urb, __func__, __LINE__); + } + + if (!usb_ifnum_to_if(urb->dev, 0)) { + printk("haley: catch if null, urb %#llx. %s, %d\n", urb, __func__, __LINE__); + } + + //hif_dev = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); + if (!skb) return; @@ -680,16 +702,27 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb) return; free: kfree_skb(skb); + kfree(rx_buf); } static void ath9k_hif_usb_reg_in_cb(struct urb *urb) { - struct sk_buff *skb = (struct sk_buff *) urb->context; + struct rx_buf *rx_buf = (struct rx_buf*) urb->context; + struct sk_buff *skb = rx_buf->skb; struct sk_buff *nskb; - struct hif_device_usb *hif_dev = - usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); + struct hif_device_usb *hif_dev = rx_buf->hif_dev; int ret; + if (!urb->dev) { + printk("haley: catch dev null, urb %#llx. %s, %d\n", urb, __func__, __LINE__); + } + + if (!usb_ifnum_to_if(urb->dev, 0)) { + printk("haley: catch if null, urb %#llx. %s, %d\n", urb, __func__, __LINE__); + } + + //hif_dev = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); + if (!skb) return; @@ -745,6 +778,7 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) return; free: kfree_skb(skb); + kfree(rx_buf); urb->context = NULL; } @@ -806,6 +840,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) __skb_queue_head_init(&tx_buf->skb_queue); list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf); + printk("haley: dev %#llx, urb %#llx. %s, %d\n", hif_dev, tx_buf->urb, __func__, __LINE__); } hif_dev->tx.tx_buf_cnt = MAX_TX_URB_NUM; @@ -829,13 +864,19 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev) { struct urb *urb = NULL; struct sk_buff *skb = NULL; + struct rx_buf *rx_buf = NULL; int i, ret; init_usb_anchor(&hif_dev->rx_submitted); spin_lock_init(&hif_dev->rx_lock); for (i = 0; i < MAX_RX_URB_NUM; i++) { - + rx_buf = kzalloc(sizeof(struct rx_buf), GFP_KERNEL); + if (!rx_buf) { + ret = -ENOMEM; + goto err_rxb; + } + /* Allocate URB */ urb = usb_alloc_urb(0, GFP_KERNEL); if (urb == NULL) { @@ -850,11 +891,14 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev) goto err_skb; } + rx_buf->hif_dev = hif_dev; + rx_buf->skb = skb; + usb_fill_bulk_urb(urb, hif_dev->udev, usb_rcvbulkpipe(hif_dev->udev, USB_WLAN_RX_PIPE), skb->data, MAX_RX_BUF_SIZE, - ath9k_hif_usb_rx_cb, skb); + ath9k_hif_usb_rx_cb, rx_buf); /* Anchor URB */ usb_anchor_urb(urb, &hif_dev->rx_submitted); @@ -865,6 +909,8 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev) usb_unanchor_urb(urb); goto err_submit; } + printk("haley: dev %#llx, urb %#llx, data %#llx, udev %#llx->%#llx. %s, %d\n", + hif_dev, urb, skb->data, hif_dev->udev, urb->dev, __func__, __LINE__); /* * Drop reference count. @@ -880,12 +926,15 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev) err_skb: usb_free_urb(urb); err_urb: + kfree(rx_buf); +err_rxb: ath9k_hif_usb_dealloc_rx_urbs(hif_dev); return ret; } static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev) { + printk("ath9k_debug %s, %d\n", __func__, __LINE__); usb_kill_anchored_urbs(&hif_dev->reg_in_submitted); } @@ -893,11 +942,19 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) { struct urb *urb = NULL; struct sk_buff *skb = NULL; + struct rx_buf *rx_buf = NULL; int i, ret; + printk("ath9k_debug %s, %d\n", __func__, __LINE__); + init_usb_anchor(&hif_dev->reg_in_submitted); for (i = 0; i < MAX_REG_IN_URB_NUM; i++) { + rx_buf = kzalloc(sizeof(struct rx_buf), GFP_KERNEL); + if (!rx_buf) { + ret = -ENOMEM; + goto err_rxb; + } /* Allocate URB */ urb = usb_alloc_urb(0, GFP_KERNEL); @@ -906,6 +963,9 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) goto err_urb; } + rx_buf->hif_dev = hif_dev; + rx_buf->skb = skb; + /* Allocate buffer */ skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); if (!skb) { @@ -929,6 +989,8 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) goto err_submit; } + printk("haley: dev %#llx, urb %#llx, data %#llx. %s, %d\n", hif_dev, urb, skb->data, __func__, __LINE__); + /* * Drop reference count. * This ensures that the URB is freed when killing them. @@ -943,12 +1005,15 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) err_skb: usb_free_urb(urb); err_urb: + kfree(rx_buf); +err_rxb: ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); return ret; } static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) { + printk("ath9k_debug %s, %d\n", __func__, __LINE__); /* Register Write */ init_usb_anchor(&hif_dev->regout_submitted); @@ -975,6 +1040,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) { + printk("ath9k_debug %s, %d\n", __func__, __LINE__); usb_kill_anchored_urbs(&hif_dev->regout_submitted); ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); ath9k_hif_usb_dealloc_tx_urbs(hif_dev); @@ -1141,13 +1207,16 @@ static int ath9k_hif_request_firmware(struct hif_device_usb *hif_dev, ret = request_firmware_nowait(THIS_MODULE, true, hif_dev->fw_name, &hif_dev->udev->dev, GFP_KERNEL, hif_dev, ath9k_hif_usb_firmware_cb); + + printk("haley: dev %#llx. %s, %d\n", hif_dev, __func__, __LINE__); + if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Async request for firmware %s failed\n", hif_dev->fw_name); return ret; } - + printk("haley: dev %#llx. %s, %d\n", hif_dev, __func__, __LINE__); dev_info(&hif_dev->udev->dev, "ath9k_htc: Firmware %s requested\n", hif_dev->fw_name); @@ -1159,6 +1228,7 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) struct hif_device_usb *hif_dev = context; int ret; + printk("haley: dev %#llx. %s, %d\n", hif_dev, __func__, __LINE__); if (!fw) { ret = ath9k_hif_request_firmware(hif_dev, false); if (!ret) @@ -1170,11 +1240,15 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) goto err_fw; } + printk("ath9k_debug %s, %d\n", __func__, __LINE__); hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb, &hif_dev->udev->dev); if (hif_dev->htc_handle == NULL) goto err_dev_alloc; + printk("haley: dev %#llx. htc %#llx, base %#llx, %s, %d\n", hif_dev, + hif_dev->htc_handle, hif_dev->htc_handle->endpoint, __func__, __LINE__); + hif_dev->fw_data = fw->data; hif_dev->fw_size = fw->size; @@ -1195,7 +1269,9 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) } release_firmware(fw); + printk("ath9k_debug %s, %d\n", __func__, __LINE__); hif_dev->flags |= HIF_USB_READY; + smp_mb(); complete_all(&hif_dev->fw_done); return; @@ -1203,6 +1279,7 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) err_htc_hw_init: ath9k_hif_usb_dev_deinit(hif_dev); err_dev_init: + printk("ath9k_debug %s, %d\n", __func__, __LINE__); ath9k_htc_hw_free(hif_dev->htc_handle); err_dev_alloc: release_firmware(fw); @@ -1300,6 +1377,8 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, if (ret) goto err_fw_req; + printk("haley: hif_dev %#llx dev %#llx. %s, %d\n", hif_dev, udev, __func__, __LINE__); + return ret; err_fw_req: @@ -1339,10 +1418,15 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) wait_for_completion(&hif_dev->fw_done); + printk("ath9k_debug %s, %d\n", __func__, __LINE__); + smp_mb(); if (hif_dev->flags & HIF_USB_READY) { + printk("ath9k_debug %s, %d\n", __func__, __LINE__); ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); - ath9k_htc_hw_free(hif_dev->htc_handle); ath9k_hif_usb_dev_deinit(hif_dev); + smp_mb(); + ath9k_destoy_wmi(hif_dev->htc_handle->drv_priv); + ath9k_htc_hw_free(hif_dev->htc_handle); } usb_set_intfdata(interface, NULL); diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 7846916aa01d..a777401a13b9 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -86,6 +86,11 @@ struct tx_buf { struct list_head list; }; +struct rx_buf { + struct sk_buff *skb; + struct hif_device_usb *hif_dev; +}; + #define HIF_USB_TX_STOP BIT(0) #define HIF_USB_TX_FLUSH BIT(1) @@ -134,4 +139,11 @@ struct hif_device_usb { int ath9k_hif_usb_init(void); void ath9k_hif_usb_exit(void); +struct hif_skb_cb { + struct hif_device_usb* hif_dev; +}; + + +#define HIF_CB(skb) ((struct hif_skb_cb *)&((skb)->cb)) + #endif /* HTC_USB_H */ diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index d961095ab01f..d1d0ed6e653c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -982,7 +982,7 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug) htc_handle->drv_priv->ah->ah_flags |= AH_UNPLUGGED; ath9k_deinit_device(htc_handle->drv_priv); - ath9k_deinit_wmi(htc_handle->drv_priv); + ath9k_stop_wmi(htc_handle->drv_priv); ieee80211_free_hw(htc_handle->drv_priv->hw); } } diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index d091c8ebdcf0..f1b9e65c716f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -115,7 +115,10 @@ static void htc_process_conn_rsp(struct htc_target *target, epid = svc_rspmsg->endpoint_id; service_id = be16_to_cpu(svc_rspmsg->service_id); max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len); + if (epid >= ENDPOINT_MAX) + printk("haley: catch %d. %s, %d\n", epid, __func__, __LINE__); endpoint = &target->endpoint[epid]; + printk("haley: endpoint base %#llx, endpoint %#llx.\n", target->endpoint, endpoint); for (tepid = (ENDPOINT_MAX - 1); tepid > ENDPOINT0; tepid--) { tmp_endpoint = &target->endpoint[tepid]; @@ -279,7 +282,6 @@ int htc_connect_service(struct htc_target *target, if (!time_left) { dev_err(target->dev, "Service connection timeout for: %d\n", service_connreq->service_id); - kfree_skb(skb); return -ETIMEDOUT; } @@ -407,6 +409,8 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle, htc_hdr = (struct htc_frame_hdr *) skb->data; epid = htc_hdr->endpoint_id; + printk("haley: dev %#llx, htc_hdr %#llx. %s, %d\n", htc_handle->hif_dev, htc_hdr, __func__, __LINE__); + if (epid == 0x99) { ath9k_htc_fw_panic_report(htc_handle, skb); kfree_skb(skb); @@ -455,6 +459,7 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle, skb_pull(skb, sizeof(struct htc_frame_hdr)); endpoint = &htc_handle->endpoint[epid]; + printk("haley: dev %#llx, htc_hdr %#llx. %s, %d\n", htc_handle->hif_dev, htc_hdr, __func__, __LINE__); if (endpoint->ep_callbacks.rx) endpoint->ep_callbacks.rx(endpoint->ep_callbacks.priv, skb, epid); @@ -491,6 +496,7 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle, void ath9k_htc_hw_free(struct htc_target *htc) { + printk("ath9k_debug %s, %d\n", __func__, __LINE__); kfree(htc); } diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index cdc146091194..94f95676e02c 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -123,6 +123,20 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv) kfree(priv->wmi); } +void ath9k_stop_wmi(struct ath9k_htc_priv *priv) +{ + struct wmi *wmi = priv->wmi; + + mutex_lock(&wmi->op_mutex); + wmi->stopped = true; + mutex_unlock(&wmi->op_mutex); +} + +void ath9k_destoy_wmi(struct ath9k_htc_priv *priv) +{ + kfree(priv->wmi); +} + void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv) { unsigned long flags; diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 380175d5ecd7..c3e278377365 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -189,6 +189,8 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, void ath9k_wmi_event_tasklet(unsigned long data); void ath9k_fatal_work(struct work_struct *work); void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv); +void ath9k_stop_wmi(struct ath9k_htc_priv *priv); +void ath9k_destoy_wmi(struct ath9k_htc_priv *priv); #define WMI_CMD(_wmi_cmd) \ do { \