Subversion Repositories shark

Rev

Rev 184 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
#include <ll/i386/hw-instr.h>
2
#include <ll/i386/hw-data.h>
3
#include <ll/i386/hw-arch.h>
4
#include <ll/i386/hw-io.h>
5
#include <ll/i386/cons.h>
6
#include <ll/stdlib.h>
7
#include <drivers/llpci.h>
8
#include <drivers/pci.h>
9
#include <drivers/linuxpci.h>
10
 
16 pj 11
#include <kernel/log.h>
12
 
2 pj 13
static int ndev = 0;
14
static struct pci_des pci_devs[N_MAX_DEVS];
15
 
184 giacomo 16
static int initialized = 0;
17
 
2 pj 18
/* scan the bus to find all the connected devices */
19
int scan_bus(struct pci_des *p_des)
20
{
21
    int ndev;
22
    DWORD tmp;
23
    BYTE hdr;
24
    int j, ok;
25
    BYTE bus, b;
26
    WORD dev;
27
    int present;
28
 
29
    if (pcibios_present() == 0) return -1;
30
    ndev = 0;
31
 
49 pj 32
    for (bus = 0; bus <= 1; bus++) {
2 pj 33
        for (dev = 0; dev <= 0xFF; dev++) {
34
            present = 0;
35
            if ((dev & 0x07) == 0) {
36
                present = pcibios_read_config_byte(bus, dev, 0x0e, &hdr);
37
            }
38
            if (hdr & 0x80) {
39
                present = 1;
40
            }
41
            if (present) {
42
                ok = pcibios_read_config_dword(bus, dev, 0, &tmp);
43
                if ( ok && (((tmp & 0xFFFF) != 0xFFFF) && ((tmp >> 16) != 0xFFFF))) {
44
                    p_des[ndev].bus = bus;
45
                    p_des[ndev].dev = dev;
46
                    for (j = 0; j <= 255; j++) {
47
                        pcibios_read_config_byte(bus, dev, j, &b);
48
                        p_des[ndev].mem[j] = b;
49
                    }
50
                    ndev++;
51
                }      
52
            }
53
        }
54
    }
55
    return ndev;
56
}
57
 
58
struct pci_regs *pci_device(WORD vendor, WORD device, WORD index, BYTE *bus, BYTE *dev)
59
{
60
    int i, curr;
61
    struct pci_regs *regs;
62
 
63
    curr = 0;
64
    for (i = 0; i < ndev; i++) {
65
        regs = (struct pci_regs *)pci_devs[i].mem;
66
        if ((regs->VendorId == vendor) && (regs->DeviceId == device)) {
67
            if (curr == index) {
68
                *dev = pci_devs[i].dev;
69
                *bus = pci_devs[i].bus;
70
                return regs;
71
            }
72
            ++curr;
73
        }
74
    }
75
    return NULL;
76
}
77
 
78
struct pci_regs *pci_class(DWORD class_code, WORD index, BYTE *bus, BYTE *dev)
79
{
80
    int i, curr;
81
    struct pci_regs *regs;
82
 
83
    curr = 0;
84
    for (i = 0; i < ndev; i++) {
85
        regs = (struct pci_regs *)pci_devs[i].mem;
86
        if ((regs->ClassCode << 8) == class_code) {
87
            if (curr == index) {
88
                *dev = pci_devs[i].dev;
89
                *bus = pci_devs[i].bus;
90
                return regs;
91
            }
92
            ++curr;
93
        }
94
    }
95
    return NULL;
96
}
97
 
98
int pcibios_find_device(WORD vendor, WORD device, WORD index, BYTE *bus, BYTE *dev)
99
{
100
 
101
        if (pci_device(vendor, device, index, bus, dev) != NULL) {
102
                return PCIBIOS_SUCCESSFUL;
103
        } else {
104
                return PCIBIOS_DEVICE_NOT_FOUND;
105
        }
106
}
107
int pcibios_find_class(DWORD class_code, WORD index, BYTE *bus, BYTE *dev)
108
{
109
 
110
        if (pci_class(class_code, index, bus, dev) != NULL) {
16 pj 111
#ifdef DEBUG_PCI
112
          printk(KERN_DEBUG "PCIBIOS_FIND_CLASS:"
113
                 "found at bus %d, dev %d\n", *bus, *dev);
114
#endif
2 pj 115
                return PCIBIOS_SUCCESSFUL;
116
        } else {
117
                return PCIBIOS_DEVICE_NOT_FOUND;
118
        }
119
}
120
 
121
 
122
/* shows the detected devices */
123
void pci_show(void)
124
{
125
    int i;
126
    struct pci_regs *r;
127
 
16 pj 128
    printk(KERN_INFO "DevLib PCI support\n\n");
129
    printk(KERN_INFO "PCI config type %d\n", pcibios_present());
130
    printk(KERN_INFO "%d PCI devices found:\n\n", ndev);
2 pj 131
    for(i = 0; i < ndev; i++) {
132
        r = (struct pci_regs *) pci_devs[i].mem;
16 pj 133
        printk(KERN_INFO "%d: bus %d dev %d\n",
134
               i, pci_devs[i].bus, pci_devs[i].dev);
198 pj 135
        printk(KERN_INFO "Vendor: %s Class: %s\n", pci_strvendor(r->VendorId),
136
               pci_strclass(r->ClassCode << 8));
2 pj 137
    }
138
}
139
 
140
/*Linux-->unsigned long pci_init(unsigned long mem_start, unsigned long mem_end) */
141
/*      H-PCI -->       void pci_init(void)                             */
142
/*      (mem_start/mem_end have no sense)                               */
143
 
144
int pci_init(void)
145
{
184 giacomo 146
    if (initialized == 1) return 1;
147
 
2 pj 148
    if (pcibios_init() == -1) {
149
        return -1;
150
    }
184 giacomo 151
 
2 pj 152
    ndev = scan_bus(pci_devs);
184 giacomo 153
 
154
    initialized = 1;
155
 
2 pj 156
    return 1;
184 giacomo 157
 
2 pj 158
}