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

Alan Cox (alan@irongate.swansea.linux.org.uk)
Thu, 25 Jul 2002 15:47:14 +0100 (BST)


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/