patch-2.4.22 linux-2.4.22/drivers/scsi/aacraid/dpcsup.c

Next file: linux-2.4.22/drivers/scsi/aacraid/linit.c
Previous file: linux-2.4.22/drivers/scsi/aacraid/commsup.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.21/drivers/scsi/aacraid/dpcsup.c linux-2.4.22/drivers/scsi/aacraid/dpcsup.c
@@ -74,12 +74,14 @@
 	 */
 	while(aac_consumer_get(dev, q, &entry))
 	{
-		int fast;
+		u32 fast ;
+		fast = (entry->addr & cpu_to_le32(0x01));
+//		fib = &dev->fibs[(entry->addr >> 1)];
+//		hwfib = fib->hw_fib;
+		hwfib = bus_to_virt(le32_to_cpu(entry->addr & cpu_to_le32(~0x01)));
+		fib = &dev->fibs[hwfib->header.SenderData];
 
-		fast = (int) (entry->addr & 0x01);
-		hwfib = addr2fib(entry->addr & ~0x01);
 		aac_consumer_free(dev, q, HostNormRespQueue);
-		fib = &dev->fibs[hwfib->header.SenderData];
 		/*
 		 *	Remove this fib from the Outstanding I/O queue.
 		 *	But only if it has not already been timed out.
@@ -169,30 +171,51 @@
 	 *	up the waiters until there are no more QEs. We then return
 	 *	back to the system.
 	 */
+	dprintk((KERN_INFO
+	  "dev=%p, dev->comm_phys=%x, dev->comm_addr=%p, dev->comm_size=%u\n",
+	  dev, (u32)dev->comm_phys, dev->comm_addr, (unsigned)dev->comm_size));
+
 	while(aac_consumer_get(dev, q, &entry))
 	{
-		struct hw_fib * fib;
-		fib = addr2fib(entry->addr);
+		struct fib fibctx;
+		struct fib *fib = &fibctx;
+		u32 hw_fib_pa = le32_to_cpu(entry->addr & cpu_to_le32(~0x01));
+		struct hw_fib * hw_fib_va = ((dev->comm_phys <= hw_fib_pa)
+		 && (hw_fib_pa < (dev->comm_phys + dev->comm_size)))
+		  ? dev->comm_addr + (hw_fib_pa - dev->comm_phys)
+		  : /* inconceivable */ bus_to_virt(hw_fib_pa);
+		dprintk((KERN_INFO "hw_fib_pa=%x hw_fib_va=%p\n", hw_fib_pa, hw_fib_va));
 
-		if (dev->aif_thread) {
-		        list_add_tail(&fib->header.FibLinks, &q->cmdq);
+		/*
+		 *	Allocate a FIB at all costs. For non queued stuff
+		 *	we can just use the stack so we are happy. We need
+		 *	a fib object in order to manage the linked lists
+		 */
+		if (dev->aif_thread)
+			if((fib = kmalloc(sizeof(struct fib), GFP_ATOMIC))==NULL)
+				fib = &fibctx;
+			
+		memset(fib, 0, sizeof(struct fib));
+		INIT_LIST_HEAD(&fib->fiblink);
+		fib->type = FSAFS_NTC_FIB_CONTEXT;
+		fib->size = sizeof(struct fib);
+		fib->hw_fib = hw_fib_va;
+		fib->data = hw_fib_va->data;
+		fib->dev = dev;
+		
+		if (dev->aif_thread && fib != &fibctx)
+		{		
+			list_add_tail(&fib->fiblink, &q->cmdq);
 	 	        aac_consumer_free(dev, q, HostNormCmdQueue);
 		        wake_up_interruptible(&q->cmdready);
 		} else {
-			struct fib fibctx;
 	 	        aac_consumer_free(dev, q, HostNormCmdQueue);
 			spin_unlock_irqrestore(q->lock, flags);
-			memset(&fibctx, 0, sizeof(struct fib));
-			fibctx.type = FSAFS_NTC_FIB_CONTEXT;
-			fibctx.size = sizeof(struct fib);
-			fibctx.fib = fib;
-			fibctx.data = fib->data;
-			fibctx.dev = dev;
 			/*
 			 *	Set the status of this FIB
 			 */
-			*(u32 *)fib->data = cpu_to_le32(ST_OK);
-			fib_adapter_complete(&fibctx, sizeof(u32));
+			*(u32 *)hw_fib_va->data = cpu_to_le32(ST_OK);
+			fib_adapter_complete(fib, sizeof(u32));
 			spin_lock_irqsave(q->lock, flags);
 		}		
 	}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)