Main Page | Directories | File List | Globals

pcibus_ops.c File Reference

#include <agnix/agnix.h>
#include <agnix/adi/adi.h>
#include <agnix/ioport.h>
#include <agnix/console.h>

Include dependency graph for pcibus_ops.c:

Go to the source code of this file.

Defines

#define MOD_NAME   "PCI: \t\t"
#define PCIBUS_ADDRESS_1(bus, device, fn, reg)   ((u32)(0x80000000 | (bus << 16) | (device << 11) | (fn << 8) | (reg & ~3)))
#define PCIBUS_ADDRESS_2(device, reg)   ((u16)(0xC000 | (device << 8) | (reg & 0xFF)))
#define PCIBUS_CONF_ADDR_1   0xCF8
#define PCIBUS_CONF_DATA_1   0xCFC
#define PCIBUS_CONF_FN_2   0xCF8
#define PCIBUS_CONF_BUS_2   0xCFA

Functions

int pcibus_direct_send_address_1 (struct pcidev_s *pcidev, int reg)
int pcibus_read_config_1 (struct pcidev_s *pcidev, int reg, u32 *value, int len)
int pcibus_write_config_1 (struct pcidev_s *pcidev, int reg, u32 value, int len)
int pcibus_direct_send_address_2 (struct pcidev_s *pcidev, int reg)
int pcibus_read_config_2 (struct pcidev_s *pcidev, int reg, u32 *value, int len)
int pcibus_write_config_2 (struct pcidev_s *pcidev, int reg, u32 value, int len)
int pcibus_check_direct_access_1 (void)
int pcibus_check_direct_access_2 (void)
int pcibus_check_direct_access (void)
int pcibus_ops_init (void)

Variables

pcibus_ops_s pcibus_primary_ops


Define Documentation

#define MOD_NAME   "PCI: \t\t"
 

Definition at line 19 of file pcibus_ops.c.

#define PCIBUS_ADDRESS_1 bus,
device,
fn,
reg   )     ((u32)(0x80000000 | (bus << 16) | (device << 11) | (fn << 8) | (reg & ~3)))
 

Definition at line 21 of file pcibus_ops.c.

Referenced by pcibus_direct_send_address_1().

#define PCIBUS_ADDRESS_2 device,
reg   )     ((u16)(0xC000 | (device << 8) | (reg & 0xFF)))
 

Definition at line 22 of file pcibus_ops.c.

Referenced by pcibus_read_config_2(), and pcibus_write_config_2().

#define PCIBUS_CONF_ADDR_1   0xCF8
 

Definition at line 24 of file pcibus_ops.c.

Referenced by pcibus_check_direct_access_1(), and pcibus_direct_send_address_1().

#define PCIBUS_CONF_BUS_2   0xCFA
 

Definition at line 28 of file pcibus_ops.c.

Referenced by pcibus_check_direct_access_2(), and pcibus_direct_send_address_2().

#define PCIBUS_CONF_DATA_1   0xCFC
 

Definition at line 25 of file pcibus_ops.c.

Referenced by pcibus_read_config_1(), and pcibus_write_config_1().

#define PCIBUS_CONF_FN_2   0xCF8
 

Definition at line 27 of file pcibus_ops.c.

Referenced by pcibus_check_direct_access_2().


Function Documentation

int pcibus_check_direct_access void   ) 
 

Definition at line 182 of file pcibus_ops.c.

References pcibus_check_direct_access_1(), pcibus_check_direct_access_2(), pcibus_primary_ops, pcibus_read_config_1(), pcibus_read_config_2(), pcibus_write_config_1(), and pcibus_write_config_2().

Referenced by pcibus_ops_init().

00183 {
00184     if (pcibus_check_direct_access_1() == 0) {
00185         pcibus_primary_ops.pcibus_read_config  = pcibus_read_config_1;
00186         pcibus_primary_ops.pcibus_write_config = pcibus_write_config_1;
00187         return 0;
00188     } else
00189     if (pcibus_check_direct_access_2() == 0) {
00190         pcibus_primary_ops.pcibus_read_config  = pcibus_read_config_2;
00191         pcibus_primary_ops.pcibus_write_config = pcibus_write_config_2;
00192         return 0;
00193     }
00194     
00195     return -1;
00196 }

Here is the call graph for this function:

int pcibus_check_direct_access_1 void   ) 
 

Definition at line 131 of file pcibus_ops.c.

References MOD_NAME, PCIBUS_CONF_ADDR_1, and printk().

Referenced by pcibus_check_direct_access().

00132 {
00133     u32 saved_value;
00134     u32 write_value = 0x80000000;
00135     u32 read_value;
00136 
00137     outb(0x01, 0xCFB);    
00138     saved_value = inl(PCIBUS_CONF_ADDR_1);
00139     
00140     outl(write_value, PCIBUS_CONF_ADDR_1);
00141     read_value = inl(PCIBUS_CONF_ADDR_1);
00142     
00143     if (read_value == write_value) {
00144         outl(saved_value, PCIBUS_CONF_ADDR_1);
00145         printk(MOD_NAME "detected type 1 direct access to PCI configuration space\n");
00146         return 0;
00147     }
00148     
00149     outl(saved_value, PCIBUS_CONF_ADDR_1);
00150     
00151     return -1;
00152 }

Here is the call graph for this function:

int pcibus_check_direct_access_2 void   ) 
 

Definition at line 154 of file pcibus_ops.c.

References MOD_NAME, PCIBUS_CONF_BUS_2, PCIBUS_CONF_FN_2, and printk().

Referenced by pcibus_check_direct_access().

00155 {
00156     u8 saved_bus;
00157     u8 saved_fn;
00158     u8 read_bus;
00159     u8 read_fn;
00160     
00161     outb(0x00, 0xCFB);    
00162     
00163     saved_fn  = inb(PCIBUS_CONF_FN_2);
00164     saved_bus = inb(PCIBUS_CONF_BUS_2);
00165 
00166     outb(0x00, PCIBUS_CONF_FN_2);
00167     outb(0x00, PCIBUS_CONF_BUS_2);
00168 
00169     read_fn  = inb(PCIBUS_CONF_FN_2);
00170     read_bus = inb(PCIBUS_CONF_BUS_2);
00171 
00172     if (read_fn == 0x00 && read_bus == 0x00) {
00173         outl(saved_fn, PCIBUS_CONF_FN_2);
00174         outl(saved_bus, PCIBUS_CONF_BUS_2);
00175         printk(MOD_NAME "detected type 2 direct access to PCI configuration space\n");
00176         return 0;
00177     }
00178     
00179     return -1;
00180 }

Here is the call graph for this function:

int pcibus_direct_send_address_1 struct pcidev_s *  pcidev,
int  reg
 

Definition at line 32 of file pcibus_ops.c.

References MOD_NAME, PCIBUS_ADDRESS_1, PCIBUS_CONF_ADDR_1, and printk().

Referenced by pcibus_read_config_1(), and pcibus_write_config_1().

00033 {
00034     int dev_bus  = PCIDEV_BUS(pcidev);
00035     int dev_slot = PCIDEV_SLOT(pcidev);
00036     int dev_fn   = PCIDEV_FN(pcidev);  
00037 
00038     if (reg < 0 || reg > 255) {
00039         printk(MOD_NAME "wrong values in pcibus_direct_read_1 (bus=%02x slot=%02x fn=%01x reg=%d\n", 
00040                dev_bus, dev_slot, dev_fn, reg);
00041         return -1;
00042     }
00043 
00044     outl(PCIBUS_ADDRESS_1(dev_bus, dev_slot, dev_fn, reg), PCIBUS_CONF_ADDR_1);
00045     
00046     return 0;
00047 }

Here is the call graph for this function:

int pcibus_direct_send_address_2 struct pcidev_s *  pcidev,
int  reg
 

Definition at line 79 of file pcibus_ops.c.

References MOD_NAME, PCIBUS_CONF_BUS_2, and printk().

Referenced by pcibus_read_config_2(), and pcibus_write_config_2().

00080 {
00081     int dev_bus  = PCIDEV_BUS(pcidev);
00082     int dev_slot = PCIDEV_SLOT(pcidev);
00083     int dev_fn   = PCIDEV_FN(pcidev);  
00084 
00085     if (reg > 255) {
00086         printk(MOD_NAME "wrong values in pcibus_direct_read_1 (bus=%02x slot=%02x fn=%01x reg=%02x\n", 
00087                dev_bus, dev_slot, dev_fn, reg);
00088         return -1;
00089     }
00090 
00091     outl(0xF0 | (dev_fn << 1), PCIBUS_CONF_BUS_2);
00092     outl(dev_bus, PCIBUS_CONF_BUS_2);
00093     
00094     return 0;
00095 }

Here is the call graph for this function:

int pcibus_ops_init void   ) 
 

Definition at line 198 of file pcibus_ops.c.

References MOD_NAME, pcibus_check_direct_access(), and printk().

Referenced by adi_pcibus_init().

00199 {
00200     printk(MOD_NAME "initializing pcibus_ops\n");
00201 
00202     if (pcibus_check_direct_access() < 0) {
00203         printk(MOD_NAME "can not detect access to PCI configuration space\n");
00204         return -1;
00205     }
00206 
00207     return 0;
00208 }

Here is the call graph for this function:

int pcibus_read_config_1 struct pcidev_s *  pcidev,
int  reg,
u32 value,
int  len
 

Definition at line 49 of file pcibus_ops.c.

References PCIBUS_CONF_DATA_1, and pcibus_direct_send_address_1().

Referenced by pcibus_check_direct_access().

00050 {
00051     pcibus_direct_send_address_1(pcidev, reg);
00052     
00053     switch(len) {
00054         case 4: *value = inl(PCIBUS_CONF_DATA_1);
00055                 break;
00056         case 2: *(u16 *)value = inw(PCIBUS_CONF_DATA_1 + (reg & 0x02)); 
00057                 break;
00058         case 1: *(u8  *)value = inb(PCIBUS_CONF_DATA_1 + (reg & 0x03));
00059     }
00060         
00061     return 0;    
00062 }

Here is the call graph for this function:

int pcibus_read_config_2 struct pcidev_s *  pcidev,
int  reg,
u32 value,
int  len
 

Definition at line 97 of file pcibus_ops.c.

References PCIBUS_ADDRESS_2, and pcibus_direct_send_address_2().

Referenced by pcibus_check_direct_access().

00098 {
00099     int dev_slot = PCIDEV_SLOT(pcidev);
00100 
00101     pcibus_direct_send_address_2(pcidev, reg);
00102     
00103     switch(len) {
00104         case 4: *value = inl(PCIBUS_ADDRESS_2(dev_slot, reg));
00105                 break;
00106         case 2: *(u16 *)value = inw(PCIBUS_ADDRESS_2(dev_slot, reg));
00107                 break;
00108         case 1: *(u8  *)value = inb(PCIBUS_ADDRESS_2(dev_slot, reg));
00109     }
00110         
00111     return 0;    
00112 }

Here is the call graph for this function:

int pcibus_write_config_1 struct pcidev_s *  pcidev,
int  reg,
u32  value,
int  len
 

Definition at line 64 of file pcibus_ops.c.

References PCIBUS_CONF_DATA_1, and pcibus_direct_send_address_1().

Referenced by pcibus_check_direct_access().

00065 {
00066     pcibus_direct_send_address_1(pcidev, reg);
00067     
00068     switch(len) {
00069         case 4: outl(value, PCIBUS_CONF_DATA_1);
00070                 break;
00071         case 2: outw((u16)(value), PCIBUS_CONF_DATA_1 + (reg & 0x02));
00072                 break;
00073         case 1: outb((u8) (value), PCIBUS_CONF_DATA_1 + (reg & 0x03));
00074     }
00075         
00076     return 0;    
00077 }

Here is the call graph for this function:

int pcibus_write_config_2 struct pcidev_s *  pcidev,
int  reg,
u32  value,
int  len
 

Definition at line 114 of file pcibus_ops.c.

References PCIBUS_ADDRESS_2, and pcibus_direct_send_address_2().

Referenced by pcibus_check_direct_access().

00115 {
00116     int dev_slot = PCIDEV_SLOT(pcidev);
00117 
00118     pcibus_direct_send_address_2(pcidev, reg);
00119     
00120     switch(len) {
00121         case 4: outl((u32)(value), PCIBUS_ADDRESS_2(dev_slot, reg));
00122                 break;
00123         case 2: outw((u16)(value), PCIBUS_ADDRESS_2(dev_slot, reg));
00124                 break;
00125         case 1: outb((u8) (value), PCIBUS_ADDRESS_2(dev_slot, reg));
00126     }
00127         
00128     return 0;    
00129 }

Here is the call graph for this function:


Variable Documentation

struct pcibus_ops_s pcibus_primary_ops
 

Definition at line 30 of file pcibus_ops.c.

Referenced by pcibus_check_direct_access(), and pcibus_scan_all().

Dokumentacje wygenerowano programem Doxygen 1.4.2 dla projektu Agnix