return (hoststatus << 16) | tgt_status;
 }
 
+/*
+ * turn the dma address from an inbox into a ccb pointer
+ * This is rather inefficient.
+ */
+static struct blogic_ccb *
+blogic_inbox_to_ccb(struct blogic_adapter *adapter, struct blogic_inbox *inbox)
+{
+       struct blogic_ccb *ccb;
+
+       for (ccb = adapter->all_ccbs; ccb; ccb = ccb->next_all)
+               if (inbox->ccb == ccb->dma_handle)
+                       break;
+
+       return ccb;
+}
 
 /*
   blogic_scan_inbox scans the Incoming Mailboxes saving any
   Incoming Mailbox entries for completion processing.
 */
-
 static void blogic_scan_inbox(struct blogic_adapter *adapter)
 {
        /*
        enum blogic_cmplt_code comp_code;
 
        while ((comp_code = next_inbox->comp_code) != BLOGIC_INBOX_FREE) {
-               /*
-                  We are only allowed to do this because we limit our
-                  architectures we run on to machines where bus_to_virt(
-                  actually works.  There *needs* to be a dma_addr_to_virt()
-                  in the new PCI DMA mapping interface to replace
-                  bus_to_virt() or else this code is going to become very
-                  innefficient.
-                */
-               struct blogic_ccb *ccb =
-                       (struct blogic_ccb *) bus_to_virt(next_inbox->ccb);
-               if (comp_code != BLOGIC_CMD_NOTFOUND) {
+               struct blogic_ccb *ccb = blogic_inbox_to_ccb(adapter, next_inbox);
+               if (!ccb) {
+                       /*
+                        * This should never happen, unless the CCB list is
+                        * corrupted in memory.
+                        */
+                       blogic_warn("Could not find CCB for dma address %x\n", adapter, next_inbox->ccb);
+               } else if (comp_code != BLOGIC_CMD_NOTFOUND) {
                        if (ccb->status == BLOGIC_CCB_ACTIVE ||
                                        ccb->status == BLOGIC_CCB_RESET) {
                                /*