Commit 77257fe5 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: Tidy up various bits of the iSeries code. No significant code...

[PATCH] ppc64: Tidy up various bits of the iSeries code. No significant code changes, from Stephen Rothwell

From: Anton Blanchard <anton@samba.org>

Tidy up various bits of the iSeries code.  No significant code changes, from
Stephen Rothwell
parent 9a7dd652
......@@ -8,108 +8,29 @@
* (at your option) any later version.
*/
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/system.h>
#include <asm/page.h>
#include <asm/abs_addr.h>
#include <asm/iSeries/HvCall.h>
#ifndef _HVCALLSC_H
#include <asm/iSeries/HvCallSc.h>
#endif
#include <asm/iSeries/LparData.h>
#ifndef _HVTYPES_H
#include <asm/iSeries/HvTypes.h>
#endif
/*=====================================================================
* Note that this call takes at MOST one page worth of data
*/
int HvCall_readLogBuffer(HvLpIndex lpIndex, void *buffer, u64 bufLen)
void HvCall_writeLogBuffer(const void *buffer, u64 len)
{
struct HvLpBufferList *bufList;
u64 bytesLeft = bufLen;
u64 leftThisPage;
u64 curPtr = virt_to_absolute( (unsigned long) buffer );
u64 retVal;
int npages;
int i;
npages = 0;
while (bytesLeft) {
npages++;
leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr;
if (leftThisPage > bytesLeft)
bytesLeft = 0;
else
bytesLeft -= leftThisPage;
curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE;
}
if (npages == 0)
return 0;
bufList = (struct HvLpBufferList *)
kmalloc(npages * sizeof(struct HvLpBufferList), GFP_ATOMIC);
bytesLeft = bufLen;
curPtr = virt_to_absolute( (unsigned long) buffer );
for(i=0; i<npages; i++) {
bufList[i].addr = curPtr;
leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr;
if (leftThisPage > bytesLeft) {
bufList[i].len = bytesLeft;
bytesLeft = 0;
} else {
bufList[i].len = leftThisPage;
bytesLeft -= leftThisPage;
}
curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE;
}
retVal = HvCall3(HvCallBaseReadLogBuffer, lpIndex,
virt_to_absolute((unsigned long)bufList), bufLen);
kfree(bufList);
return (int)retVal;
}
/*=====================================================================
*/
void HvCall_writeLogBuffer(const void *buffer, u64 bufLen)
{
struct HvLpBufferList bufList;
u64 bytesLeft = bufLen;
u64 leftThisPage;
u64 curPtr = virt_to_absolute((unsigned long) buffer);
while (bytesLeft) {
bufList.addr = curPtr;
leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr;
if (leftThisPage > bytesLeft) {
bufList.len = bytesLeft;
bytesLeft = 0;
} else {
bufList.len = leftThisPage;
bytesLeft -= leftThisPage;
}
struct HvLpBufferList hv_buf;
u64 left_this_page;
u64 cur = virt_to_absolute((unsigned long)buffer);
while (len) {
hv_buf.addr = cur;
left_this_page = ((cur & PAGE_MASK) + PAGE_SIZE) - cur;
if (left_this_page > len)
left_this_page = len;
hv_buf.len = left_this_page;
len -= left_this_page;
HvCall2(HvCallBaseWriteLogBuffer,
virt_to_absolute((unsigned long) &bufList),
bufList.len);
curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE;
virt_to_absolute((unsigned long)&hv_buf),
left_this_page);
cur = (cur & PAGE_MASK) + PAGE_SIZE;
}
}
......@@ -147,17 +147,14 @@ unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs )
printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType );
ItLpQueue_clearValid( nextLpEvent );
}
else /* No more valid events
* If overflow events are pending
* process them
} else if ( lpQueue->xPlicOverflowIntPending )
/*
* No more valid events. If overflow events are
* pending process them
*/
if ( lpQueue->xPlicOverflowIntPending ) {
HvCallEvent_getOverflowLpEvents(
lpQueue->xIndex);
}
else /* If nothing left then we are done */
break;
HvCallEvent_getOverflowLpEvents( lpQueue->xIndex);
else
break;
}
ItLpQueueInProcess = 0;
......
/*
* File XmPciLpEvent.h created by Wayne Holm on Mon Jan 15 2001.
*
* This module handles PCI interrupt events sent by the iSeries Hypervisor.
* File XmPciLpEvent.h created by Wayne Holm on Mon Jan 15 2001.
*
* This module handles PCI interrupt events sent by the iSeries Hypervisor.
*/
#include <linux/config.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/threads.h>
......@@ -36,14 +36,14 @@ enum XmPciLpEvent_Subtype {
};
struct XmPciLpEvent_BusInterrupt {
HvBusNumber busNumber;
HvBusNumber busNumber;
HvSubBusNumber subBusNumber;
};
struct XmPciLpEvent_NodeInterrupt {
HvBusNumber busNumber;
HvBusNumber busNumber;
HvSubBusNumber subBusNumber;
HvAgentId deviceId;
HvAgentId deviceId;
};
struct XmPciLpEvent {
......@@ -53,10 +53,10 @@ struct XmPciLpEvent {
u64 alignData; // Align on an 8-byte boundary
struct {
u32 fisr;
u32 fisr;
HvBusNumber busNumber;
HvSubBusNumber subBusNumber;
HvAgentId deviceId;
HvAgentId deviceId;
} slotInterrupt;
struct XmPciLpEvent_BusInterrupt busFailed;
......@@ -70,40 +70,52 @@ struct XmPciLpEvent {
};
static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm);
static void intReceived(struct XmPciLpEvent *eventParm,
struct pt_regs *regsParm);
static void XmPciLpEvent_handler( struct HvLpEvent* eventParm, struct pt_regs* regsParm)
static void XmPciLpEvent_handler(struct HvLpEvent *eventParm,
struct pt_regs *regsParm)
{
//PPCDBG(PPCDBG_BUSWALK,"XmPciLpEvent_handler, type 0x%x\n",eventParm->xType );
#ifdef CONFIG_PCI
#if 0
PPCDBG(PPCDBG_BUSWALK, "XmPciLpEvent_handler, type 0x%x\n",
eventParm->xType);
#endif
++Pci_Event_Count;
if (eventParm && eventParm->xType == HvLpEvent_Type_PciIo) {
switch( eventParm->xFlags.xFunction ) {
if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) {
switch (eventParm->xFlags.xFunction) {
case HvLpEvent_Function_Int:
intReceived( (struct XmPciLpEvent*)eventParm, regsParm );
intReceived((struct XmPciLpEvent *)eventParm, regsParm);
break;
case HvLpEvent_Function_Ack:
printk(KERN_ERR "XmPciLpEvent.c: unexpected ack received\n");
printk(KERN_ERR
"XmPciLpEvent.c: unexpected ack received\n");
break;
default:
printk(KERN_ERR "XmPciLpEvent.c: unexpected event function %d\n",(int)eventParm->xFlags.xFunction);
printk(KERN_ERR
"XmPciLpEvent.c: unexpected event function %d\n",
(int)eventParm->xFlags.xFunction);
break;
}
}
else if (eventParm) {
printk(KERN_ERR "XmPciLpEvent.c: Unrecognized PCI event type 0x%x\n",(int)eventParm->xType);
}
else {
} else if (eventParm)
printk(KERN_ERR
"XmPciLpEvent.c: Unrecognized PCI event type 0x%x\n",
(int)eventParm->xType);
else
printk(KERN_ERR "XmPciLpEvent.c: NULL event received\n");
}
#endif
}
static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm)
static void intReceived(struct XmPciLpEvent *eventParm,
struct pt_regs *regsParm)
{
int irq;
++Pci_Interrupt_Count;
//PPCDBG(PPCDBG_BUSWALK,"PCI: XmPciLpEvent.c: intReceived\n");
#if 0
PPCDBG(PPCDBG_BUSWALK, "PCI: XmPciLpEvent.c: intReceived\n");
#endif
switch (eventParm->hvLpEvent.xSubtype) {
case XmPciLpEvent_SlotInterrupt:
......@@ -111,33 +123,45 @@ static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm
/* Dispatch the interrupt handlers for this irq */
ppc_irq_dispatch_handler(regsParm, irq);
HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
eventParm->eventData.slotInterrupt.subBusNumber,
eventParm->eventData.slotInterrupt.deviceId);
eventParm->eventData.slotInterrupt.subBusNumber,
eventParm->eventData.slotInterrupt.deviceId);
break;
/* Ignore error recovery events for now */
case XmPciLpEvent_BusCreated:
printk(KERN_INFO "XmPciLpEvent.c: system bus %d created\n", eventParm->eventData.busCreated.busNumber);
printk(KERN_INFO "XmPciLpEvent.c: system bus %d created\n",
eventParm->eventData.busCreated.busNumber);
break;
case XmPciLpEvent_BusError:
case XmPciLpEvent_BusFailed:
printk(KERN_INFO "XmPciLpEvent.c: system bus %d failed\n", eventParm->eventData.busFailed.busNumber);
printk(KERN_INFO "XmPciLpEvent.c: system bus %d failed\n",
eventParm->eventData.busFailed.busNumber);
break;
case XmPciLpEvent_BusRecovered:
case XmPciLpEvent_UnQuiesceBus:
printk(KERN_INFO "XmPciLpEvent.c: system bus %d recovered\n", eventParm->eventData.busRecovered.busNumber);
printk(KERN_INFO "XmPciLpEvent.c: system bus %d recovered\n",
eventParm->eventData.busRecovered.busNumber);
break;
case XmPciLpEvent_NodeFailed:
case XmPciLpEvent_BridgeError:
printk(KERN_INFO "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d failed\n", eventParm->eventData.nodeFailed.busNumber, eventParm->eventData.nodeFailed.subBusNumber, eventParm->eventData.nodeFailed.deviceId);
printk(KERN_INFO
"XmPciLpEvent.c: multi-adapter bridge %d/%d/%d failed\n",
eventParm->eventData.nodeFailed.busNumber,
eventParm->eventData.nodeFailed.subBusNumber,
eventParm->eventData.nodeFailed.deviceId);
break;
case XmPciLpEvent_NodeRecovered:
printk(KERN_INFO "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d recovered\n", eventParm->eventData.nodeRecovered.busNumber, eventParm->eventData.nodeRecovered.subBusNumber, eventParm->eventData.nodeRecovered.deviceId);
printk(KERN_INFO
"XmPciLpEvent.c: multi-adapter bridge %d/%d/%d recovered\n",
eventParm->eventData.nodeRecovered.busNumber,
eventParm->eventData.nodeRecovered.subBusNumber,
eventParm->eventData.nodeRecovered.deviceId);
break;
default:
printk(KERN_ERR "XmPciLpEvent.c: unrecognized event subtype 0x%x\n",
eventParm->hvLpEvent.xSubtype);
printk(KERN_ERR
"XmPciLpEvent.c: unrecognized event subtype 0x%x\n",
eventParm->hvLpEvent.xSubtype);
break;
};
}
}
......@@ -145,18 +169,22 @@ static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm
int XmPciLpEvent_init()
{
int xRc;
PPCDBG(PPCDBG_BUSWALK,"XmPciLpEvent_init, Register Event type 0x%04X\n",HvLpEvent_Type_PciIo);
xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, &XmPciLpEvent_handler);
PPCDBG(PPCDBG_BUSWALK,
"XmPciLpEvent_init, Register Event type 0x%04X\n",
HvLpEvent_Type_PciIo);
xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo,
&XmPciLpEvent_handler);
if (xRc == 0) {
xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0);
if (xRc != 0) {
printk(KERN_ERR "XmPciLpEvent.c: open event path failed with rc 0x%x\n", xRc);
}
}
else {
printk(KERN_ERR "XmPciLpEvent.c: register handler failed with rc 0x%x\n", xRc);
}
return xRc;
if (xRc != 0)
printk(KERN_ERR
"XmPciLpEvent.c: open event path failed with rc 0x%x\n",
xRc);
} else
printk(KERN_ERR
"XmPciLpEvent.c: register handler failed with rc 0x%x\n",
xRc);
return xRc;
}
......@@ -38,127 +38,133 @@
#include "iSeries_IoMmTable.h"
#include "pci.h"
/*******************************************************************/
/* Table defines */
/* Each Entry size is 4 MB * 1024 Entries = 4GB I/O address space. */
/*******************************************************************/
/*
* Table defines
* Each Entry size is 4 MB * 1024 Entries = 4GB I/O address space.
*/
#define Max_Entries 1024
unsigned long iSeries_IoMmTable_Entry_Size = 0x0000000000400000;
unsigned long iSeries_Base_Io_Memory = 0xE000000000000000;
unsigned long iSeries_Max_Io_Memory = 0xE000000000000000;
static long iSeries_CurrentIndex = 0;
/*******************************************************************/
/* Lookup Tables. */
/*******************************************************************/
struct iSeries_Device_Node** iSeries_IoMmTable;
u8* iSeries_IoBarTable;
/*
* Lookup Tables.
*/
struct iSeries_Device_Node **iSeries_IoMmTable;
u8 *iSeries_IoBarTable;
/*******************************************************************/
/* Static and Global variables */
/*******************************************************************/
static char* iSeriesPciIoText = "iSeries PCI I/O";
/*
* Static and Global variables
*/
static char *iSeriesPciIoText = "iSeries PCI I/O";
static spinlock_t iSeriesIoMmTableLock = SPIN_LOCK_UNLOCKED;
/*******************************************************************/
/* iSeries_IoMmTable_Initialize */
/*******************************************************************/
/* Allocates and initalizes the Address Translation Table and Bar */
/* Tables to get them ready for use. Must be called before any */
/* I/O space is handed out to the device BARs. */
/* A follow up method,iSeries_IoMmTable_Status can be called to */
/* adjust the table after the device BARs have been assiged to */
/* resize the table. */
/*******************************************************************/
/*
* iSeries_IoMmTable_Initialize
*
* Allocates and initalizes the Address Translation Table and Bar
* Tables to get them ready for use. Must be called before any
* I/O space is handed out to the device BARs.
* A follow up method,iSeries_IoMmTable_Status can be called to
* adjust the table after the device BARs have been assiged to
* resize the table.
*/
void iSeries_IoMmTable_Initialize(void)
{
spin_lock(&iSeriesIoMmTableLock);
iSeries_IoMmTable = kmalloc(sizeof(void*)*Max_Entries,GFP_KERNEL);
iSeries_IoBarTable = kmalloc(sizeof(u8)*Max_Entries, GFP_KERNEL);
iSeries_IoMmTable = kmalloc(sizeof(void *) * Max_Entries, GFP_KERNEL);
iSeries_IoBarTable = kmalloc(sizeof(u8) * Max_Entries, GFP_KERNEL);
spin_unlock(&iSeriesIoMmTableLock);
PCIFR("IoMmTable Initialized 0x%p", iSeries_IoMmTable);
if(iSeries_IoMmTable == NULL || iSeries_IoBarTable == NULL) {
PCIFR("IoMmTable Initialized 0x%p", iSeries_IoMmTable);
if ((iSeries_IoMmTable == NULL) || (iSeries_IoBarTable == NULL))
panic("PCI: I/O tables allocation failed.\n");
}
}
/*******************************************************************/
/* iSeries_IoMmTable_AllocateEntry */
/*******************************************************************/
/* Adds pci_dev entry in address translation table */
/*******************************************************************/
/* - Allocates the number of entries required in table base on BAR */
/* size. */
/* - Allocates starting at iSeries_Base_Io_Memory and increases. */
/* - The size is round up to be a multiple of entry size. */
/* - CurrentIndex is incremented to keep track of the last entry. */
/* - Builds the resource entry for allocated BARs. */
/*******************************************************************/
static void iSeries_IoMmTable_AllocateEntry(struct pci_dev* PciDev, int BarNumber)
/*
* iSeries_IoMmTable_AllocateEntry
*
* Adds pci_dev entry in address translation table
*
* - Allocates the number of entries required in table base on BAR
* size.
* - Allocates starting at iSeries_Base_Io_Memory and increases.
* - The size is round up to be a multiple of entry size.
* - CurrentIndex is incremented to keep track of the last entry.
* - Builds the resource entry for allocated BARs.
*/
static void iSeries_IoMmTable_AllocateEntry(struct pci_dev *PciDev,
int BarNumber)
{
struct resource* BarResource = &PciDev->resource[BarNumber];
long BarSize = pci_resource_len(PciDev,BarNumber);
/***********************************************************/
/* No space to allocate, quick exit, skip Allocation. */
/***********************************************************/
if(BarSize == 0) return;
/***********************************************************/
/* Set Resource values. */
/***********************************************************/
struct resource *BarResource = &PciDev->resource[BarNumber];
long BarSize = pci_resource_len(PciDev, BarNumber);
/*
* No space to allocate, quick exit, skip Allocation.
*/
if (BarSize == 0)
return;
/*
* Set Resource values.
*/
spin_lock(&iSeriesIoMmTableLock);
BarResource->name = iSeriesPciIoText;
BarResource->start = iSeries_IoMmTable_Entry_Size*iSeries_CurrentIndex;
BarResource->start+= iSeries_Base_Io_Memory;
BarResource->end = BarResource->start+BarSize-1;
/***********************************************************/
/* Allocate the number of table entries needed for BAR. */
/***********************************************************/
BarResource->name = iSeriesPciIoText;
BarResource->start =
iSeries_IoMmTable_Entry_Size * iSeries_CurrentIndex;
BarResource->start += iSeries_Base_Io_Memory;
BarResource->end = BarResource->start+BarSize-1;
/*
* Allocate the number of table entries needed for BAR.
*/
while (BarSize > 0 ) {
*(iSeries_IoMmTable +iSeries_CurrentIndex) = (struct iSeries_Device_Node*)PciDev->sysdata;
*(iSeries_IoBarTable+iSeries_CurrentIndex) = BarNumber;
*(iSeries_IoMmTable + iSeries_CurrentIndex) =
(struct iSeries_Device_Node *)PciDev->sysdata;
*(iSeries_IoBarTable + iSeries_CurrentIndex) = BarNumber;
BarSize -= iSeries_IoMmTable_Entry_Size;
++iSeries_CurrentIndex;
}
iSeries_Max_Io_Memory = (iSeries_IoMmTable_Entry_Size*iSeries_CurrentIndex)+iSeries_Base_Io_Memory;
iSeries_Max_Io_Memory = iSeries_Base_Io_Memory +
(iSeries_IoMmTable_Entry_Size * iSeries_CurrentIndex);
spin_unlock(&iSeriesIoMmTableLock);
}
/*******************************************************************/
/* iSeries_allocateDeviceBars */
/*******************************************************************/
/* - Allocates ALL pci_dev BAR's and updates the resources with the*/
/* BAR value. BARS with zero length will have the resources */
/* The HvCallPci_getBarParms is used to get the size of the BAR */
/* space. It calls iSeries_IoMmTable_AllocateEntry to allocate */
/* each entry. */
/* - Loops through The Bar resources(0 - 5) including the ROM */
/* is resource(6). */
/*******************************************************************/
void iSeries_allocateDeviceBars(struct pci_dev* PciDev)
/*
* iSeries_allocateDeviceBars
*
* - Allocates ALL pci_dev BAR's and updates the resources with the
* BAR value. BARS with zero length will have the resources
* The HvCallPci_getBarParms is used to get the size of the BAR
* space. It calls iSeries_IoMmTable_AllocateEntry to allocate
* each entry.
* - Loops through The Bar resources(0 - 5) including the ROM
* is resource(6).
*/
void iSeries_allocateDeviceBars(struct pci_dev *PciDev)
{
struct resource* BarResource;
int BarNumber;
for(BarNumber = 0; BarNumber <= PCI_ROM_RESOURCE; ++BarNumber) {
struct resource *BarResource;
int BarNumber;
for (BarNumber = 0; BarNumber <= PCI_ROM_RESOURCE; ++BarNumber) {
BarResource = &PciDev->resource[BarNumber];
iSeries_IoMmTable_AllocateEntry(PciDev, BarNumber);
}
}
/************************************************************************/
/* Translates the IoAddress to the device that is mapped to IoSpace. */
/* This code is inlined, see the iSeries_pci.c file for the replacement.*/
/************************************************************************/
struct iSeries_Device_Node* iSeries_xlateIoMmAddress(void* IoAddress)
/*
* Translates the IoAddress to the device that is mapped to IoSpace.
* This code is inlined, see the iSeries_pci.c file for the replacement.
*/
struct iSeries_Device_Node *iSeries_xlateIoMmAddress(void *IoAddress)
{
return NULL;
}
/************************************************************************
/*
* Status hook for IoMmTable
************************************************************************/
void iSeries_IoMmTable_Status(void)
*/
void iSeries_IoMmTable_Status(void)
{
PCIFR("IoMmTable......: 0x%p",iSeries_IoMmTable);
PCIFR("IoMmTable Range: 0x%p to 0x%p",iSeries_Base_Io_Memory,iSeries_Max_Io_Memory);
return;
PCIFR("IoMmTable......: 0x%p", iSeries_IoMmTable);
PCIFR("IoMmTable Range: 0x%p to 0x%p", iSeries_Base_Io_Memory,
iSeries_Max_Io_Memory);
}
......@@ -31,55 +31,55 @@
struct pci_dev;
struct iSeries_Device_Node;
extern struct iSeries_Device_Node** iSeries_IoMmTable;
extern u8* iSeries_IoBarTable;
extern struct iSeries_Device_Node **iSeries_IoMmTable;
extern u8 *iSeries_IoBarTable;
extern unsigned long iSeries_Base_Io_Memory;
extern unsigned long iSeries_Max_Io_Memory;
extern unsigned long iSeries_Base_Io_Memory;
extern unsigned long iSeries_IoMmTable_Entry_Size;
/************************************************************************/
/* iSeries_IoMmTable_Initialize */
/************************************************************************/
/* - Initalizes the Address Translation Table and get it ready for use. */
/* Must be called before any client calls any of the other methods. */
/* */
/* Parameters: None. */
/* */
/* Return: None. */
/************************************************************************/
extern void iSeries_IoMmTable_Initialize(void);
extern void iSeries_IoMmTable_Status(void);
/*
* iSeries_IoMmTable_Initialize
*
* - Initalizes the Address Translation Table and get it ready for use.
* Must be called before any client calls any of the other methods.
*
* Parameters: None.
*
* Return: None.
*/
extern void iSeries_IoMmTable_Initialize(void);
extern void iSeries_IoMmTable_Status(void);
/************************************************************************/
/* iSeries_allocateDeviceBars */
/************************************************************************/
/* - Allocates ALL pci_dev BAR's and updates the resources with the BAR */
/* value. BARS with zero length will not have the resources. The */
/* HvCallPci_getBarParms is used to get the size of the BAR space. */
/* It calls iSeries_IoMmTable_AllocateEntry to allocate each entry. */
/* */
/* Parameters: */
/* pci_dev = Pointer to pci_dev structure that will be mapped to pseudo */
/* I/O Address. */
/* */
/* Return: */
/* The pci_dev I/O resources updated with pseudo I/O Addresses. */
/************************************************************************/
extern void iSeries_allocateDeviceBars(struct pci_dev* );
/*
* iSeries_allocateDeviceBars
*
* - Allocates ALL pci_dev BAR's and updates the resources with the BAR
* value. BARS with zero length will not have the resources. The
* HvCallPci_getBarParms is used to get the size of the BAR space.
* It calls iSeries_IoMmTable_AllocateEntry to allocate each entry.
*
* Parameters:
* pci_dev = Pointer to pci_dev structure that will be mapped to pseudo
* I/O Address.
*
* Return:
* The pci_dev I/O resources updated with pseudo I/O Addresses.
*/
extern void iSeries_allocateDeviceBars(struct pci_dev *);
/************************************************************************/
/* iSeries_xlateIoMmAddress */
/************************************************************************/
/* - Translates an I/O Memory address to Device Node that has been the */
/* allocated the psuedo I/O Address. */
/* */
/* Parameters: */
/* IoAddress = I/O Memory Address. */
/* */
/* Return: */
/* An iSeries_Device_Node to the device mapped to the I/O address. The*/
/* BarNumber and BarOffset are valid if the Device Node is returned. */
/************************************************************************/
extern struct iSeries_Device_Node* iSeries_xlateIoMmAddress(void* IoAddress);
/*
* iSeries_xlateIoMmAddress
*
* - Translates an I/O Memory address to Device Node that has been the
* allocated the psuedo I/O Address.
*
* Parameters:
* IoAddress = I/O Memory Address.
*
* Return:
* An iSeries_Device_Node to the device mapped to the I/O address. The
* BarNumber and BarOffset are valid if the Device Node is returned.
*/
extern struct iSeries_Device_Node *iSeries_xlateIoMmAddress(void *IoAddress);
#endif /* _ISERIES_IOMMTABLE_H */
This diff is collapsed.
......@@ -42,47 +42,62 @@
#include <asm/iSeries/iSeries_pci.h>
#include "pci.h"
/************************************************************************/
/* Interface to toggle the reset line */
/* Time is in .1 seconds, need for seconds. */
/************************************************************************/
int iSeries_Device_ToggleReset(struct pci_dev* PciDev, int AssertTime, int DelayTime)
/*
* Interface to toggle the reset line
* Time is in .1 seconds, need for seconds.
*/
int iSeries_Device_ToggleReset(struct pci_dev *PciDev, int AssertTime,
int DelayTime)
{
unsigned long AssertDelay, WaitDelay;
struct iSeries_Device_Node* DeviceNode = (struct iSeries_Device_Node*)PciDev->sysdata;
struct iSeries_Device_Node *DeviceNode =
(struct iSeries_Device_Node *)PciDev->sysdata;
if (DeviceNode == NULL) {
printk("PCI: Pci Reset Failed, Device Node not found for pci_dev %p\n",PciDev);
printk("PCI: Pci Reset Failed, Device Node not found for pci_dev %p\n",
PciDev);
return -1;
}
/********************************************************************
/*
* Set defaults, Assert is .5 second, Wait is 3 seconds.
********************************************************************/
if (AssertTime == 0) AssertDelay = ( 5 * HZ)/10;
else AssertDelay = (AssertTime*HZ)/10;
if (WaitDelay == 0) WaitDelay = (30 * HZ)/10;
else WaitDelay = (DelayTime* HZ)/10;
*/
if (AssertTime == 0)
AssertDelay = (5 * HZ) / 10;
else
AssertDelay = (AssertTime * HZ) / 10;
if (WaitDelay == 0)
WaitDelay = (30 * HZ) / 10;
else
WaitDelay = (DelayTime * HZ) / 10;
/********************************************************************
/*
* Assert reset
********************************************************************/
DeviceNode->ReturnCode = HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode),0x00,DeviceNode->AgentId,1);
*/
DeviceNode->ReturnCode = HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode),
0x00, DeviceNode->AgentId, 1);
if (DeviceNode->ReturnCode == 0) {
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(AssertDelay); /* Sleep for the time */
DeviceNode->ReturnCode = HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode),0x00,DeviceNode->AgentId, 0);
schedule_timeout(AssertDelay); /* Sleep for the time */
DeviceNode->ReturnCode =
HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode),
0x00, DeviceNode->AgentId, 0);
/***************************************************************
/*
* Wait for device to reset
***************************************************************/
*/
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(WaitDelay);
}
if (DeviceNode->ReturnCode == 0) {
PCIFR("Slot 0x%04X.%02 Reset\n",ISERIES_BUS(DeviceNode),DeviceNode->AgentId );
}
if (DeviceNode->ReturnCode == 0)
PCIFR("Slot 0x%04X.%02 Reset\n", ISERIES_BUS(DeviceNode),
DeviceNode->AgentId);
else {
printk("PCI: Slot 0x%04X.%02X Reset Failed, RCode: %04X\n",ISERIES_BUS(DeviceNode),DeviceNode->AgentId,DeviceNode->ReturnCode);
PCIFR( "Slot 0x%04X.%02X Reset Failed, RCode: %04X\n",ISERIES_BUS(DeviceNode),DeviceNode->AgentId,DeviceNode->ReturnCode);
printk("PCI: Slot 0x%04X.%02X Reset Failed, RCode: %04X\n",
ISERIES_BUS(DeviceNode), DeviceNode->AgentId,
DeviceNode->ReturnCode);
PCIFR("Slot 0x%04X.%02X Reset Failed, RCode: %04X\n",
ISERIES_BUS(DeviceNode), DeviceNode->AgentId,
DeviceNode->ReturnCode);
}
return DeviceNode->ReturnCode;
}
......@@ -16,29 +16,22 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Change Activity: */
/* End Change Activity */
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#ifndef _ISERIES_PROC_H
#include <linux/init.h>
#include <asm/iSeries/iSeries_proc.h>
#endif
static struct proc_dir_entry *iSeries_proc_root;
static int iSeries_proc_initializationDone;
static spinlock_t iSeries_proc_lock;
struct iSeries_proc_registration
{
struct iSeries_proc_registration {
struct iSeries_proc_registration *next;
iSeriesProcFunction functionMember;
};
struct iSeries_proc_registration preallocated[16];
#define MYQUEUETYPE(T) struct MYQueue##T
#define MYQUEUE(T) \
MYQUEUETYPE(T) \
......@@ -68,33 +61,33 @@ do { \
if ((q)->tail == NULL) \
(q)->head = NULL; \
} while(0)
MYQUEUE(iSeries_proc_registration);
typedef MYQUEUETYPE(iSeries_proc_registration) aQueue;
aQueue iSeries_free;
aQueue iSeries_queued;
static aQueue iSeries_free;
static aQueue iSeries_queued;
void iSeries_proc_early_init(void)
{
int i = 0;
unsigned long flags;
iSeries_proc_initializationDone = 0;
spin_lock_init(&iSeries_proc_lock);
MYQUEUECTOR(&iSeries_free);
MYQUEUECTOR(&iSeries_queued);
spin_lock_irqsave(&iSeries_proc_lock, flags);
for (i = 0; i < 16; ++i) {
MYQUEUEENQ(&iSeries_free, preallocated+i);
}
for (i = 0; i < 16; ++i)
MYQUEUEENQ(&iSeries_free, preallocated + i);
spin_unlock_irqrestore(&iSeries_proc_lock, flags);
}
void iSeries_proc_create(void)
static int iSeries_proc_create(void)
{
unsigned long flags;
struct iSeries_proc_registration *reg = NULL;
struct iSeries_proc_registration *reg;
printk("iSeries_proc: Creating /proc/iSeries\n");
......@@ -112,31 +105,27 @@ void iSeries_proc_create(void)
iSeries_proc_initializationDone = 1;
out:
spin_unlock_irqrestore(&iSeries_proc_lock, flags);
return 0;
}
arch_initcall(iSeries_proc_create);
void iSeries_proc_callback(iSeriesProcFunction initFunction)
{
unsigned long flags;
spin_lock_irqsave(&iSeries_proc_lock, flags);
if (iSeries_proc_initializationDone) {
spin_lock_irqsave(&iSeries_proc_lock, flags);
if (iSeries_proc_initializationDone)
(*initFunction)(iSeries_proc_root);
} else {
else {
struct iSeries_proc_registration *reg = NULL;
MYQUEUEDEQ(&iSeries_free, reg);
if (reg != NULL) {
/* printk("Registering %p in reg %p\n", initFunction, reg); */
reg->functionMember = initFunction;
MYQUEUEENQ(&iSeries_queued, reg);
} else {
} else
printk("Couldn't get a queue entry\n");
}
}
spin_unlock_irqrestore(&iSeries_proc_lock, flags);
}
......@@ -16,22 +16,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Change Activity: */
/* End Change Activity */
#ifndef _ISERIES_PROC_H
#define _ISERIES_PROC_H
#include <linux/proc_fs.h>
extern void iSeries_proc_early_init(void);
extern void iSeries_proc_create(void);
typedef void (*iSeriesProcFunction)(struct proc_dir_entry *iSeries_proc);
extern void iSeries_proc_callback(iSeriesProcFunction initFunction);
#endif /* _iSeries_PROC_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment