Thread (3 messages) 3 messages, 3 authors, 2007-07-25

Re: [PATCH 12/12] drivers: PMC MSP71xx security engine driver

From: Evgeniy Polyakov <hidden>
Date: 2007-06-29 09:51:24

Hi Marc.

On Thu, Jun 28, 2007 at 01:49:13PM -0600, Marc St-Jean (stjeanma@pmc-sierra.com) wrote:
+static int
+sec_init_queues(void)
+{
+	int i;
+	struct workq *wq;
+	struct compq *cq;
+
+	/*
+	 * Allocate uncached space for hw_ptr values.
+	 * NOTE: status ptr value is not currently used.
+	 */
+	status_ptr = dma_alloc_coherent(NULL, sizeof(int), &status_dma_addr,
+					GFP_KERNEL);
+	DBG_SEC("Allocated status ptr memory at 0x%p (0x%08x)\n",
+			status_ptr, status_dma_addr);
+	if (!status_ptr)
+		return -ENOMEM;
+
+	for (i = 0; i < HW_NR_COMP_QUEUES; i++) {
+		void *base; /* slowpath virtual address of base */
+		dma_addr_t base_dma_addr; /* DMA bus address of base */
+
+		base = dma_alloc_coherent(NULL, SEC_COMP_Q_SIZE,
+				&base_dma_addr, GFP_KERNEL);
+		DBG_SEC("Allocated CQ%d at 0x%p (0x%08x)\n",
+			i, base, base_dma_addr);
+		if (!base)
+			return -ENOMEM;
This leaks allocations.
+		cq = &sec_comp_queues[i];
+
+		cq->compq_lock = SPIN_LOCK_UNLOCKED;
+		cq->cq_regs = &sec2_regs->cq[i];
+		cq->base = base;
+		cq->base_dma_addr = base_dma_addr;
+		cq->out = 0;
+
+		cq->cq_regs->ofst_ptr = (unsigned int *)status_dma_addr;
+		cq->cq_regs->base = (unsigned char *)cq->base_dma_addr;
+		cq->cq_regs->size = SEC_COMP_Q_SIZE;
+		cq->cq_regs->in = 0;
+		cq->cq_regs->out = 0;
+	}
+
+	for (i = 0; i < HW_NR_WORK_QUEUES; i++) {
+		void *base; /* slowpath virtual address of base */
+		dma_addr_t base_dma_addr; /* DMA bus address of base */
+
+		base = dma_alloc_coherent(NULL, SEC_WORK_Q_SIZE,
+					&base_dma_addr, GFP_KERNEL);
+		DBG_SEC("Allocated WQ%d at 0x%p (0x%08x)\n",
+			i, base, base_dma_addr);
+		if (!base)
+			return -ENOMEM;
This too.
+		wq = &sec_work_queues[i];
+
+		init_waitqueue_head(&wq->space_wait);
+
+		wq->workq_lock = SPIN_LOCK_UNLOCKED;
+		wq->wq_regs = &sec2_regs->wq[i];
+		wq->base = base;
+		wq->base_dma_addr = base_dma_addr;
+		wq->in = 0;
+		wq->low_water = SEC_WORK_Q_SIZE >> 1; /* wake when half full */
+
+		wq->wq_regs->ofst_ptr = (unsigned int *)status_dma_addr;
+		wq->wq_regs->base = (unsigned char *)wq->base_dma_addr;
+		wq->wq_regs->size = SEC_WORK_Q_SIZE;
+		wq->wq_regs->in = 0;
+		wq->wq_regs->out = 0;
+	}
+	
+	debug_dump_sec_regs();
+
+	return 0;
+}
+
+static int __init
+msp_secv2_init(void)
Shouldn't this and other places be marked as __devinit?

...
+static irqreturn_t
+msp_secv2_interrupt(int irq, void *dev_id)
+{
+	/*
+	 * TODO: This clears all interrupts, and assumes
+	 * that the cause was a completion queue update.
+	 */
+	unsigned int status;
+
+	status = sec2_regs->sis;
+	sec2_regs->sis = /* ~status */ 0;
+
+	DBG_SEC("interrupt irq %d status was %x\n", irq, status);
+
+	poll_completion();
+
+	return IRQ_HANDLED;
+}
Irqs can not be shared?

...
+static int
+poll_completion(void)
+{
+	struct compq *cq;
+	int flags;
+	int work_ct = 0;
+	
+	/*
+	 * Check IPSEC engine register to see if at least one
+	 * completion element is in completion queue.
+	 */
+	cq = sec_comp_queues;
+	spin_lock_irqsave(&cq->compq_lock, flags);
This lock seems not to protect against desc_do_work() for example, but
there are register/mmio access under both - what is a locking rules
there?

-- 
	Evgeniy Polyakov
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help