|
@@ -337,6 +337,7 @@ struct i40iw_cqp_request *i40iw_get_cqp_request(struct i40iw_cqp *cqp, bool wait
|
|
|
*/
|
|
|
void i40iw_free_cqp_request(struct i40iw_cqp *cqp, struct i40iw_cqp_request *cqp_request)
|
|
|
{
|
|
|
+ struct i40iw_device *iwdev = container_of(cqp, struct i40iw_device, cqp);
|
|
|
unsigned long flags;
|
|
|
|
|
|
if (cqp_request->dynamic) {
|
|
@@ -350,6 +351,7 @@ void i40iw_free_cqp_request(struct i40iw_cqp *cqp, struct i40iw_cqp_request *cqp
|
|
|
list_add_tail(&cqp_request->list, &cqp->cqp_avail_reqs);
|
|
|
spin_unlock_irqrestore(&cqp->req_lock, flags);
|
|
|
}
|
|
|
+ wake_up(&iwdev->close_wq);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -364,6 +366,56 @@ void i40iw_put_cqp_request(struct i40iw_cqp *cqp,
|
|
|
i40iw_free_cqp_request(cqp, cqp_request);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * i40iw_free_pending_cqp_request -free pending cqp request objs
|
|
|
+ * @cqp: cqp ptr
|
|
|
+ * @cqp_request: to be put back in cqp list
|
|
|
+ */
|
|
|
+static void i40iw_free_pending_cqp_request(struct i40iw_cqp *cqp,
|
|
|
+ struct i40iw_cqp_request *cqp_request)
|
|
|
+{
|
|
|
+ struct i40iw_device *iwdev = container_of(cqp, struct i40iw_device, cqp);
|
|
|
+
|
|
|
+ if (cqp_request->waiting) {
|
|
|
+ cqp_request->compl_info.error = true;
|
|
|
+ cqp_request->request_done = true;
|
|
|
+ wake_up(&cqp_request->waitq);
|
|
|
+ }
|
|
|
+ i40iw_put_cqp_request(cqp, cqp_request);
|
|
|
+ wait_event_timeout(iwdev->close_wq,
|
|
|
+ !atomic_read(&cqp_request->refcount),
|
|
|
+ 1000);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * i40iw_cleanup_pending_cqp_op - clean-up cqp with no completions
|
|
|
+ * @iwdev: iwarp device
|
|
|
+ */
|
|
|
+void i40iw_cleanup_pending_cqp_op(struct i40iw_device *iwdev)
|
|
|
+{
|
|
|
+ struct i40iw_sc_dev *dev = &iwdev->sc_dev;
|
|
|
+ struct i40iw_cqp *cqp = &iwdev->cqp;
|
|
|
+ struct i40iw_cqp_request *cqp_request = NULL;
|
|
|
+ struct cqp_commands_info *pcmdinfo = NULL;
|
|
|
+ u32 i, pending_work, wqe_idx;
|
|
|
+
|
|
|
+ pending_work = I40IW_RING_WORK_AVAILABLE(cqp->sc_cqp.sq_ring);
|
|
|
+ wqe_idx = I40IW_RING_GETCURRENT_TAIL(cqp->sc_cqp.sq_ring);
|
|
|
+ for (i = 0; i < pending_work; i++) {
|
|
|
+ cqp_request = (struct i40iw_cqp_request *)(unsigned long)cqp->scratch_array[wqe_idx];
|
|
|
+ if (cqp_request)
|
|
|
+ i40iw_free_pending_cqp_request(cqp, cqp_request);
|
|
|
+ wqe_idx = (wqe_idx + 1) % I40IW_RING_GETSIZE(cqp->sc_cqp.sq_ring);
|
|
|
+ }
|
|
|
+
|
|
|
+ while (!list_empty(&dev->cqp_cmd_head)) {
|
|
|
+ pcmdinfo = (struct cqp_commands_info *)i40iw_remove_head(&dev->cqp_cmd_head);
|
|
|
+ cqp_request = container_of(pcmdinfo, struct i40iw_cqp_request, info);
|
|
|
+ if (cqp_request)
|
|
|
+ i40iw_free_pending_cqp_request(cqp, cqp_request);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* i40iw_free_qp - callback after destroy cqp completes
|
|
|
* @cqp_request: cqp request for destroy qp
|