Subversion Repositories shark

Rev

Rev 2 | 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
 
7
#include <ll/stdlib.h>
8
 
9
 
10
 
11
#include <drivers/llpci.h>
12
#include <drivers/pci.h>
13
#include <drivers/linuxpci.h>
14
 
15
static int ndev = 0;
16
static struct pci_des pci_devs[N_MAX_DEVS];
17
 
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
 
32
    for (bus = 0; bus <= 0; bus++) {
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) {
111
cprintf("PCIBIOS_FIND_CLASS: found at bus %d, dev %d\n", *bus, *dev);
112
                return PCIBIOS_SUCCESSFUL;
113
        } else {
114
                return PCIBIOS_DEVICE_NOT_FOUND;
115
        }
116
}
117
 
118
 
119
/* shows the detected devices */
120
void pci_show(void)
121
{
122
    int i;
123
    struct pci_regs *r;
124
 
125
    cprintf("                DevLib PCI support\n\n");
126
    cprintf("        PCI config type %d\n", pcibios_present());
127
    cprintf("        %d PCI devices found:\n\n", ndev);
128
    for(i = 0; i < ndev; i++) {
129
        cprintf("        %d: bus %d dev %d\n",i , pci_devs[i].bus, pci_devs[i].dev);
130
        r = (struct pci_regs *) pci_devs[i].mem;
131
        cprintf("                Vendor: %s", pci_strvendor(r->VendorId));
132
        cprintf("        Class: %s\n", pci_strclass(r->ClassCode << 8));
133
    }
134
}
135
 
136
/*Linux-->unsigned long pci_init(unsigned long mem_start, unsigned long mem_end) */
137
/*      H-PCI -->       void pci_init(void)                             */
138
/*      (mem_start/mem_end have no sense)                               */
139
 
140
int pci_init(void)
141
{
142
    if (pcibios_init() == -1) {
143
        return -1;
144
    }
145
    ndev = scan_bus(pci_devs);
146
    return 1;
147
}