--- a/drivers/message/i2o/i2o_block.c 2004-04-27 03:55:49.000000000 -1000 +++ b/drivers/message/i2o/i2o_block.c 2004-04-30 07:32:23.254713216 -1000 @@ -316,6 +316,11 @@ i2o_raw_writel( offset & 0xFFFFFFFF, msg+24); i2o_raw_writel(offset>>32, msg+28); mptr=msg+32; + if((sizeof(dma_addr_t) > 4) && (c->pae_support)) { + i2o_raw_writel((0x7C<<24)+(2<<16)+0x02, mptr); + i2o_raw_writel(1 << PAGE_SHIFT, mptr + 4); + mptr += 8; + } sg = ireq->sg_table; if(rq_data_dir(req) == READ) @@ -328,8 +334,15 @@ i2o_raw_writel(0x10000000|sg_dma_len(sg), mptr); else i2o_raw_writel(0xD0000000|sg_dma_len(sg), mptr); - i2o_raw_writel(sg_dma_address(sg), mptr+4); - mptr += 8; + if(c->pae_support) { + dma_addr_t addr = sg_dma_address(sg); + i2o_raw_writel(i2o_low_ptr_to_u32((void *)addr), mptr+4); + i2o_raw_writel(i2o_high_ptr_to_u32((void *)addr), mptr+8); + mptr += 12; + } else { + i2o_raw_writel(sg_dma_address(sg), mptr+4); + mptr += 8; + } count -= sg_dma_len(sg); sg++; } --- a/drivers/message/i2o/i2o_core.c 2004-04-26 23:42:22.000000000 -1000 +++ b/drivers/message/i2o/i2o_core.c 2004-04-30 04:48:19.000000000 -1000 @@ -1794,6 +1794,7 @@ return -ETIMEDOUT; msg=(u32 *)(c->mem_offset+m); + pci_set_dma_mask(c->pdev, (dma_addr_t)0xFFFFFFFF); status = pci_alloc_consistent(c->pdev, 4, &status_phys); if(status == NULL) { printk(KERN_ERR "IOP reset failed - no free memory.\n"); @@ -1882,6 +1887,7 @@ i2o_enable_controller(iop); pci_free_consistent(c->pdev, 4, status, status_phys); + pci_set_dma_mask(c->pdev, (dma_addr_t)0xFFFFFFFFFFFFFFFFULL); return 0; } @@ -1905,8 +1911,12 @@ if (c->status_block == NULL) { + if(c->pae_support) + pci_set_dma_mask(c->pdev, (dma_addr_t) 0xffffffff); c->status_block = (i2o_status_block *) pci_alloc_consistent(c->pdev, sizeof(i2o_status_block), &c->status_block_phys); + if(c->pae_support) + pci_set_dma_mask(c->pdev, (dma_addr_t) 0xffffffffffffffffULL); if (c->status_block == NULL) { printk(KERN_CRIT "%s: Get Status Block failed; Out of memory.\n", @@ -2447,7 +2457,11 @@ do { if (c->lct == NULL) { + if(c->pae_support) + pci_set_dma_mask(c->pdev, (dma_addr_t)0xffffffffffffffff); c->lct = pci_alloc_consistent(c->pdev, size, &c->lct_phys); + if(c->pae_support) + pci_set_dma_mask(c->pdev, (dma_addr_t)0xffffffffffffffffULL); if(c->lct == NULL) { printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n", c->name); @@ -2616,8 +2630,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 = iop->post_port; - sys_tbl->iops[count].inbound_high = 0; // FIXME: 64-bit support + sys_tbl->iops[count].inbound_low = (u32)iop->post_port; + sys_tbl->iops[count].inbound_high = (u32)(iop->post_port >> 32); count++; } @@ -3678,6 +3692,12 @@ c->short_req = 0; c->pdev = dev; + if(sizeof(dma_addr_t) > 4) { + pci_set_dma_mask(dev, (dma_addr_t)0xFFFFFFFFFFFFFFFFULL); + c->pae_support = 1; + } else + c->pae_support = 0; + #if BITS_PER_LONG == 64 c->context_list_lock = SPIN_LOCK_UNLOCKED; #endif --- a/include/linux/i2o.h 2004-04-26 23:42:22.000000000 -1000 +++ b/include/linux/i2o.h 2004-04-30 07:07:05.000000000 -1000 @@ -143,6 +143,7 @@ void *page_frame; /* Message buffers */ dma_addr_t page_frame_map; /* Cache map */ + int pae_support; /* PAE support for Adaptec */ #if BITS_PER_LONG == 64 spinlock_t context_list_lock; /* lock for context_list */ struct i2o_context_list_element *context_list; /* list of context id's @@ -341,6 +342,14 @@ extern u32 i2o_context_list_add(void *, struct i2o_controller *); extern void *i2o_context_list_get(u32, struct i2o_controller *); extern u32 i2o_context_list_remove(void *, struct i2o_controller *); + +static inline u32 i2o_high_ptr_to_u32(void *ptr) { + return (u32)((u64)ptr >> 32); +} + +static inline u32 i2o_low_ptr_to_u32(void *ptr) { + return (u32)(u64)ptr; +} #else static inline u32 i2o_context_list_add(void *ptr, struct i2o_controller *c) { @@ -356,6 +365,14 @@ { return (u32)ptr; } + +static inline u32 i2o_high_ptr_to_u32(void *ptr) { + return 0; +} + +static inline u32 i2o_low_ptr_to_u32(void *ptr) { + return ptr; +} #endif /*