Subversion Repositories shark

Rev

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