/*else the command was successfully sent in SYNC mode, need to free
* the reply page */
- iwl_free_pages(priv->shrd, cmd.reply_page);
+ iwl_free_resp(&cmd);
if (cmd.handler_status)
IWL_ERR(priv, "%s - error in the CMD response %d", __func__,
if (ret)
return ret;
- pkt = (struct iwl_rx_packet *)cmd.reply_page;
+ pkt = cmd.resp_pkt;
if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
pkt->hdr.flags);
break;
}
}
- iwl_free_pages(priv->shrd, cmd.reply_page);
+ iwl_free_resp(&cmd);
return ret;
}
if (ret)
return ret;
- pkt = (struct iwl_rx_packet *)cmd.reply_page;
+ pkt = cmd.resp_pkt;
if (pkt->u.status != CAN_ABORT_STATUS) {
/* The scan abort will return 1 for success or
* 2 for "failure". A failure condition can be
ret = -EIO;
}
- iwl_free_pages(priv->shrd, cmd.reply_page);
+ iwl_free_resp(&cmd);
return ret;
}
return iwlagn_mod_params.debug_level & level;
}
-static inline void iwl_free_pages(struct iwl_shared *shrd, unsigned long page)
-{
- free_pages(page, shrd->hw_params.rx_page_order);
-}
-
/**
* iwl_queue_inc_wrap - increment queue index, wrap back to beginning
* @index -- current index
return ret;
/* Handling return of SKB to the user */
- pkt = (struct iwl_rx_packet *)cmd.reply_page;
+ pkt = cmd.resp_pkt;
if (!pkt) {
IWL_ERR(priv, "HCMD received a null response packet\n");
return ret;
/* The reply is in a page, that we cannot send to user space. */
memcpy(reply_buf, &(pkt->hdr), reply_len);
- iwl_free_pages(priv->shrd, cmd.reply_page);
+ iwl_free_resp(&cmd);
NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf);
/* Input error checking is done when commands are added to queue. */
if (meta->flags & CMD_WANT_SKB) {
- meta->source->reply_page = (unsigned long)rxb_addr(rxb);
- meta->source->handler_status = handler_status;
+ struct page *p = rxb->page;
+
rxb->page = NULL;
+ meta->source->resp_pkt = pkt;
+ meta->source->_rx_page_addr = (unsigned long)page_address(p);
+ meta->source->_rx_page_order = hw_params(trans).rx_page_order;
+ meta->source->handler_status = handler_status;
}
iwl_hcmd_queue_reclaim(trans, txq_id, index);
}
}
- if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) {
+ if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) {
IWL_ERR(trans, "Error: Response NULL in '%s'\n",
get_cmd_string(cmd->id));
ret = -EIO;
~CMD_WANT_SKB;
}
- if (cmd->reply_page) {
- iwl_free_pages(trans->shrd, cmd->reply_page);
- cmd->reply_page = 0;
+ if (cmd->resp_pkt) {
+ iwl_free_resp(cmd);
+ cmd->resp_pkt = NULL;
}
return ret;
* struct iwl_host_cmd - Host command to the uCode
*
* @data: array of chunks that composes the data of the host command
- * @reply_page: pointer to the page that holds the response to the host command
+ * @resp_pkt: response packet, if %CMD_WANT_SKB was set
+ * @_rx_page_order: (internally used to free response packet)
+ * @_rx_page_addr: (internally used to free response packet)
* @handler_status: return value of the handler of the command
* (put in setup_rx_handlers) - valid for SYNC mode only
* @flags: can be CMD_*
*/
struct iwl_host_cmd {
const void *data[IWL_MAX_CMD_TFDS];
- unsigned long reply_page;
+ struct iwl_rx_packet *resp_pkt;
+ unsigned long _rx_page_addr;
+ u32 _rx_page_order;
int handler_status;
u32 flags;
u8 id;
};
+static inline void iwl_free_resp(struct iwl_host_cmd *cmd)
+{
+ free_pages(cmd->_rx_page_addr, cmd->_rx_page_order);
+}
+
/**
* struct iwl_trans_ops - transport specific operations
*