VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / message / i2o / i2o_core.c
index e5afe8d..66fa24b 100644 (file)
@@ -354,7 +354,7 @@ static void i2o_core_reply(struct i2o_handler *h, struct i2o_controller *c,
 
        if (msg[0] & MSG_FAIL) // Fail bit is set
        {
-               u32 *preserved_msg = (u32*)(c->mem_offset + msg[7]);
+               u32 *preserved_msg = (u32*)(c->msg_virt + msg[7]);
 
                i2o_report_status(KERN_INFO, "i2o_core", msg);
                i2o_dump_message(preserved_msg);
@@ -831,12 +831,14 @@ static int i2o_issue_claim(u32 cmd, struct i2o_controller *c, int tid, u32 type)
  
 int i2o_claim_device(struct i2o_device *d, struct i2o_handler *h)
 {
+       int ret = 0;
+
        down(&i2o_configuration_lock);
        if (d->owner) {
                printk(KERN_INFO "Device claim called, but dev already owned by %s!",
                       h->name);
-               up(&i2o_configuration_lock);
-               return -EBUSY;
+               ret = -EBUSY;
+               goto out;
        }
        d->owner=h;
 
@@ -844,10 +846,11 @@ int i2o_claim_device(struct i2o_device *d, struct i2o_handler *h)
                           I2O_CLAIM_PRIMARY))
        {
                d->owner = NULL;
-               return -EBUSY;
+               ret = -EBUSY;
        }
+out:
        up(&i2o_configuration_lock);
-       return 0;
+       return ret;
 }
 
 /**
@@ -1794,7 +1797,7 @@ static int i2o_reset_controller(struct i2o_controller *c)
        m=i2o_wait_message(c, "AdapterReset");
        if(m==0xFFFFFFFF)       
                return -ETIMEDOUT;
-       msg=(u32 *)(c->mem_offset+m);
+       msg=(u32 *)(c->msg_virt+m);
        
        status = pci_alloc_consistent(c->pdev, 4, &status_phys);
        if(status == NULL) {
@@ -1923,7 +1926,7 @@ int i2o_status_get(struct i2o_controller *c)
        m=i2o_wait_message(c, "StatusGet");
        if(m==0xFFFFFFFF)
                return -ETIMEDOUT;      
-       msg=(u32 *)(c->mem_offset+m);
+       msg=(u32 *)(c->msg_virt+m);
 
        msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_0;
        msg[1]=I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID;
@@ -2344,7 +2347,7 @@ int i2o_init_outbound_q(struct i2o_controller *c)
        m=i2o_wait_message(c, "OutboundInit");
        if(m==0xFFFFFFFF)
                return -ETIMEDOUT;
-       msg=(u32 *)(c->mem_offset+m);
+       msg=(u32 *)(c->msg_virt+m);
 
        status = pci_alloc_consistent(c->pdev, 4, &status_phys);
        if (status==NULL) {
@@ -2618,7 +2621,7 @@ static int i2o_build_sys_table(void)
                sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
                sys_tbl->iops[count].iop_capabilities = 
                                iop->status_block->iop_capabilities;
-               sys_tbl->iops[count].inbound_low = iop->post_port;
+               sys_tbl->iops[count].inbound_low = (u32)iop->post_port;
                sys_tbl->iops[count].inbound_high = 0;  // FIXME: 64-bit support
 
                count++;
@@ -2666,7 +2669,7 @@ int i2o_post_this(struct i2o_controller *c, u32 *data, int len)
                       c->name);
                return -ETIMEDOUT;
        }
-       msg = (u32 *)(c->mem_offset + m);
+       msg = (u32 *)(c->msg_virt + m);
        memcpy_toio(msg, data, len);
        i2o_post_message(c,m);
        return 0;
@@ -3592,7 +3595,9 @@ static void i2o_pci_dispose(struct i2o_controller *c)
        I2O_IRQ_WRITE32(c,0xFFFFFFFF);
        if(c->irq > 0)
                free_irq(c->irq, c);
-       iounmap(((u8 *)c->post_port)-0x40);
+       iounmap(c->base_virt);
+       if(c->raptor)
+               iounmap(c->msg_virt);
 
 #ifdef CONFIG_MTRR
        if(c->mtrr_reg0 > 0)
@@ -3633,9 +3638,12 @@ int __init i2o_pci_install(struct pci_dev *dev)
 {
        struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller),
                                                GFP_KERNEL);
-       unsigned long mem;
-       u32 memptr = 0;
-       u32 size;
+       void *bar0_virt;
+       void *bar1_virt;
+       unsigned long bar0_phys = 0;
+       unsigned long bar1_phys = 0;
+       unsigned long bar0_size = 0;
+       unsigned long bar1_size = 0;
        
        int i;
 
@@ -3646,37 +3654,9 @@ int __init i2o_pci_install(struct pci_dev *dev)
        }
        memset(c, 0, sizeof(*c));
 
-       for(i=0; i<6; i++)
-       {
-               /* Skip I/O spaces */
-               if(!(pci_resource_flags(dev, i) & IORESOURCE_IO))
-               {
-                       memptr = pci_resource_start(dev, i);
-                       break;
-               }
-       }
-       
-       if(i==6)
-       {
-               printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n");
-               kfree(c);
-               return -EINVAL;
-       }
-       
-       size = dev->resource[i].end-dev->resource[i].start+1;   
-       /* Map the I2O controller */
-       
-       printk(KERN_INFO "i2o: PCI I2O controller at 0x%08X size=%d\n", memptr, size);
-       mem = (unsigned long)ioremap(memptr, size);
-       if(mem==0)
-       {
-               printk(KERN_ERR "i2o: Unable to map controller.\n");
-               kfree(c);
-               return -EINVAL;
-       }
-
        c->irq = -1;
        c->dpt = 0;
+       c->raptor = 0;
        c->short_req = 0;
        c->pdev = dev;
 
@@ -3684,13 +3664,6 @@ int __init i2o_pci_install(struct pci_dev *dev)
        c->context_list_lock = SPIN_LOCK_UNLOCKED;
 #endif
 
-       c->irq_mask = mem+0x34;
-       c->post_port = mem+0x40;
-       c->reply_port = mem+0x44;
-
-       c->mem_phys = memptr;
-       c->mem_offset = mem;
-       
        /*
         *      Cards that fall apart if you hit them with large I/O
         *      loads...
@@ -3701,6 +3674,7 @@ int __init i2o_pci_install(struct pci_dev *dev)
                c->short_req = 1;
                printk(KERN_INFO "I2O: Symbios FC920 workarounds activated.\n");
        }
+
        if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE)
        {
                c->promise = 1;
@@ -3712,15 +3686,85 @@ int __init i2o_pci_install(struct pci_dev *dev)
         *      them
         */
         
-       if(dev->vendor == PCI_VENDOR_ID_DPT)
+       if(dev->vendor == PCI_VENDOR_ID_DPT) {
                c->dpt=1;
+               if(dev->device == 0xA511)
+                       c->raptor=1;
+       }
+
+       for(i=0; i<6; i++)
+       {
+               /* Skip I/O spaces */
+               if(!(pci_resource_flags(dev, i) & IORESOURCE_IO))
+               {
+                       if(!bar0_phys)
+                       {
+                               bar0_phys = pci_resource_start(dev, i);
+                               bar0_size = pci_resource_len(dev, i);
+                               if(!c->raptor)
+                                       break;
+                       }
+                       else
+                       {
+                               bar1_phys = pci_resource_start(dev, i);
+                               bar1_size = pci_resource_len(dev, i);
+                               break;
+                       }
+               }
+       }
+
+       if(i==6)
+       {
+               printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n");
+               kfree(c);
+               return -EINVAL;
+       }
+
+
+       /* Map the I2O controller */
+       if(!c->raptor)
+               printk(KERN_INFO "i2o: PCI I2O controller at %08lX size=%ld\n", bar0_phys, bar0_size);
+       else
+               printk(KERN_INFO "i2o: PCI I2O controller\n    BAR0 at 0x%08lX size=%ld\n    BAR1 at 0x%08lX size=%ld\n", bar0_phys, bar0_size, bar1_phys, bar1_size);
+
+       bar0_virt = ioremap(bar0_phys, bar0_size);
+       if(bar0_virt==0)
+       {
+               printk(KERN_ERR "i2o: Unable to map controller.\n");
+               kfree(c);
+               return -EINVAL;
+       }
+
+       if(c->raptor)
+       {
+               bar1_virt = ioremap(bar1_phys, bar1_size);
+               if(bar1_virt==0)
+               {
+                       printk(KERN_ERR "i2o: Unable to map controller.\n");
+                       kfree(c);
+                       iounmap(bar0_virt);
+                       return -EINVAL;
+               }
+       } else {
+               bar1_virt = bar0_virt;
+               bar1_phys = bar0_phys;
+               bar1_size = bar0_size;
+       }
+
+       c->irq_mask = bar0_virt+0x34;
+       c->post_port = bar0_virt+0x40;
+       c->reply_port = bar0_virt+0x44;
+
+       c->base_phys = bar0_phys;
+       c->base_virt = bar0_virt;
+       c->msg_phys = bar1_phys;
+       c->msg_virt = bar1_virt;
        
        /* 
         * Enable Write Combining MTRR for IOP's memory region
         */
 #ifdef CONFIG_MTRR
-       c->mtrr_reg0 =
-               mtrr_add(c->mem_phys, size, MTRR_TYPE_WRCOMB, 1);
+       c->mtrr_reg0 = mtrr_add(c->base_phys, bar0_size, MTRR_TYPE_WRCOMB, 1);
        /*
         * If it is an INTEL i960 I/O processor then set the first 64K to
         * Uncacheable since the region contains the Messaging unit which
@@ -3730,14 +3774,16 @@ int __init i2o_pci_install(struct pci_dev *dev)
        if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT)
        {
                printk(KERN_INFO "I2O: MTRR workaround for Intel i960 processor\n"); 
-               c->mtrr_reg1 =  mtrr_add(c->mem_phys, 65536, MTRR_TYPE_UNCACHABLE, 1);
+               c->mtrr_reg1 =  mtrr_add(c->base_phys, 65536, MTRR_TYPE_UNCACHABLE, 1);
                if(c->mtrr_reg1< 0)
                {
                        printk(KERN_INFO "i2o_pci: Error in setting MTRR_TYPE_UNCACHABLE\n");
-                       mtrr_del(c->mtrr_reg0, c->mem_phys, size);
+                       mtrr_del(c->mtrr_reg0, c->msg_phys, bar1_size);
                        c->mtrr_reg0 = -1;
                }
        }
+       if(c->raptor)
+               c->mtrr_reg1 = mtrr_add(c->msg_phys, bar1_size, MTRR_TYPE_WRCOMB, 1);
 
 #endif
 
@@ -3749,7 +3795,9 @@ int __init i2o_pci_install(struct pci_dev *dev)
        {
                printk(KERN_ERR "i2o: Unable to install controller.\n");
                kfree(c);
-               iounmap((void *)mem);
+               iounmap(bar0_virt);
+               if(c->raptor)
+                       iounmap(bar1_virt);
                return i;
        }
 
@@ -3764,7 +3812,9 @@ int __init i2o_pci_install(struct pci_dev *dev)
                                c->name, dev->irq);
                        c->irq = -1;
                        i2o_delete_controller(c);
-                       iounmap((void *)mem);
+                       iounmap(bar0_virt);
+                       if(c->raptor)
+                               iounmap(bar1_virt);
                        return -EBUSY;
                }
        }
@@ -3797,10 +3847,12 @@ int __init i2o_pci_scan(void)
 
        while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
        {
-               if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O)
+               if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O &&
+                  (dev->vendor!=PCI_VENDOR_ID_DPT || dev->device!=0xA511))
                        continue;
 
-               if((dev->class&0xFF)>1)
+               if((dev->class>>8)==PCI_CLASS_INTELLIGENT_I2O &&
+                  (dev->class&0xFF)>1)
                {
                        printk(KERN_INFO "i2o: I2O Controller found but does not support I2O 1.5 (skipping).\n");
                        continue;