system.conf: subsystem VID/DID matching support

- change "vid/did" to "vid:did", old form still supported for now;
- allow "vid:did/subvid:subdid" specification in system.conf, in
  which case a device will be visible to a driver if the subsystem
  VID/DID also match.

Change-Id: I7aef54da1b0bc81e24b5d98f1a28416f38f8b266
This commit is contained in:
David van Moolenbroek 2013-10-01 00:42:41 +02:00 committed by Lionel Sambuc
parent acc46143ab
commit 89332ecdf1
14 changed files with 129 additions and 80 deletions

View file

@ -519,7 +519,7 @@ static void do_io(config_t *cpe, struct rs_start *rs_start)
static void do_pci_device(config_t *cpe, struct rs_start *rs_start) static void do_pci_device(config_t *cpe, struct rs_start *rs_start)
{ {
u16_t vid, did; u16_t vid, did, sub_vid, sub_did;
char *check, *check2; char *check, *check2;
/* Process a list of PCI device IDs */ /* Process a list of PCI device IDs */
@ -536,13 +536,26 @@ static void do_pci_device(config_t *cpe, struct rs_start *rs_start)
cpe->file, cpe->line); cpe->file, cpe->line);
} }
vid= strtoul(cpe->word, &check, 0x10); vid= strtoul(cpe->word, &check, 0x10);
if (check[0] == '/') if (check[0] != ':' && /* LEGACY: */ check[0] != '/') {
did= strtoul(check+1, &check2, 0x10);
if (check[0] != '/' || check2[0] != '\0')
{
fatal("do_pci_device: bad ID '%s' at %s:%d", fatal("do_pci_device: bad ID '%s' at %s:%d",
cpe->word, cpe->file, cpe->line); cpe->word, cpe->file, cpe->line);
} }
did= strtoul(check+1, &check, 0x10);
if (check[0] == '/') {
sub_vid= strtoul(check+1, &check, 0x10);
if (check[0] == ':')
sub_did= strtoul(check+1, &check2, 0x10);
if (check[0] != ':' || check2[0] != '\0') {
fatal("do_pci_device: bad ID '%s' at %s:%d",
cpe->word, cpe->file, cpe->line);
}
} else if (check[0] != '\0') {
fatal("do_pci_device: bad ID '%s' at %s:%d",
cpe->word, cpe->file, cpe->line);
} else {
sub_vid = NO_SUB_VID;
sub_did = NO_SUB_DID;
}
if (rs_start->rss_nr_pci_id >= RS_NR_PCI_DEVICE) if (rs_start->rss_nr_pci_id >= RS_NR_PCI_DEVICE)
{ {
fatal("do_pci_device: too many device IDs (max %d)", fatal("do_pci_device: too many device IDs (max %d)",
@ -550,6 +563,8 @@ static void do_pci_device(config_t *cpe, struct rs_start *rs_start)
} }
rs_start->rss_pci_id[rs_start->rss_nr_pci_id].vid= vid; rs_start->rss_pci_id[rs_start->rss_nr_pci_id].vid= vid;
rs_start->rss_pci_id[rs_start->rss_nr_pci_id].did= did; rs_start->rss_pci_id[rs_start->rss_nr_pci_id].did= did;
rs_start->rss_pci_id[rs_start->rss_nr_pci_id].sub_vid= sub_vid;
rs_start->rss_pci_id[rs_start->rss_nr_pci_id].sub_did= sub_did;
rs_start->rss_nr_pci_id++; rs_start->rss_nr_pci_id++;
} }
} }

View file

@ -6,7 +6,7 @@ service atl2
UMAP # 14 UMAP # 14
IRQCTL # 19 IRQCTL # 19
; ;
pci device 1969/2048; pci device 1969:2048;
ipc ipc
SYSTEM pm rs tty ds vm SYSTEM pm rs tty ds vm
pci inet lwip pci inet lwip

View file

@ -8,7 +8,7 @@ service dec21140A
IRQCTL # 19 IRQCTL # 19
DEVIO # 21 DEVIO # 21
; ;
pci device 1011/0009; pci device 1011:0009;
ipc ipc
SYSTEM pm rs log tty ds vm SYSTEM pm rs log tty ds vm
pci inet lwip pci inet lwip

View file

@ -7,13 +7,13 @@ service e1000
IRQCTL # 19 IRQCTL # 19
DEVIO # 21 DEVIO # 21
; ;
pci device 8086/100e; pci device 8086:100e;
pci device 8086/100f; pci device 8086:100f;
pci device 8086/107c; pci device 8086:107c;
pci device 8086/10cd; pci device 8086:10cd;
pci device 8086/10d3; pci device 8086:10d3;
pci device 8086/10de; pci device 8086:10de;
pci device 8086/105e; pci device 8086:105e;
ipc ipc
SYSTEM pm rs log tty ds vm SYSTEM pm rs log tty ds vm
pci inet lwip ; pci inet lwip ;

View file

@ -8,13 +8,13 @@ service fxp
IRQCTL # 19 IRQCTL # 19
DEVIO # 21 DEVIO # 21
; ;
pci device 8086/1031; pci device 8086:1031;
pci device 8086/1032; pci device 8086:1032;
pci device 8086/103d; pci device 8086:103d;
pci device 8086/1064; pci device 8086:1064;
pci device 8086/1229; pci device 8086:1229;
pci device 8086/2449; pci device 8086:2449;
pci device 8086/1209; pci device 8086:1209;
ipc ipc
SYSTEM pm rs log tty ds vm SYSTEM pm rs log tty ds vm
pci inet lwip amddev pci inet lwip amddev

View file

@ -8,7 +8,7 @@ service lance
IRQCTL # 19 IRQCTL # 19
DEVIO # 21 DEVIO # 21
; ;
pci device 1022/2000; pci device 1022:2000;
uid 0; uid 0;
}; };

View file

@ -70,6 +70,8 @@ static struct pcidev
u8_t pd_infclass; u8_t pd_infclass;
u16_t pd_vid; u16_t pd_vid;
u16_t pd_did; u16_t pd_did;
u16_t pd_sub_vid;
u16_t pd_sub_did;
u8_t pd_ilr; u8_t pd_ilr;
u8_t pd_inuse; u8_t pd_inuse;
@ -737,7 +739,7 @@ static void pci_intel_init()
dstr= "unknown device"; dstr= "unknown device";
if (debug) if (debug)
{ {
printf("pci_intel_init: %s (%04X/%04X)\n", printf("pci_intel_init: %s (%04X:%04X)\n",
dstr, vid, did); dstr, vid, did);
} }
@ -774,7 +776,7 @@ static void pci_intel_init()
static void probe_bus(int busind) static void probe_bus(int busind)
{ {
u32_t dev, func, t3; u32_t dev, func, t3;
u16_t vid, did, sts; u16_t vid, did, sts, sub_vid, sub_did;
u8_t headt; u8_t headt;
u8_t baseclass, subclass, infclass; u8_t baseclass, subclass, infclass;
int devind, busnr; int devind, busnr;
@ -831,12 +833,15 @@ static void probe_bus(int busind)
} }
} }
sub_vid= pci_attr_r16(devind, PCI_SUBVID);
sub_did= pci_attr_r16(devind, PCI_SUBDID);
dstr= pci_dev_name(vid, did); dstr= pci_dev_name(vid, did);
if (debug) if (debug)
{ {
if (dstr) if (dstr)
{ {
printf("%d.%lu.%lu: %s (%04X/%04X)\n", printf("%d.%lu.%lu: %s (%04X:%04X)\n",
busnr, (unsigned long)dev, busnr, (unsigned long)dev,
(unsigned long)func, dstr, (unsigned long)func, dstr,
vid, did); vid, did);
@ -851,8 +856,7 @@ static void probe_bus(int busind)
} }
printf("Device index: %d\n", devind); printf("Device index: %d\n", devind);
printf("Subsystem: Vid 0x%x, did 0x%x\n", printf("Subsystem: Vid 0x%x, did 0x%x\n",
pci_attr_r16(devind, PCI_SUBVID), sub_vid, sub_did);
pci_attr_r16(devind, PCI_SUBDID));
} }
baseclass= pci_attr_r8_u(devind, PCI_BCR); baseclass= pci_attr_r8_u(devind, PCI_BCR);
@ -886,6 +890,8 @@ static void probe_bus(int busind)
pcidev[devind].pd_infclass= infclass; pcidev[devind].pd_infclass= infclass;
pcidev[devind].pd_vid= vid; pcidev[devind].pd_vid= vid;
pcidev[devind].pd_did= did; pcidev[devind].pd_did= did;
pcidev[devind].pd_sub_vid= sub_vid;
pcidev[devind].pd_sub_did= sub_did;
pcidev[devind].pd_inuse= 0; pcidev[devind].pd_inuse= 0;
pcidev[devind].pd_bar_nr= 0; pcidev[devind].pd_bar_nr= 0;
record_irq(devind); record_irq(devind);
@ -1531,7 +1537,7 @@ static void complete_bars(void)
if (debug) if (debug)
{ {
printf( printf(
"pci device %d (%04x/%04x), bar %d: base 0x%x, size 0x%x\n", "pci device %d (%04x:%04x), bar %d: base 0x%x, size 0x%x\n",
i, pcidev[i].pd_vid, pcidev[i].pd_did, i, pcidev[i].pd_vid, pcidev[i].pd_did,
j, base, size); j, base, size);
} }
@ -1765,7 +1771,7 @@ int busind;
dstr= "unknown device"; dstr= "unknown device";
if (debug) if (debug)
{ {
printf("found ISA bridge (%04X/%04X) %s\n", printf("found ISA bridge (%04X:%04X) %s\n",
vid, did, dstr); vid, did, dstr);
} }
pcibus[busind].pb_isabridge_dev= bridge_dev; pcibus[busind].pb_isabridge_dev= bridge_dev;
@ -1803,7 +1809,7 @@ int busind;
if (debug) if (debug)
{ {
printf( printf(
"(warning) unsupported ISA bridge %04X/%04X for bus %d\n", "(warning) unsupported ISA bridge %04X:%04X for bus %d\n",
pcidev[unknown_bridge].pd_vid, pcidev[unknown_bridge].pd_vid,
pcidev[unknown_bridge].pd_did, busind); pcidev[unknown_bridge].pd_did, busind);
} }
@ -1899,7 +1905,7 @@ int busind;
t3 != PCI_T3_PCI2PCI_SUBTR) t3 != PCI_T3_PCI2PCI_SUBTR)
{ {
printf( printf(
"Unknown PCI class %02x:%02x:%02x for PCI-to-PCI bridge, device %04X/%04X\n", "Unknown PCI class %02x/%02x/%02x for PCI-to-PCI bridge, device %04X:%04X\n",
baseclass, subclass, infclass, baseclass, subclass, infclass,
vid, did); vid, did);
continue; continue;
@ -1908,7 +1914,7 @@ int busind;
t3 != PCI_T3_CARDBUS) t3 != PCI_T3_CARDBUS)
{ {
printf( printf(
"Unknown PCI class %02x:%02x:%02x for Cardbus bridge, device %04X/%04X\n", "Unknown PCI class %02x/%02x/%02x for Cardbus bridge, device %04X:%04X\n",
baseclass, subclass, infclass, baseclass, subclass, infclass,
vid, did); vid, did);
continue; continue;
@ -1917,7 +1923,7 @@ int busind;
if (debug) if (debug)
{ {
printf("%u.%u.%u: PCI-to-PCI bridge: %04X/%04X\n", printf("%u.%u.%u: PCI-to-PCI bridge: %04X:%04X\n",
pcidev[devind].pd_busnr, pcidev[devind].pd_busnr,
pcidev[devind].pd_dev, pcidev[devind].pd_dev,
pcidev[devind].pd_func, vid, did); pcidev[devind].pd_func, vid, did);
@ -2640,6 +2646,7 @@ static int visible(aclp, devind)
struct rs_pci *aclp; struct rs_pci *aclp;
int devind; int devind;
{ {
u16_t acl_sub_vid, acl_sub_did;
int i; int i;
u32_t class_id; u32_t class_id;
@ -2651,8 +2658,14 @@ int devind;
/* Check whether the caller is allowed to get this device. */ /* Check whether the caller is allowed to get this device. */
for (i= 0; i<aclp->rsp_nr_device; i++) for (i= 0; i<aclp->rsp_nr_device; i++)
{ {
acl_sub_vid = aclp->rsp_device[i].sub_vid;
acl_sub_did = aclp->rsp_device[i].sub_did;
if (aclp->rsp_device[i].vid == pcidev[devind].pd_vid && if (aclp->rsp_device[i].vid == pcidev[devind].pd_vid &&
aclp->rsp_device[i].did == pcidev[devind].pd_did) aclp->rsp_device[i].did == pcidev[devind].pd_did &&
(acl_sub_vid == NO_SUB_VID ||
acl_sub_vid == pcidev[devind].pd_sub_vid) &&
(acl_sub_did == NO_SUB_DID ||
acl_sub_did == pcidev[devind].pd_sub_did))
{ {
return TRUE; return TRUE;
} }

View file

@ -7,23 +7,23 @@ service rtl8139
IRQCTL # 19 IRQCTL # 19
DEVIO # 21 DEVIO # 21
; ;
pci device 10ec/8139; pci device 10ec:8139;
pci device 02ac/1012; pci device 02ac:1012;
pci device 1065/8139; pci device 1065:8139;
pci device 1113/1211; pci device 1113:1211;
pci device 1186/1300; pci device 1186:1300;
pci device 1186/1340; pci device 1186:1340;
pci device 11db/1234; pci device 11db:1234;
pci device 1259/a117; pci device 1259:a117;
pci device 1259/a11e; pci device 1259:a11e;
pci device 126c/1211; pci device 126c:1211;
pci device 13d1/ab06; pci device 13d1:ab06;
pci device 1432/9130; pci device 1432:9130;
pci device 14ea/ab06; pci device 14ea:ab06;
pci device 14ea/ab07; pci device 14ea:ab07;
pci device 1500/1360; pci device 1500:1360;
pci device 1743/8139; pci device 1743:8139;
pci device 4033/1360; pci device 4033:1360;
ipc ipc
SYSTEM pm rs log tty ds vm SYSTEM pm rs log tty ds vm
pci inet lwip amddev pci inet lwip amddev

View file

@ -8,16 +8,16 @@ service rtl8169
IRQCTL # 19 IRQCTL # 19
DEVIO # 21 DEVIO # 21
; ;
pci device 10ec/8129; pci device 10ec:8129;
pci device 10ec/8136; pci device 10ec:8136;
pci device 10ec/8167; pci device 10ec:8167;
pci device 10ec/8169; pci device 10ec:8169;
pci device 10ec/8168; pci device 10ec:8168;
pci device 1186/4300; pci device 1186:4300;
pci device 1259/c107; pci device 1259:c107;
pci device 1385/8169; pci device 1385:8169;
pci device 16ec/0116; pci device 16ec:0116;
pci device 1737/1032; pci device 1737:1032;
ipc ipc
SYSTEM pm rs log tty ds vm SYSTEM pm rs log tty ds vm
pci inet lwip amddev pci inet lwip amddev

View file

@ -9,5 +9,5 @@ service virtio_net
DEVIO DEVIO
; ;
pci device 1af4/1000; pci device 1af4:1000;
} }

View file

@ -255,7 +255,7 @@ service dp8390
DEVIO # 21 DEVIO # 21
SDEVIO # 22 SDEVIO # 22
; ;
pci device 10ec/8029; pci device 10ec:8029;
uid 0; uid 0;
}; };
@ -348,7 +348,7 @@ service virtio_blk
DEVIO DEVIO
; ;
pci device 1af4/1001; pci device 1af4:1001;
}; };
service at_wini service at_wini
@ -437,8 +437,8 @@ service orinoco
DEVIO # 21 DEVIO # 21
VM_MAP # 30 VM_MAP # 30
; ;
pci device 1260/3873; pci device 1260:3873;
pci device 1186/1300; pci device 1186:1300;
uid 0; uid 0;
}; };
@ -449,7 +449,7 @@ service es1370
IRQCTL # 19 IRQCTL # 19
DEVIO # 21 DEVIO # 21
; ;
pci device 1274/5000; pci device 1274:5000;
}; };
service es1371 service es1371
@ -459,7 +459,7 @@ service es1371
IRQCTL # 19 IRQCTL # 19
DEVIO # 21 DEVIO # 21
; ;
pci device 1274/1371; pci device 1274:1371;
}; };
service ti1225 service ti1225
@ -467,12 +467,12 @@ service ti1225
system system
IRQCTL # 19 IRQCTL # 19
; ;
pci device 104c/ac1c; pci device 104c:ac1c;
}; };
service amddev service amddev
{ {
pci device 1022/1103; pci device 1022:1103;
system system
UMAP_REMOTE # 17 UMAP_REMOTE # 17
; ;
@ -671,7 +671,7 @@ service vbox
IRQCTL # 19 IRQCTL # 19
DEVIO # 21 DEVIO # 21
; ;
pci device 80ee/cafe; pci device 80ee:cafe;
ipc ipc
SYSTEM SYSTEM
PM PM

View file

@ -47,6 +47,20 @@ struct rss_label
size_t l_len; size_t l_len;
}; };
struct rs_pci_id {
u16_t vid;
u16_t did;
u16_t sub_vid;
u16_t sub_did;
};
#define NO_SUB_VID 0xffff
#define NO_SUB_DID 0xffff
struct rs_pci_class {
u32_t pciclass;
u32_t mask;
};
/* Arguments needed to start a new driver or server */ /* Arguments needed to start a new driver or server */
struct rs_start struct rs_start
{ {
@ -68,9 +82,9 @@ struct rs_start
int rss_nr_io; int rss_nr_io;
struct { unsigned base; unsigned len; } rss_io[RSS_NR_IO]; struct { unsigned base; unsigned len; } rss_io[RSS_NR_IO];
int rss_nr_pci_id; int rss_nr_pci_id;
struct { u16_t vid; u16_t did; } rss_pci_id[RS_NR_PCI_DEVICE]; struct rs_pci_id rss_pci_id[RS_NR_PCI_DEVICE];
int rss_nr_pci_class; int rss_nr_pci_class;
struct { u32_t pciclass; u32_t mask; } rss_pci_class[RS_NR_PCI_CLASS]; struct rs_pci_class rss_pci_class[RS_NR_PCI_CLASS];
bitchunk_t rss_system[SYS_CALL_MASK_SIZE]; bitchunk_t rss_system[SYS_CALL_MASK_SIZE];
struct rss_label rss_label; struct rss_label rss_label;
char *rss_ipc; char *rss_ipc;
@ -94,9 +108,9 @@ struct rs_pci
char rsp_label[RS_MAX_LABEL_LEN]; char rsp_label[RS_MAX_LABEL_LEN];
int rsp_endpoint; int rsp_endpoint;
int rsp_nr_device; int rsp_nr_device;
struct { u16_t vid; u16_t did; } rsp_device[RS_NR_PCI_DEVICE]; struct rs_pci_id rsp_device[RS_NR_PCI_DEVICE];
int rsp_nr_class; int rsp_nr_class;
struct { u32_t pciclass; u32_t mask; } rsp_class[RS_NR_PCI_CLASS]; struct rs_pci_class rsp_class[RS_NR_PCI_CLASS];
}; };
/* Definition of a public entry of the system process table. */ /* Definition of a public entry of the system process table. */

View file

@ -144,19 +144,22 @@ specifies the quantum size (ms) the scheduler must consider the service for.
The default is specified in \fB<minix/priv.h>\fR (see macro \fBDSRV_QT\fR). The default is specified in \fB<minix/priv.h>\fR (see macro \fBDSRV_QT\fR).
.RE .RE
.PP .PP
\fBpci device\fR \fI<vid/did>\fR\fB;\fR \fBpci device\fR \fI<vid:did[/subvid:subdid]>\fR\fB;\fR
.PP .PP
.RS .RS
specifies the PCI device IDs the system service is allowed to use specifies the PCI device IDs the system service is allowed to use
(only used for device drivers). (only used for device drivers). Optionally, a subsystem ID may be provided
for more precise (limited) matching.
The default is to allow no PCI device IDs. The default is to allow no PCI device IDs.
.RE .RE
.PP .PP
\fBpci class\fR \fI<class1/mask1 class2/mask2...classN/maskN>\fR\fB;\fR \fBpci class\fR \fI<class[/subclass[/progif]]>\fR\fB;\fR
.PP .PP
.RS .RS
specifies the PCI classes the system service is allowed to use specifies the PCI classes the system service is allowed to use
(only used for device drivers). (only used for device drivers).
Optionally, a subclass code and a programming interface code may be provided
for more precise (limited) matching.
The default is to allow no PCI classes. The default is to allow no PCI classes.
.RE .RE
.PP .PP

View file

@ -1627,10 +1627,14 @@ endpoint_t source;
for (i= 0; i<rpub->pci_acl.rsp_nr_device; i++) { for (i= 0; i<rpub->pci_acl.rsp_nr_device; i++) {
rpub->pci_acl.rsp_device[i].vid= rs_start->rss_pci_id[i].vid; rpub->pci_acl.rsp_device[i].vid= rs_start->rss_pci_id[i].vid;
rpub->pci_acl.rsp_device[i].did= rs_start->rss_pci_id[i].did; rpub->pci_acl.rsp_device[i].did= rs_start->rss_pci_id[i].did;
rpub->pci_acl.rsp_device[i].sub_vid= rs_start->rss_pci_id[i].sub_vid;
rpub->pci_acl.rsp_device[i].sub_did= rs_start->rss_pci_id[i].sub_did;
if(rs_verbose) if(rs_verbose)
printf("RS: init_slot: PCI %04x/%04x\n", printf("RS: init_slot: PCI %04x/%04x (sub %04x:%04x)\n",
rpub->pci_acl.rsp_device[i].vid, rpub->pci_acl.rsp_device[i].vid,
rpub->pci_acl.rsp_device[i].did); rpub->pci_acl.rsp_device[i].did,
rpub->pci_acl.rsp_device[i].sub_vid,
rpub->pci_acl.rsp_device[i].sub_did);
} }
if (rs_start->rss_nr_pci_class > RS_NR_PCI_CLASS) { if (rs_start->rss_nr_pci_class > RS_NR_PCI_CLASS) {
printf("RS: init_slot: too many PCI class IDs\n"); printf("RS: init_slot: too many PCI class IDs\n");