]> mj.ucw.cz Git - pciutils.git/blob - lib/sylixos-device.c
lspci: Show Slot Power Limit values above EFh
[pciutils.git] / lib / sylixos-device.c
1 /*
2  *  The PCI Library -- Direct Configuration access via SylixOS Ports
3  *
4  *  Copyright (c) 2018 YuJian.Gong <gongyujian@acoinfo.com>
5  *
6  *  Can be freely distributed and used under the terms of the GNU GPL.
7  */
8
9 #define _GNU_SOURCE
10 #define  __SYLIXOS_KERNEL
11 #define  __SYLIXOS_PCI_DRV
12 #include <SylixOS.h>
13 #include <stdlib.h>
14 #include <string.h>
15
16 #include "internal.h"
17
18 static void
19 sylixos_scan(struct pci_access *a)
20 {
21   u8 busmap[256];
22   int bus;
23
24   memset(busmap, 0, sizeof(busmap));
25
26   for (bus = 0; bus < PCI_MAX_BUS; bus++)
27     if (!busmap[bus])
28       pci_generic_scan_bus(a, busmap, bus);
29 }
30
31 static void
32 sylixos_config(struct pci_access *a)
33 {
34   pci_define_param(a, "sylixos.path", PCI_PATH_SYLIXOS_DEVICE, "Path to the SylixOS PCI device");
35 }
36
37 static int
38 sylixos_detect(struct pci_access *a)
39 {
40   char *name = pci_get_param(a, "sylixos.path");
41
42   if (access(name, R_OK))
43     {
44       a->warning("Cannot open %s", name);
45       return 0;
46     }
47
48   a->debug("...using %s", name);
49   return 1;
50 }
51
52 static void
53 sylixos_init(struct pci_access *a UNUSED)
54 {
55 }
56
57 static void
58 sylixos_cleanup(struct pci_access *a UNUSED)
59 {
60 }
61
62 static int
63 sylixos_read(struct pci_dev *d, int pos, byte *buf, int len)
64 {
65   int ret = -1;
66   u8  data_byte = -1;
67   u16 data_word = -1;
68   u32 data_dword = -1;
69
70   if (!(len == 1 || len == 2 || len == 4))
71     return pci_generic_block_read(d, pos, buf, len);
72
73   if (pos >= 256)
74     return 0;
75
76   switch (len)
77     {
78     case 1:
79       ret = pciConfigInByte(d->bus, d->dev, d->func, pos, &data_byte);
80       if (ret != ERROR_NONE)
81         return 0;
82       buf[0] = (u8)data_byte;
83       break;
84
85     case 2:
86       ret = pciConfigInWord(d->bus, d->dev, d->func, pos, &data_word);
87       if (ret != ERROR_NONE)
88         return 0;
89       ((u16 *) buf)[0] = cpu_to_le16(data_word);
90       break;
91
92     case 4:
93       ret = pciConfigInDword(d->bus, d->dev, d->func, pos, &data_dword);
94       if (ret != ERROR_NONE)
95         return 0;
96       ((u32 *) buf)[0] = cpu_to_le32(data_dword);
97       break;
98     }
99
100   return 1;
101 }
102
103 static int
104 sylixos_write(struct pci_dev *d, int pos, byte *buf, int len)
105 {
106   int ret = PX_ERROR;
107   u8 data_byte;
108   u16 data_word;
109   u32 data_dword;
110
111   if (!(len == 1 || len == 2 || len == 4))
112     return pci_generic_block_write(d, pos, buf, len);
113
114   if (pos >= 256)
115     return 0;
116
117   switch (len)
118     {
119     case 1:
120       data_byte = buf[0];
121       ret = pciConfigOutByte(d->bus, d->dev, d->func, pos, data_byte);
122       if (ret != ERROR_NONE)
123         return 0;
124       break;
125
126     case 2:
127       data_word = le16_to_cpu(((u16 *) buf)[0]);
128       ret = pciConfigOutWord(d->bus, d->dev, d->func, pos, data_word);
129       if (ret != ERROR_NONE)
130         return 0;
131       break;
132
133     case 4:
134       data_dword = le32_to_cpu(((u32 *) buf)[0]);
135       ret = pciConfigOutDword(d->bus, d->dev, d->func, pos, data_dword);
136       if (ret != ERROR_NONE)
137         return 0;
138       break;
139     }
140
141   return 1;
142 }
143
144 struct pci_methods pm_sylixos_device = {
145   "sylixos-device",
146   "SylixOS /proc/pci device",
147   sylixos_config,
148   sylixos_detect,
149   sylixos_init,
150   sylixos_cleanup,
151   sylixos_scan,
152   pci_generic_fill_info,
153   sylixos_read,
154   sylixos_write,
155   NULL,                 // no read_vpd
156   NULL,                 // no init_dev
157   NULL,                 // no cleanup_dev
158 };