PATCH: 2.5.28 (resend #1) Update i2o core functionality to 2.5

From: Alan Cox (alan@irongate.swansea.linux.org.uk)
Date: Thu Jul 25 2002 - 09:47:14 EST


diff -u --new-file --recursive --exclude-from /usr/src/exclude linux-2.5.28/drivers/message/i2o/i2o_config.c linux-2.5.28-ac1/drivers/message/i2o/i2o_config.c
--- linux-2.5.28/drivers/message/i2o/i2o_config.c Thu Jul 25 10:49:25 2002
+++ linux-2.5.28-ac1/drivers/message/i2o/i2o_config.c Sun Jul 21 19:56:10 2002
@@ -1,7 +1,7 @@
 /*
  * I2O Configuration Interface Driver
  *
- * (C) Copyright 1999 Red Hat Software
+ * (C) Copyright 1999-2002 Red Hat
  *
  * Written by Alan Cox, Building Number Three Ltd
  *
@@ -16,17 +16,17 @@
  * - Fixed ioctl_swdl()
  * Modified 10/04/1999 by Taneli Vähäkangas
  * - Changed ioctl_swdl(), implemented ioctl_swul() and ioctl_swdel()
- * Modified 11/18/199 by Deepak Saxena
+ * Modified 11/18/1999 by Deepak Saxena
  * - Added event managmenet support
  *
+ * 2.4 rewrite ported to 2.5 - Alan Cox <alan@redhat.com>
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
 
-#error Please convert me to Documentation/DMA-mapping.txt
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -47,7 +47,7 @@
 static spinlock_t i2o_config_lock = SPIN_LOCK_UNLOCKED;
 struct wait_queue *i2o_wait_queue;
 
-#define MODINC(x,y) (x = x++ % y)
+#define MODINC(x,y) ((x) = ((x) + 1) % (y))
 
 struct i2o_cfg_info
 {
@@ -279,7 +279,14 @@
                 if(c)
                 {
                         foo[i] = 1;
- i2o_unlock_controller(c);
+ if(pci_set_dma_mask(c->pdev, 0xffffffff))
+ {
+ printk(KERN_WARNING "i2o_config : No suitable DMA available on controller %d\n", i);
+ i2o_unlock_controller(c);
+ continue;
+ }
+
+ i2o_unlock_controller(c);
                 }
                 else
                 {
@@ -445,11 +452,12 @@
         struct i2o_controller *c;
         u8 *res = NULL;
         void *query = NULL;
+ dma_addr_t query_phys, res_phys;
         int ret = 0;
         int token;
         u32 len;
         u32 reslen;
- u32 msg[MSG_FRAME_SIZE/4];
+ u32 msg[MSG_FRAME_SIZE];
 
         if(copy_from_user(&kcmd, cmd, sizeof(struct i2o_html)))
         {
@@ -475,7 +483,7 @@
 
         if(kcmd.qlen) /* Check for post data */
         {
- query = kmalloc(kcmd.qlen, GFP_KERNEL);
+ query = pci_alloc_consistent(c->pdev, kcmd.qlen, &query_phys);
                 if(!query)
                 {
                         i2o_unlock_controller(c);
@@ -485,16 +493,16 @@
                 {
                         i2o_unlock_controller(c);
                         printk(KERN_INFO "i2o_config: could not get query\n");
- kfree(query);
+ pci_free_consistent(c->pdev, kcmd.qlen, query, query_phys);
                         return -EFAULT;
                 }
         }
 
- res = kmalloc(65536, GFP_KERNEL);
+ res = pci_alloc_consistent(c->pdev, 65536, &res_phys);
         if(!res)
         {
                 i2o_unlock_controller(c);
- kfree(query);
+ pci_free_consistent(c->pdev, kcmd.qlen, query, query_phys);
                 return -ENOMEM;
         }
 
@@ -503,7 +511,7 @@
         msg[3] = 0;
         msg[4] = kcmd.page;
         msg[5] = 0xD0000000|65536;
- msg[6] = virt_to_bus(res);
+ msg[6] = res_phys;
         if(!kcmd.qlen) /* Check for post data */
                 msg[0] = SEVEN_WORD_MSG_SIZE|SGL_OFFSET_5;
         else
@@ -511,7 +519,7 @@
                 msg[0] = NINE_WORD_MSG_SIZE|SGL_OFFSET_5;
                 msg[5] = 0x50000000|65536;
                 msg[7] = 0xD4000000|(kcmd.qlen);
- msg[8] = virt_to_bus(query);
+ msg[8] = query_phys;
         }
         /*
         Wait for a considerable time till the Controller
@@ -519,7 +527,7 @@
         take more time to process this request if there are
         many devices connected to it.
         */
- token = i2o_post_wait_mem(c, msg, 9*4, 400, query, res);
+ token = i2o_post_wait_mem(c, msg, 9*4, 400, query, res, query_phys, res_phys, kcmd.qlen, 65536);
         if(token < 0)
         {
                 printk(KERN_DEBUG "token = %#10x\n", token);
@@ -527,10 +535,10 @@
                 
                 if(token != -ETIMEDOUT)
                 {
- kfree(res);
- if(kcmd.qlen) kfree(query);
+ pci_free_consistent(c->pdev, 65536, res, res_phys);
+ if(kcmd.qlen)
+ pci_free_consistent(c->pdev, kcmd.qlen, query, query_phys);
                 }
-
                 return token;
         }
         i2o_unlock_controller(c);
@@ -542,9 +550,9 @@
         if(copy_to_user(kcmd.resbuf, res, len))
                 ret = -EFAULT;
 
- kfree(res);
- if(kcmd.qlen)
- kfree(query);
+ pci_free_consistent(c->pdev, 65536, res, res_phys);
+ if(kcmd.qlen)
+ pci_free_consistent(c->pdev, kcmd.qlen, query, query_phys);
 
         return ret;
 }
@@ -558,6 +566,7 @@
         u32 msg[9];
         unsigned int status = 0, swlen = 0, fragsize = 8192;
         struct i2o_controller *c;
+ dma_addr_t buffer_phys;
 
         if(copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
                 return -EFAULT;
@@ -580,7 +589,7 @@
         if(!c)
                 return -ENXIO;
 
- buffer=kmalloc(fragsize, GFP_KERNEL);
+ buffer=pci_alloc_consistent(c->pdev, fragsize, &buffer_phys);
         if (buffer==NULL)
         {
                 i2o_unlock_controller(c);
@@ -597,14 +606,14 @@
         msg[5]= swlen;
         msg[6]= kxfer.sw_id;
         msg[7]= (0xD0000000 | fragsize);
- msg[8]= virt_to_bus(buffer);
+ msg[8]= buffer_phys;
 
 // printk("i2o_config: swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
- status = i2o_post_wait_mem(c, msg, sizeof(msg), 60, buffer, NULL);
+ status = i2o_post_wait_mem(c, msg, sizeof(msg), 60, buffer, NULL, buffer_phys, 0, fragsize, 0);
 
         i2o_unlock_controller(c);
         if(status != -ETIMEDOUT)
- kfree(buffer);
+ pci_free_consistent(c->pdev, fragsize, buffer, buffer_phys);
         
         if (status != I2O_POST_WAIT_OK)
         {
@@ -626,7 +635,8 @@
         u32 msg[9];
         unsigned int status = 0, swlen = 0, fragsize = 8192;
         struct i2o_controller *c;
-
+ dma_addr_t buffer_phys;
+
         if(copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
                 return -EFAULT;
                 
@@ -648,7 +658,7 @@
         if(!c)
                 return -ENXIO;
                 
- buffer=kmalloc(fragsize, GFP_KERNEL);
+ buffer=pci_alloc_consistent(c->pdev, fragsize, &buffer_phys);
         if (buffer==NULL)
         {
                 i2o_unlock_controller(c);
@@ -663,22 +673,22 @@
         msg[5]= swlen;
         msg[6]= kxfer.sw_id;
         msg[7]= (0xD0000000 | fragsize);
- msg[8]= virt_to_bus(buffer);
+ msg[8]= buffer_phys;
         
 // printk("i2o_config: swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
- status = i2o_post_wait_mem(c, msg, sizeof(msg), 60, buffer, NULL);
+ status = i2o_post_wait_mem(c, msg, sizeof(msg), 60, buffer, NULL, buffer_phys, 0, fragsize, 0);
         i2o_unlock_controller(c);
         
         if (status != I2O_POST_WAIT_OK)
         {
                 if(status != -ETIMEDOUT)
- kfree(buffer);
+ pci_free_consistent(c->pdev, fragsize, buffer, buffer_phys);
                 printk(KERN_INFO "i2o_config: swul failed, DetailedStatus = %d\n", status);
                 return status;
         }
         
         __copy_to_user(kxfer.buf, buffer, fragsize);
- kfree(buffer);
+ pci_free_consistent(c->pdev, fragsize, buffer, buffer_phys);
         
         return 0;
 }
@@ -849,6 +859,7 @@
         struct i2o_cfg_info *p1, *p2;
         unsigned long flags;
 
+ lock_kernel();
         p1 = p2 = NULL;
 
         spin_lock_irqsave(&i2o_config_lock, flags);
@@ -871,6 +882,7 @@
                 p1 = p1->next;
         }
         spin_unlock_irqrestore(&i2o_config_lock, flags);
+ unlock_kernel();
 
         return 0;
 }
@@ -908,11 +920,7 @@
         &config_fops
 };
 
-#ifdef MODULE
-int init_module(void)
-#else
-int __init i2o_config_init(void)
-#endif
+static int __init i2o_config_init(void)
 {
         printk(KERN_INFO "I2O configuration manager v 0.04.\n");
         printk(KERN_INFO " (C) Copyright 1999 Red Hat Software\n");
@@ -946,9 +954,7 @@
         return 0;
 }
 
-#ifdef MODULE
-
-void cleanup_module(void)
+static void i2o_config_exit(void)
 {
         misc_deregister(&i2o_miscdev);
         
@@ -958,8 +964,10 @@
                 i2o_remove_handler(&cfg_handler);
 }
  
+EXPORT_NO_SYMBOLS;
 MODULE_AUTHOR("Red Hat Software");
 MODULE_DESCRIPTION("I2O Configuration");
 MODULE_LICENSE("GPL");
 
-#endif
+module_init(i2o_config_init);
+module_exit(i2o_config_exit);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux-2.5.28/drivers/message/i2o/i2o_core.c linux-2.5.28-ac1/drivers/message/i2o/i2o_core.c
--- linux-2.5.28/drivers/message/i2o/i2o_core.c Thu Jul 25 10:49:25 2002
+++ linux-2.5.28-ac1/drivers/message/i2o/i2o_core.c Sun Jul 21 15:21:36 2002
@@ -1,7 +1,7 @@
 /*
  * Core I2O structure management
  *
- * (C) Copyright 1999 Red Hat Software
+ * (C) Copyright 1999-2002 Red Hat Software
  *
  * Written by Alan Cox, Building Number Three Ltd
  *
@@ -19,11 +19,12 @@
  * Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
  * Deepak Saxena <deepak@plexity.net>
  * Boji T Kannanthanam <boji.t.kannanthanam@intel.com>
+ *
+ * Ported to Linux 2.5 by
+ * Alan Cox <alan@redhat.com>
  *
  */
 
-#error Please convert me to Documentation/DMA-mapping.txt
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -72,7 +73,7 @@
 static int core_context;
 
 /* Initialization && shutdown functions */
-static void i2o_sys_init(void);
+void i2o_sys_init(void);
 static void i2o_sys_shutdown(void);
 static int i2o_reset_controller(struct i2o_controller *);
 static int i2o_reboot_event(struct notifier_block *, unsigned long , void *);
@@ -122,28 +123,6 @@
  */
 static spinlock_t i2o_dev_lock = SPIN_LOCK_UNLOCKED;
 
-#ifdef MODULE
-/*
- * Function table to send to bus specific layers
- * See <include/linux/i2o.h> for explanation of this
- */
-#ifdef CONFIG_I2O_PCI_MODULE
-static struct i2o_core_func_table i2o_core_functions =
-{
- i2o_install_controller,
- i2o_activate_controller,
- i2o_find_controller,
- i2o_unlock_controller,
- i2o_run_queue,
- i2o_delete_controller
-};
-
-extern int i2o_pci_core_attach(struct i2o_core_func_table *);
-extern void i2o_pci_core_detach(void);
-#endif /* CONFIG_I2O_PCI_MODULE */
-
-#endif /* MODULE */
-
 /*
  * Structures and definitions for synchronous message posting.
  * See i2o_post_wait() for description.
@@ -156,11 +135,14 @@
         wait_queue_head_t *wq; /* Wake up for caller (NULL for dead) */
         struct i2o_post_wait_data *next; /* Chain */
         void *mem[2]; /* Memory blocks to recover on failure path */
+ dma_addr_t phys[2]; /* Physical address of blocks to recover */
+ u32 size[2]; /* Size of blocks to recover */
 };
+
 static struct i2o_post_wait_data *post_wait_queue;
 static u32 post_wait_id; // Unique ID for each post_wait
 static spinlock_t post_wait_lock = SPIN_LOCK_UNLOCKED;
-static void i2o_post_wait_complete(u32, int);
+static void i2o_post_wait_complete(struct i2o_controller *, u32, int);
 
 /* OSM descriptor handler */
 static struct i2o_handler i2o_core_handler =
@@ -210,7 +192,7 @@
  
 static DECLARE_MUTEX(evt_sem);
 static DECLARE_COMPLETION(evt_dead);
-DECLARE_WAIT_QUEUE_HEAD(evt_wait);
+static DECLARE_WAIT_QUEUE_HEAD(evt_wait);
 
 static struct notifier_block i2o_reboot_notifier =
 {
@@ -269,7 +251,7 @@
                 else
                         status = I2O_POST_WAIT_OK;
         
- i2o_post_wait_complete(context, status);
+ i2o_post_wait_complete(c, context, status);
                 return;
         }
 
@@ -503,7 +485,7 @@
         {
                 if(i2o_controllers[i]==NULL)
                 {
- c->dlct = (i2o_lct*)kmalloc(8192, GFP_KERNEL);
+ c->dlct = (i2o_lct*)pci_alloc_consistent(c->pdev, 8192, &c->dlct_phys);
                         if(c->dlct==NULL)
                         {
                                 up(&i2o_configuration_lock);
@@ -613,13 +595,13 @@
                                 kfree(c->page_frame);
                         }
                         if(c->hrt)
- kfree(c->hrt);
+ pci_free_consistent(c->pdev, c->hrt_len, c->hrt, c->hrt_phys);
                         if(c->lct)
- kfree(c->lct);
+ pci_free_consistent(c->pdev, c->lct->table_size << 2, c->lct, c->lct_phys);
                         if(c->status_block)
- kfree(c->status_block);
+ pci_free_consistent(c->pdev, sizeof(i2o_status_block), c->status_block, c->status_block_phys);
                         if(c->dlct)
- kfree(c->dlct);
+ pci_free_consistent(c->pdev, 8192, c->dlct, c->dlct_phys);
 
                         i2o_controllers[c->unit]=NULL;
                         memcpy(name, c->name, strlen(c->name)+1);
@@ -1145,15 +1127,17 @@
                  */
                 if(c->lct->table_size < c->dlct->table_size)
                 {
+ dma_addr_t phys;
                         tmp = c->lct;
- c->lct = kmalloc(c->dlct->table_size<<2, GFP_KERNEL);
+ c->lct = pci_alloc_consistent(c->pdev, c->dlct->table_size<<2, &phys);
                         if(!c->lct)
                         {
                                 printk(KERN_ERR "%s: No memory for LCT!\n", c->name);
                                 c->lct = tmp;
                                 continue;
                         }
- kfree(tmp);
+ pci_free_consistent(tmp, c->lct->table_size << 2, c->lct, c->lct_phys);
+ c->lct_phys = phys;
                 }
                 memcpy(c->lct, c->dlct, c->dlct->table_size<<2);
         }
@@ -1186,7 +1170,8 @@
         {
                 struct i2o_handler *i;
                 /* Map the message from the page frame map to kernel virtual */
- m=(struct i2o_message *)(mv - (unsigned long)c->page_frame_map + (unsigned long)c->page_frame);
+ /* m=(struct i2o_message *)(mv - (unsigned long)c->page_frame_map + (unsigned long)c->page_frame); */
+ m=(struct i2o_message *)bus_to_virt(mv);
                 msg=(u32*)m;
 
                 /*
@@ -1665,6 +1650,7 @@
         struct i2o_controller *iop;
         u32 m;
         u8 *status;
+ dma_addr_t status_phys;
         u32 *msg;
         long time;
 
@@ -1681,8 +1667,8 @@
                 return -ETIMEDOUT;
         msg=(u32 *)(c->mem_offset+m);
         
- status=(void *)kmalloc(4, GFP_KERNEL);
- if(status==NULL) {
+ status = pci_alloc_consistent(c->pdev, 4, &status_phys);
+ if(status == NULL) {
                 printk(KERN_ERR "IOP reset failed - no free memory.\n");
                 return -ENOMEM;
         }
@@ -1694,7 +1680,7 @@
         msg[3]=0;
         msg[4]=0;
         msg[5]=0;
- msg[6]=virt_to_bus(status);
+ msg[6]=status_phys;
         msg[7]=0; /* 64bit host FIXME */
 
         i2o_post_message(c,m);
@@ -1706,7 +1692,7 @@
                 if((jiffies-time)>=20*HZ)
                 {
                         printk(KERN_ERR "IOP reset timeout.\n");
- // Better to leak this for safety: kfree(status);
+ // Better to leak this for safety: - status;
                         return -ETIMEDOUT;
                 }
                 schedule();
@@ -1762,7 +1748,7 @@
                 if (iop != c)
                         i2o_enable_controller(iop);
 
- kfree(status);
+ pci_free_consistent(c->pdev, 4, status, status_phys);
         return 0;
 }
 
@@ -1787,7 +1773,7 @@
         if (c->status_block == NULL)
         {
                 c->status_block = (i2o_status_block *)
- kmalloc(sizeof(i2o_status_block),GFP_KERNEL);
+ pci_alloc_consistent(c->pdev, sizeof(i2o_status_block), &c->status_block_phys);
                 if (c->status_block == NULL)
                 {
                         printk(KERN_CRIT "%s: Get Status Block failed; Out of memory.\n",
@@ -1810,7 +1796,7 @@
         msg[3]=0;
         msg[4]=0;
         msg[5]=0;
- msg[6]=virt_to_bus(c->status_block);
+ msg[6]=c->status_block_phys;
         msg[7]=0; /* 64bit host FIXME */
         msg[8]=sizeof(i2o_status_block); /* always 88 bytes */
 
@@ -1826,7 +1812,7 @@
                         printk(KERN_ERR "%s: Get status timeout.\n",c->name);
                         return -ETIMEDOUT;
                 }
- schedule();
+ yield();
                 barrier();
         }
 
@@ -1876,7 +1862,7 @@
 
         do {
                 if (c->hrt == NULL) {
- c->hrt=kmalloc(size, GFP_KERNEL);
+ c->hrt=pci_alloc_consistent(c->pdev, size, &c->hrt_phys);
                         if (c->hrt == NULL) {
                                 printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", c->name);
                                 return -ENOMEM;
@@ -1887,9 +1873,9 @@
                 msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID;
                 msg[3]= 0;
                 msg[4]= (0xD0000000 | size); /* Simple transaction */
- msg[5]= virt_to_bus(c->hrt); /* Dump it here */
+ msg[5]= c->hrt_phys; /* Dump it here */
 
- ret = i2o_post_wait_mem(c, msg, sizeof(msg), 20, c->hrt, NULL);
+ ret = i2o_post_wait_mem(c, msg, sizeof(msg), 20, c->hrt, NULL, c->hrt_phys, 0, size, 0);
                 
                 if(ret == -ETIMEDOUT)
                 {
@@ -1907,8 +1893,9 @@
                 }
 
                 if (c->hrt->num_entries * c->hrt->entry_len << 2 > size) {
- size = c->hrt->num_entries * c->hrt->entry_len << 2;
- kfree(c->hrt);
+ int new_size = c->hrt->num_entries * c->hrt->entry_len << 2;
+ pci_free_consistent(c->pdev, size, c->hrt, c->hrt_phys);
+ size = new_size;
                         c->hrt = NULL;
                 }
         } while (c->hrt == NULL);
@@ -1929,6 +1916,7 @@
 static int i2o_systab_send(struct i2o_controller *iop)
 {
         u32 msg[12];
+ dma_addr_t sys_tbl_phys;
         int ret;
         u32 *privbuf = kmalloc(16, GFP_KERNEL);
         if(privbuf == NULL)
@@ -2009,17 +1997,23 @@
           * Provide three SGL-elements:
           * System table (SysTab), Private memory space declaration and
           * Private i/o space declaration
- *
- * FIXME: provide these for controllers needing them
+ *
+ * Nasty one here. We can't use pci_alloc_consistent to send the
+ * same table to everyone. We have to go remap it for them all
           */
- msg[6] = 0x54000000 | sys_tbl_len;
- msg[7] = virt_to_bus(sys_tbl);
- msg[8] = 0x54000000 | 8;
- msg[9] = virt_to_bus(privbuf);
- msg[10] = 0xD4000000 | 8;
- msg[11] = virt_to_bus(privbuf+2);
+
+ sys_tbl_phys = pci_map_single(iop->pdev, sys_tbl, sys_tbl_len, PCI_DMA_TODEVICE);
+ msg[6] = 0x54000000 | sys_tbl_phys;
+
+ msg[7] = sys_tbl_phys;
+ msg[8] = 0x54000000 | privbuf[1];
+ msg[9] = privbuf[0];
+ msg[10] = 0xD4000000 | privbuf[3];
+ msg[11] = privbuf[2];
+
+ ret=i2o_post_wait(iop, msg, sizeof(msg), 120);
 
- ret=i2o_post_wait_mem(iop, msg, sizeof(msg), 120, privbuf, NULL);
+ pci_unmap_single(iop->pdev, sys_tbl_phys, sys_tbl_len, PCI_DMA_TODEVICE);
         
         if(ret==-ETIMEDOUT)
         {
@@ -2045,7 +2039,7 @@
 /*
  * Initialize I2O subsystem.
  */
-static void __init i2o_sys_init(void)
+void __init i2o_sys_init(void)
 {
         struct i2o_controller *iop, *niop = NULL;
 
@@ -2198,6 +2192,7 @@
 int i2o_init_outbound_q(struct i2o_controller *c)
 {
         u8 *status;
+ dma_addr_t status_phys;
         u32 m;
         u32 *msg;
         u32 time;
@@ -2208,7 +2203,7 @@
                 return -ETIMEDOUT;
         msg=(u32 *)(c->mem_offset+m);
 
- status = kmalloc(4,GFP_KERNEL);
+ status = pci_alloc_consistent(c->pdev, 4, &status_phys);
         if (status==NULL) {
                 printk(KERN_ERR "%s: Outbound Queue initialization failed - no free memory.\n",
                         c->name);
@@ -2221,11 +2216,10 @@
         msg[2]= core_context;
         msg[3]= 0x0106; /* Transaction context */
         msg[4]= 4096; /* Host page frame size */
- /* Frame size is in words. Pick 128, its what everyone elses uses and
- other sizes break some adapters. */
- msg[5]= MSG_FRAME_SIZE<<16|0x80; /* Outbound msg frame size and Initcode */
+ /* Frame size is in words. 256 bytes a frame for now */
+ msg[5]= MSG_FRAME_SIZE<<16|0x80; /* Outbound msg frame size in words and Initcode */
         msg[6]= 0xD0000004; /* Simple SG LE, EOB */
- msg[7]= virt_to_bus(status);
+ msg[7]= status_phys;
 
         i2o_post_message(c,m);
         
@@ -2241,20 +2235,20 @@
                         else
                                 printk(KERN_ERR "%s: Outbound queue initialize timeout.\n",
                                         c->name);
- kfree(status);
+ pci_free_consistent(c->pdev, 4, status, status_phys);
                         return -ETIMEDOUT;
                 }
- schedule();
+ yield();
                 barrier();
         }
 
         if(status[0] != I2O_CMD_COMPLETED)
         {
                 printk(KERN_ERR "%s: IOP outbound initialise failed.\n", c->name);
- kfree(status);
+ pci_free_consistent(c->pdev, 4, status, status_phys);
                 return -ETIMEDOUT;
         }
-
+ pci_free_consistent(c->pdev, 4, status, status_phys);
         return 0;
 }
 
@@ -2296,7 +2290,7 @@
         for(i=0; i< NMBR_MSG_FRAMES; i++) {
                 I2O_REPLY_WRITE32(c,m);
                 mb();
- m += MSG_FRAME_SIZE;
+ m += (MSG_FRAME_SIZE << 2);
         }
 
         return 0;
@@ -2312,7 +2306,7 @@
 
         do {
                 if (c->lct == NULL) {
- c->lct = kmalloc(size, GFP_KERNEL);
+ c->lct = pci_alloc_consistent(c->pdev, size, &c->lct_phys);
                         if(c->lct == NULL) {
                                 printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n",
                                         c->name);
@@ -2328,9 +2322,9 @@
                 msg[4] = 0xFFFFFFFF; /* All devices */
                 msg[5] = 0x00000000; /* Report now */
                 msg[6] = 0xD0000000|size;
- msg[7] = virt_to_bus(c->lct);
+ msg[7] = c->lct_phys;
 
- ret=i2o_post_wait_mem(c, msg, sizeof(msg), 120, c->lct, NULL);
+ ret=i2o_post_wait_mem(c, msg, sizeof(msg), 120, c->lct, NULL, c->lct_phys, 0, size, 0);
                 
                 if(ret == -ETIMEDOUT)
                 {
@@ -2346,8 +2340,9 @@
                 }
 
                 if (c->lct->table_size << 2 > size) {
- size = c->lct->table_size << 2;
- kfree(c->lct);
+ int new_size = c->lct->table_size << 2;
+ pci_free_consistent(c->pdev, size, c->lct, c->lct_phys);
+ size = new_size;
                         c->lct = NULL;
                 }
         } while (c->lct == NULL);
@@ -2375,7 +2370,7 @@
         msg[4] = 0xFFFFFFFF; /* All devices */
         msg[5] = c->dlct->change_ind+1; /* Next change */
         msg[6] = 0xD0000000|8192;
- msg[7] = virt_to_bus(c->dlct);
+ msg[7] = c->dlct_phys;
 
         return i2o_post_this(c, msg, sizeof(msg));
 }
@@ -2480,9 +2475,8 @@
                 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 =
- (u32)virt_to_bus(iop->post_port);
- sys_tbl->iops[count].inbound_high = 0; // TODO: 64-bit support
+ sys_tbl->iops[count].inbound_low = iop->post_port;
+ sys_tbl->iops[count].inbound_high = 0; // FIXME: 64-bit support
 
                 count++;
         }
@@ -2543,6 +2537,10 @@
  * @timeout: time in seconds to wait
  * @mem1: attached memory buffer 1
  * @mem2: attached memory buffer 2
+ * @phys1: physical address of buffer 1
+ * @phys2: physical address of buffer 2
+ * @size1: size of buffer 1
+ * @size2: size of buffer 2
  *
  * This core API allows an OSM to post a message and then be told whether
  * or not the system received a successful reply.
@@ -2557,9 +2555,10 @@
  * Pass NULL for unneeded buffers.
  */
  
-int i2o_post_wait_mem(struct i2o_controller *c, u32 *msg, int len, int timeout, void *mem1, void *mem2)
+int i2o_post_wait_mem(struct i2o_controller *c, u32 *msg, int len, int timeout, void *mem1, void *mem2, dma_addr_t phys1, dma_addr_t phys2, int size1, int size2)
 {
         DECLARE_WAIT_QUEUE_HEAD(wq_i2o_post);
+ DECLARE_WAITQUEUE(wait, current);
         int complete = 0;
         int status;
         unsigned long flags = 0;
@@ -2576,6 +2575,11 @@
         wait_data->complete = &complete;
         wait_data->mem[0] = mem1;
         wait_data->mem[1] = mem2;
+ wait_data->phys[0] = phys1;
+ wait_data->phys[1] = phys2;
+ wait_data->size[0] = size1;
+ wait_data->size[1] = size2;
+
         /*
          * Queue the event with its unique id
          */
@@ -2600,12 +2604,19 @@
          * complete will be zero. From the point post_this returns
          * the wait_data may have been deleted.
          */
+
+ add_wait_queue(&wq_i2o_post, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
         if ((status = i2o_post_this(c, msg, len))==0) {
- sleep_on_timeout(&wq_i2o_post, HZ * timeout);
+ schedule_timeout(HZ * timeout);
         }
         else
+ {
+ remove_wait_queue(&wq_i2o_post, &wait);
                 return -EIO;
-
+ }
+ remove_wait_queue(&wq_i2o_post, &wait);
+
         if(signal_pending(current))
                 status = -EINTR;
                 
@@ -2650,7 +2661,7 @@
  
 int i2o_post_wait(struct i2o_controller *c, u32 *msg, int len, int timeout)
 {
- return i2o_post_wait_mem(c, msg, len, timeout, NULL, NULL);
+ return i2o_post_wait_mem(c, msg, len, timeout, NULL, NULL, 0, 0, 0, 0);
 }
 
 /*
@@ -2658,7 +2669,7 @@
  * sleeping proccess. Called by core's reply handler.
  */
 
-static void i2o_post_wait_complete(u32 context, int status)
+static void i2o_post_wait_complete(struct i2o_controller *c, u32 context, int status)
 {
         struct i2o_post_wait_data **p1, *q;
         unsigned long flags;
@@ -2704,10 +2715,12 @@
                                 /*
                                  * Free resources. Caller is dead
                                  */
+
                                 if(q->mem[0])
- kfree(q->mem[0]);
+ pci_free_consistent(c->pdev, q->size[0], q->mem[0], q->phys[0]);
                                 if(q->mem[1])
- kfree(q->mem[1]);
+ pci_free_consistent(c->pdev, q->size[1], q->mem[1], q->phys[1]);
+
                                 printk(KERN_WARNING "i2o_post_wait event completed after timeout.\n");
                         }
                         kfree(q);
@@ -2728,6 +2741,7 @@
  * Note that the minimum sized reslist is 8 bytes and contains
  * ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
  */
+
 int i2o_issue_params(int cmd, struct i2o_controller *iop, int tid,
                 void *oplist, int oplen, void *reslist, int reslen)
 {
@@ -2738,17 +2752,18 @@
         int i = 0;
         int wait_status;
         u32 *opmem, *resmem;
+ dma_addr_t opmem_phys, resmem_phys;
         
         /* Get DMAable memory */
- opmem = kmalloc(oplen, GFP_KERNEL);
+ opmem = pci_alloc_consistent(iop->pdev, oplen, &opmem_phys);
         if(opmem == NULL)
                 return -ENOMEM;
         memcpy(opmem, oplist, oplen);
         
- resmem = kmalloc(reslen, GFP_KERNEL);
+ resmem = pci_alloc_consistent(iop->pdev, reslen, &resmem_phys);
         if(resmem == NULL)
         {
- kfree(opmem);
+ pci_free_consistent(iop->pdev, oplen, opmem, opmem_phys);
                 return -ENOMEM;
         }
         
@@ -2757,11 +2772,11 @@
         msg[3] = 0;
         msg[4] = 0;
         msg[5] = 0x54000000 | oplen; /* OperationList */
- msg[6] = virt_to_bus(opmem);
+ msg[6] = opmem_phys;
         msg[7] = 0xD0000000 | reslen; /* ResultList */
- msg[8] = virt_to_bus(resmem);
+ msg[8] = resmem_phys;
 
- wait_status = i2o_post_wait_mem(iop, msg, sizeof(msg), 10, opmem, resmem);
+ wait_status = i2o_post_wait_mem(iop, msg, sizeof(msg), 10, opmem, resmem, opmem_phys, resmem_phys, oplen, reslen);
         
         /*
          * This only looks like a memory leak - don't "fix" it.
@@ -2769,15 +2784,13 @@
         if(wait_status == -ETIMEDOUT)
                 return wait_status;
 
+ memcpy(reslist, resmem, reslen);
+ pci_free_consistent(iop->pdev, reslen, resmem, resmem_phys);
+ pci_free_consistent(iop->pdev, oplen, opmem, opmem_phys);
+
         /* Query failed */
         if(wait_status != 0)
- {
- kfree(resmem);
- kfree(opmem);
- return wait_status;
- }
-
- memcpy(reslist, resmem, reslen);
+ return wait_status;
         /*
          * Calculate number of bytes of Result LIST
          * We need to loop through each Result BLOCK and grab the length
@@ -3407,8 +3420,9 @@
         {
                 if(i2o_quiesce_controller(c))
                 {
- printk(KERN_WARNING "i2o: Could not quiesce %s." "
- Verify setup on next system power up.\n", c->name);
+ printk(KERN_WARNING "i2o: Could not quiesce %s.\n"
+ "Verify setup on next system power up.\n",
+ c->name);
                 }
         }
 
@@ -3426,6 +3440,10 @@
 EXPORT_SYMBOL(i2o_install_handler);
 EXPORT_SYMBOL(i2o_remove_handler);
 
+EXPORT_SYMBOL(i2o_install_controller);
+EXPORT_SYMBOL(i2o_delete_controller);
+EXPORT_SYMBOL(i2o_run_queue);
+
 EXPORT_SYMBOL(i2o_claim_device);
 EXPORT_SYMBOL(i2o_release_device);
 EXPORT_SYMBOL(i2o_device_notify_on);
@@ -3450,37 +3468,27 @@
 
 EXPORT_SYMBOL(i2o_get_class_name);
 
-#ifdef MODULE
+EXPORT_SYMBOL_GPL(i2o_sys_init);
 
 MODULE_AUTHOR("Red Hat Software");
 MODULE_DESCRIPTION("I2O Core");
 MODULE_LICENSE("GPL");
 
-
-
-int init_module(void)
+static int i2o_core_init(void)
 {
         printk(KERN_INFO "I2O Core - (C) Copyright 1999 Red Hat Software\n");
         if (i2o_install_handler(&i2o_core_handler) < 0)
         {
- printk(KERN_ERR
- "i2o_core: Unable to install core handler.\nI2O stack not loaded!");
+ printk(KERN_ERR "i2o_core: Unable to install core handler.\nI2O stack not loaded!");
                 return 0;
         }
 
         core_context = i2o_core_handler.context;
 
         /*
- * Attach core to I2O PCI transport (and others as they are developed)
- */
-#ifdef CONFIG_I2O_PCI_MODULE
- if(i2o_pci_core_attach(&i2o_core_functions) < 0)
- printk(KERN_INFO "i2o: No PCI I2O controllers found\n");
-#endif
-
- /*
          * Initialize event handling thread
          */
+
         init_MUTEX_LOCKED(&evt_sem);
         evt_pid = kernel_thread(i2o_core_evt, &evt_reply, CLONE_SIGHAND);
         if(evt_pid < 0)
@@ -3500,7 +3508,7 @@
         return 0;
 }
 
-void cleanup_module(void)
+static void i2o_core_exit(void)
 {
         int stat;
 
@@ -3521,73 +3529,10 @@
                 }
                 printk("done.\n");
         }
-
-#ifdef CONFIG_I2O_PCI_MODULE
- i2o_pci_core_detach();
-#endif
-
         i2o_remove_handler(&i2o_core_handler);
-
         unregister_reboot_notifier(&i2o_reboot_notifier);
 }
 
-#else
-
-extern int i2o_block_init(void);
-extern int i2o_config_init(void);
-extern int i2o_lan_init(void);
-extern int i2o_pci_init(void);
-extern int i2o_proc_init(void);
-extern int i2o_scsi_init(void);
-
-int __init i2o_init(void)
-{
- printk(KERN_INFO "Loading I2O Core - (c) Copyright 1999 Red Hat Software\n");
-
- if (i2o_install_handler(&i2o_core_handler) < 0)
- {
- printk(KERN_ERR
- "i2o_core: Unable to install core handler.\nI2O stack not loaded!");
- return 0;
- }
-
- core_context = i2o_core_handler.context;
+module_init(i2o_core_init);
+module_exit(i2o_core_exit);
 
- /*
- * Initialize event handling thread
- * We may not find any controllers, but still want this as
- * down the road we may have hot pluggable controllers that
- * need to be dealt with.
- */
- init_MUTEX_LOCKED(&evt_sem);
- if((evt_pid = kernel_thread(i2o_core_evt, &evt_reply, CLONE_SIGHAND)) < 0)
- {
- printk(KERN_ERR "I2O: Could not create event handler kernel thread\n");
- i2o_remove_handler(&i2o_core_handler);
- return 0;
- }
-
-
-#ifdef CONFIG_I2O_PCI
- i2o_pci_init();
-#endif
-
- if(i2o_num_controllers)
- i2o_sys_init();
-
- register_reboot_notifier(&i2o_reboot_notifier);
-
- i2o_config_init();
-#ifdef CONFIG_I2O_BLOCK
- i2o_block_init();
-#endif
-#ifdef CONFIG_I2O_LAN
- i2o_lan_init();
-#endif
-#ifdef CONFIG_I2O_PROC
- i2o_proc_init();
-#endif
- return 0;
-}
-
-#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux-2.5.28/drivers/message/i2o/i2o_pci.c linux-2.5.28-ac1/drivers/message/i2o/i2o_pci.c
--- linux-2.5.28/drivers/message/i2o/i2o_pci.c Thu Jul 25 10:49:25 2002
+++ linux-2.5.28-ac1/drivers/message/i2o/i2o_pci.c Sun Jul 21 13:27:21 2002
@@ -2,7 +2,7 @@
  * Find I2O capable controllers on the PCI bus, and register/install
  * them with the I2O layer
  *
- * (C) Copyright 1999 Red Hat Software
+ * (C) Copyright 1999-2002 Red Hat Software
  *
  * Written by Alan Cox, Building Number Three Ltd
  * Modified by Deepak Saxena <deepak@plexity.net>
@@ -13,8 +13,11 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  *
+ * Ported to Linux 2.5 by Alan Cox <alan@redhat.com>
+ *
  * TODO:
  * Support polled I2O PCI controllers.
+ * Finish verifying 64bit/bigendian clean
  */
 
 #include <linux/config.h>
@@ -31,21 +34,17 @@
 #include <asm/mtrr.h>
 #endif // CONFIG_MTRR
 
-#ifdef MODULE
-/*
- * Core function table
- * See <include/linux/i2o.h> for an explanation
- */
-static struct i2o_core_func_table *core;
-
-/* Core attach function */
-extern int i2o_pci_core_attach(struct i2o_core_func_table *);
-extern void i2o_pci_core_detach(void);
-#endif /* MODULE */
+static int dpt = 0;
+
 
-/*
- * Free bus specific resources
+/**
+ * i2o_pci_dispose - Free bus specific resources
+ * @c: I2O controller
+ *
+ * Disable interrupts and then free interrupt, I/O and mtrr resources
+ * used by this controller. Called by the I2O core on unload.
  */
+
 static void i2o_pci_dispose(struct i2o_controller *c)
 {
         I2O_IRQ_WRITE32(c,0xFFFFFFFF);
@@ -61,9 +60,13 @@
 #endif
 }
 
-/*
- * No real bus specific handling yet (note that later we will
- * need to 'steal' PCI devices on i960 mainboards)
+/**
+ * i2o_pci_bind - Bind controller and devices
+ * @c: i2o controller
+ * @dev: i2o device
+ *
+ * Bind a device driver to a controller. In the case of PCI all we need to do
+ * is module housekeeping.
  */
  
 static int i2o_pci_bind(struct i2o_controller *c, struct i2o_device *dev)
@@ -72,51 +75,83 @@
         return 0;
 }
 
+/**
+ * i2o_pci_unbind - Bind controller and devices
+ * @c: i2o controller
+ * @dev: i2o device
+ *
+ * Unbind a device driver from a controller. In the case of PCI all we need to do
+ * is module housekeeping.
+ */
+
+
 static int i2o_pci_unbind(struct i2o_controller *c, struct i2o_device *dev)
 {
         MOD_DEC_USE_COUNT;
         return 0;
 }
 
-/*
- * Bus specific enable/disable functions
+/**
+ * i2o_pci_enable - Enable controller
+ * @c: controller
+ *
+ * Called by the I2O core code in order to enable bus specific
+ * resources for this controller. In our case that means unmasking the
+ * interrupt line.
  */
+
 static void i2o_pci_enable(struct i2o_controller *c)
 {
         I2O_IRQ_WRITE32(c, 0);
         c->enabled = 1;
 }
 
+/**
+ * i2o_pci_disable - Enable controller
+ * @c: controller
+ *
+ * Called by the I2O core code in order to enable bus specific
+ * resources for this controller. In our case that means masking the
+ * interrupt line.
+ */
+
 static void i2o_pci_disable(struct i2o_controller *c)
 {
         I2O_IRQ_WRITE32(c, 0xFFFFFFFF);
         c->enabled = 0;
 }
 
-/*
- * Bus specific interrupt handler
+/**
+ * i2o_pci_interrupt - Bus specific interrupt handler
+ * @irq: interrupt line
+ * @dev_id: cookie
+ *
+ * Handle an interrupt from a PCI based I2O controller. This turns out
+ * to be rather simple. We keep the controller pointer in the cookie.
  */
  
 static void i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r)
 {
         struct i2o_controller *c = dev_id;
-#ifdef MODULE
- core->run_queue(c);
-#else
         i2o_run_queue(c);
-#endif /* MODULE */
 }
 
-/*
- * Install a PCI (or in theory AGP) i2o controller
+/**
+ * i2o_pci_install - Install a PCI i2o controller
+ * @dev: PCI device of the I2O controller
  *
- * TODO: Add support for polled controllers
+ * Install a PCI (or in theory AGP) i2o controller. Devices are
+ * initialized, configured and registered with the i2o core subsystem. Be
+ * very careful with ordering. There may be pending interrupts.
+ *
+ * To Do: Add support for polled controllers
  */
+
 int __init i2o_pci_install(struct pci_dev *dev)
 {
         struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller),
                                                 GFP_KERNEL);
- u8 *mem;
+ unsigned long mem;
         u32 memptr = 0;
         u32 size;
         
@@ -150,8 +185,8 @@
         /* Map the I2O controller */
         
         printk(KERN_INFO "i2o: PCI I2O controller at 0x%08X size=%d\n", memptr, size);
- mem = ioremap(memptr, size);
- if(mem==NULL)
+ mem = (unsigned long)ioremap(memptr, size);
+ if(mem==0)
         {
                 printk(KERN_ERR "i2o: Unable to map controller.\n");
                 kfree(c);
@@ -159,17 +194,16 @@
         }
 
         c->bus.pci.irq = -1;
- c->bus.pci.queue_buggy = 0;
         c->bus.pci.dpt = 0;
         c->bus.pci.short_req = 0;
         c->pdev = dev;
 
- c->irq_mask = (volatile u32 *)(mem+0x34);
- c->post_port = (volatile u32 *)(mem+0x40);
- c->reply_port = (volatile u32 *)(mem+0x44);
+ c->irq_mask = mem+0x34;
+ c->post_port = mem+0x40;
+ c->reply_port = mem+0x44;
 
         c->mem_phys = memptr;
- c->mem_offset = (u32)mem;
+ c->mem_offset = mem;
         c->destructor = i2o_pci_dispose;
         
         c->bind = i2o_pci_bind;
@@ -186,14 +220,12 @@
          
         if(dev->vendor == PCI_VENDOR_ID_NCR && dev->device == 0x0630)
         {
- c->bus.pci.short_req=1;
+ c->bus.pci.short_req = 1;
                 printk(KERN_INFO "I2O: Symbios FC920 workarounds activated.\n");
         }
         if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE)
         {
- c->bus.pci.queue_buggy=1;
- if (dev->subsystem_device == 0x0000) /* SX6000 ???? */
- c->bus.pci.queue_buggy=2;
+ c->bus.pci.promise = 1;
                 printk(KERN_INFO "I2O: Promise workarounds activated.\n");
         }
 
@@ -211,10 +243,11 @@
 #ifdef CONFIG_MTRR
         c->bus.pci.mtrr_reg0 =
                 mtrr_add(c->mem_phys, 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 shouldn't be cached.
-*/
+ /*
+ * If it is an INTEL i960 I/O processor then set the first 64K to
+ * Uncacheable since the region contains the Messaging unit which
+ * shouldn't be cached.
+ */
         c->bus.pci.mtrr_reg1 = -1;
         if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT)
         {
@@ -232,17 +265,13 @@
 
         I2O_IRQ_WRITE32(c,0xFFFFFFFF);
 
-#ifdef MODULE
- i = core->install(c);
-#else
         i = i2o_install_controller(c);
-#endif /* MODULE */
         
         if(i<0)
         {
                 printk(KERN_ERR "i2o: Unable to install controller.\n");
                 kfree(c);
- iounmap(mem);
+ iounmap((void *)mem);
                 return i;
         }
 
@@ -256,12 +285,8 @@
                         printk(KERN_ERR "%s: unable to allocate interrupt %d.\n",
                                 c->name, dev->irq);
                         c->bus.pci.irq = -1;
-#ifdef MODULE
- core->delete(c);
-#else
                         i2o_delete_controller(c);
-#endif /* MODULE */
- iounmap(mem);
+ iounmap((void *)mem);
                         return -EBUSY;
                 }
         }
@@ -272,6 +297,19 @@
         return 0;
 }
 
+/**
+ * i2o_pci_scan - Scan the pci bus for controllers
+ *
+ * Scan the PCI devices on the system looking for any device which is a
+ * memory of the Intelligent, I2O class. We attempt to set up each such device
+ * and register it with the core.
+ *
+ * Returns the number of controllers registered
+ *
+ * Note; Do not change this to a hot plug interface. I2O 1.5 itself
+ * does not support hot plugging.
+ */
+
 int __init i2o_pci_scan(void)
 {
         struct pci_dev *dev;
@@ -283,7 +321,7 @@
         {
                 if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O)
                         continue;
- if(dev->vendor == PCI_VENDOR_ID_DPT)
+ if(dev->vendor == PCI_VENDOR_ID_DPT && !dpt)
                 {
                         if(dev->device == 0xA501 || dev->device == 0xA511)
                         {
@@ -300,6 +338,11 @@
                         continue;
                 printk(KERN_INFO "i2o: I2O controller on bus %d at %d.\n",
                         dev->bus->number, dev->devfn);
+ if(pci_set_dma_mask(dev, 0xffffffff))
+ {
+ printk(KERN_WARNING "I2O controller on bus %d at %d : No suitable DMA available\n", dev->bus->number, dev->devfn);
+ continue;
+ }
                 pci_set_master(dev);
                 if(i2o_pci_install(dev)==0)
                         count++;
@@ -310,84 +353,43 @@
         return count?count:-ENODEV;
 }
 
-#ifdef I2O_HOTPLUG_SUPPORT
-/*
- * Activate a newly found PCI I2O controller
- * Not used now, but will be needed in future for
- * hot plug PCI support
+
+/**
+ * i2o_pci_core_attach - PCI initialisation for I2O
+ *
+ * Find any I2O controllers and if present initialise them and bring up
+ * the I2O subsystem.
+ *
+ * Returns 0 on success or an error code
  */
-static void i2o_pci_activate(i2o_controller * c)
+
+static int i2o_pci_core_attach(void)
 {
- int i=0;
- struct i2o_controller *c;
-
- if(c->type == I2O_TYPE_PCI)
+ printk(KERN_INFO "Linux I2O PCI support (c) 1999-2002 Red Hat.\n");
+ if(i2o_pci_scan()>0)
         {
- I2O_IRQ_WRITE32(c,0);
-#ifdef MODULE
- if(core->activate(c))
-#else
- if(i2o_activate_controller(c))
-#endif /* MODULE */
- {
- printk("%s: Failed to initialize.\n", c->name);
-#ifdef MODULE
- core->unlock(c);
- core->delete(c);
-#else
- i2o_unlock_controller(c);
- i2o_delete_controller(c);
-#endif
- continue;
- }
+ i2o_sys_init();
+ return 0;
         }
+ return -ENODEV;
 }
-#endif // I2O_HOTPLUG_SUPPORT
-
-#ifdef MODULE
-
-int i2o_pci_core_attach(struct i2o_core_func_table *table)
-{
- MOD_INC_USE_COUNT;
-
- core = table;
-
- return i2o_pci_scan();
-}
-
-void i2o_pci_core_detach(void)
-{
- core = NULL;
-
- MOD_DEC_USE_COUNT;
-}
-
-int init_module(void)
-{
- printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n");
-
- core = NULL;
 
- return 0;
+/**
+ * i2o_pci_core_detach - PCI unload for I2O
+ *
+ * Free up any resources not released when the controllers themselves were
+ * shutdown and unbound from the bus and drivers
+ */
  
-}
-
-void cleanup_module(void)
+static void i2o_pci_core_detach(void)
 {
 }
 
-EXPORT_SYMBOL(i2o_pci_core_attach);
-EXPORT_SYMBOL(i2o_pci_core_detach);
-
-MODULE_AUTHOR("Red Hat Software");
+MODULE_AUTHOR("Red Hat");
 MODULE_DESCRIPTION("I2O PCI Interface");
 MODULE_LICENSE("GPL");
 
-
-#else
-void __init i2o_pci_init(void)
-{
- printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n");
- i2o_pci_scan();
-}
-#endif
+MODULE_PARM(dpt, "i");
+MODULE_PARM_DESC(dpt, "Set this if you want to drive DPT cards normally handled by dpt_i2o");
+module_init(i2o_pci_core_attach);
+module_exit(i2o_pci_core_detach);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux-2.5.28/drivers/message/i2o/i2o_proc.c linux-2.5.28-ac1/drivers/message/i2o/i2o_proc.c
--- linux-2.5.28/drivers/message/i2o/i2o_proc.c Thu Jul 25 10:49:25 2002
+++ linux-2.5.28-ac1/drivers/message/i2o/i2o_proc.c Sun Jul 21 15:53:10 2002
@@ -45,6 +45,7 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/tqueue.h>
 #include <linux/errno.h>
 #include <linux/spinlock.h>
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux-2.5.28/include/linux/i2o.h linux-2.5.28-ac1/include/linux/i2o.h
--- linux-2.5.28/include/linux/i2o.h Thu Jul 25 10:50:19 2002
+++ linux-2.5.28-ac1/include/linux/i2o.h Sun Jul 21 15:20:20 2002
@@ -81,9 +81,9 @@
 struct i2o_pci
 {
         int irq;
- int queue_buggy:3; /* Don't send a lot of messages */
         int short_req:1; /* Use small block sizes */
         int dpt:1; /* Don't quiesce */
+ int promise:1; /* Promise controller */
 #ifdef CONFIG_MTRR
         int mtrr_reg0;
         int mtrr_reg1;
@@ -112,9 +112,9 @@
         atomic_t users;
         struct i2o_device *devices; /* I2O device chain */
         struct i2o_controller *next; /* Controller chain */
- volatile u32 *post_port; /* Inbout port */
- volatile u32 *reply_port; /* Outbound port */
- volatile u32 *irq_mask; /* Interrupt register */
+ unsigned long post_port; /* Inbout port address */
+ unsigned long reply_port; /* Outbound port address */
+ unsigned long irq_mask; /* Interrupt register address */
 
         /* Dynamic LCT related data */
         struct semaphore lct_sem;
@@ -122,12 +122,17 @@
         int lct_running;
 
         i2o_status_block *status_block; /* IOP status block */
+ dma_addr_t status_block_phys;
         i2o_lct *lct; /* Logical Config Table */
+ dma_addr_t lct_phys;
         i2o_lct *dlct; /* Temp LCT */
+ dma_addr_t dlct_phys;
         i2o_hrt *hrt; /* HW Resource Table */
+ dma_addr_t hrt_phys;
+ u32 hrt_len;
 
- u32 mem_offset; /* MFA offset */
- u32 mem_phys; /* MFA physical */
+ unsigned long mem_offset; /* MFA offset */
+ unsigned long mem_phys; /* MFA physical */
 
         int battery:1; /* Has a battery backup */
         int io_alloc:1; /* An I/O resource was allocated */
@@ -252,34 +257,34 @@
  */
 static inline u32 I2O_POST_READ32(struct i2o_controller *c)
 {
- return *c->post_port;
+ return readl(c->post_port);
 }
 
-static inline void I2O_POST_WRITE32(struct i2o_controller *c, u32 Val)
+static inline void I2O_POST_WRITE32(struct i2o_controller *c, u32 val)
 {
- *c->post_port = Val;
+ writel(val, c->post_port);
 }
 
 
 static inline u32 I2O_REPLY_READ32(struct i2o_controller *c)
 {
- return *c->reply_port;
+ return readl(c->reply_port);
 }
 
-static inline void I2O_REPLY_WRITE32(struct i2o_controller *c, u32 Val)
+static inline void I2O_REPLY_WRITE32(struct i2o_controller *c, u32 val)
 {
- *c->reply_port = Val;
+ writel(val, c->reply_port);
 }
 
 
 static inline u32 I2O_IRQ_READ32(struct i2o_controller *c)
 {
- return *c->irq_mask;
+ return readl(c->irq_mask);
 }
 
-static inline void I2O_IRQ_WRITE32(struct i2o_controller *c, u32 Val)
+static inline void I2O_IRQ_WRITE32(struct i2o_controller *c, u32 val)
 {
- *c->irq_mask = Val;
+ writel(val, c->irq_mask);
 }
 
 
@@ -295,6 +300,13 @@
         I2O_REPLY_WRITE32(c, m);
 }
 
+/*
+ * Endian handling wrapped into the macro - keeps the core code
+ * cleaner.
+ */
+
+#define i2o_raw_writel(val, mem) __raw_writel(cpu_to_le32(val), mem)
+
 extern struct i2o_controller *i2o_find_controller(int);
 extern void i2o_unlock_controller(struct i2o_controller *);
 extern struct i2o_controller *i2o_controller_chain;
@@ -313,7 +325,7 @@
 extern int i2o_post_this(struct i2o_controller *, u32 *, int);
 extern int i2o_post_wait(struct i2o_controller *, u32 *, int, int);
 extern int i2o_post_wait_mem(struct i2o_controller *, u32 *, int, int,
- void *, void *);
+ void *, void *, dma_addr_t, dma_addr_t, int, int);
 
 extern int i2o_query_scalar(struct i2o_controller *, int, int, int, void *,
                             int);
@@ -339,13 +351,66 @@
 extern void i2o_run_queue(struct i2o_controller *);
 extern int i2o_delete_controller(struct i2o_controller *);
 
+/*
+ * Cache strategies
+ */
+
+
+/* The NULL strategy leaves everything up to the controller. This tends to be a
+ * pessimal but functional choice.
+ */
+#define CACHE_NULL 0
+/* Prefetch data when reading. We continually attempt to load the next 32 sectors
+ * into the controller cache.
+ */
+#define CACHE_PREFETCH 1
+/* Prefetch data when reading. We sometimes attempt to load the next 32 sectors
+ * into the controller cache. When an I/O is less <= 8K we assume its probably
+ * not sequential and don't prefetch (default)
+ */
+#define CACHE_SMARTFETCH 2
+/* Data is written to the cache and then out on to the disk. The I/O must be
+ * physically on the medium before the write is acknowledged (default without
+ * NVRAM)
+ */
+#define CACHE_WRITETHROUGH 17
+/* Data is written to the cache and then out on to the disk. The controller
+ * is permitted to write back the cache any way it wants. (default if battery
+ * backed NVRAM is present). It can be useful to set this for swap regardless of
+ * battery state.
+ */
+#define CACHE_WRITEBACK 18
+/* Optimise for under powered controllers, especially on RAID1 and RAID0. We
+ * write large I/O's directly to disk bypassing the cache to avoid the extra
+ * memory copy hits. Small writes are writeback cached
+ */
+#define CACHE_SMARTBACK 19
+/* Optimise for under powered controllers, especially on RAID1 and RAID0. We
+ * write large I/O's directly to disk bypassing the cache to avoid the extra
+ * memory copy hits. Small writes are writethrough cached. Suitable for devices
+ * lacking battery backup
+ */
+#define CACHE_SMARTTHROUGH 20
+
+/*
+ * Ioctl structures
+ */
+
+
+#define BLKI2OGRSTRAT _IOR('2', 1, int)
+#define BLKI2OGWSTRAT _IOR('2', 2, int)
+#define BLKI2OSRSTRAT _IOW('2', 3, int)
+#define BLKI2OSWSTRAT _IOW('2', 4, int)
+
+
+
 
 /*
- * I2O Function codes
+ * I2O Function codes
  */
 
 /*
- * Executive Class
+ * Executive Class
  */
 #define I2O_CMD_ADAPTER_ASSIGN 0xB3
 #define I2O_CMD_ADAPTER_READ 0xB2
@@ -416,6 +481,7 @@
 #define I2O_CMD_BLOCK_MUNLOCK 0x4B
 #define I2O_CMD_BLOCK_MMOUNT 0x41
 #define I2O_CMD_BLOCK_MEJECT 0x43
+#define I2O_CMD_BLOCK_POWER 0x70
 
 #define I2O_PRIVATE_MSG 0xFF
 
@@ -574,6 +640,7 @@
 #define EIGHT_WORD_MSG_SIZE 0x00080000
 #define NINE_WORD_MSG_SIZE 0x00090000
 #define TEN_WORD_MSG_SIZE 0x000A0000
+#define ELEVEN_WORD_MSG_SIZE 0x000B0000
 #define I2O_MESSAGE_SIZE(x) ((x)<<16)
 
 
@@ -582,10 +649,10 @@
 #define ADAPTER_TID 0
 #define HOST_TID 1
 
-#define MSG_FRAME_SIZE 128
+#define MSG_FRAME_SIZE 64 /* i2o_scsi assumes >= 32 */
 #define NMBR_MSG_FRAMES 128
 
-#define MSG_POOL_SIZE 16384
+#define MSG_POOL_SIZE (MSG_FRAME_SIZE*NMBR_MSG_FRAMES*sizeof(u32))
 
 #define I2O_POST_WAIT_OK 0
 #define I2O_POST_WAIT_TIMEOUT -ETIMEDOUT
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Jul 30 2002 - 14:00:20 EST