} 
void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn){	struct mthca_cq *cq;	struct mthca_cqe *cqe;	int prod_index;	int nfreed = 0;	spin_lock_irq(&dev->cq_table.lock);	cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1));	if (cq)		atomic_inc(&cq->refcount);	spin_unlock_irq(&dev->cq_table.lock);	if (!cq)		return;	spin_lock_irq(&cq->lock);	/*	 * First we need to find the current producer index, so we	 * know where to start cleaning from.  It doesn't matter if HW	 * adds new entries after this loop -- the QP we're worried	 * about is already in RESET, so the new entries won't come	 * from our QP and therefore don't need to be checked.	 */	for (prod_index = cq->cons_index;	     cqe_sw(cq, prod_index & cq->ibcq.cqe);	     ++prod_index)		if (prod_index == cq->cons_index + cq->ibcq.cqe)			break;	if (0)		mthca_dbg(dev, "Cleaning QPN %06x from CQN %06x; ci %d, pi %d\n",			  qpn, cqn, cq->cons_index, prod_index);	/*	 * Now sweep backwards through the CQ, removing CQ entries	 * that match our QP by copying older entries on top of them.	 */	while (prod_index > cq->cons_index) {		cqe = get_cqe(cq, (prod_index - 1) & cq->ibcq.cqe);		if (cqe->my_qpn == cpu_to_be32(qpn))			++nfreed;		else if (nfreed)			memcpy(get_cqe(cq, (prod_index - 1 + nfreed) &				       cq->ibcq.cqe),			       cqe,			       MTHCA_CQ_ENTRY_SIZE);		--prod_index;	}	if (nfreed) {		wmb();		cq->cons_index += nfreed;		update_cons_index(dev, cq, nfreed);	}	spin_unlock_irq(&cq->lock);	if (atomic_dec_and_test(&cq->refcount))		wake_up(&cq->wait);}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/ec34a922d243c3401a694450734e9effb2bafbfe/mthca_cq.c/buggy/drivers/infiniband/hw/mthca/mthca_cq.c