From 352699137996048946554f106e3107cc82cd731c Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 28 Sep 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-09-28 --- pc/devpccard.c | 33 +++++++++++++++++++++++++++++++-- pc/devusb.c | 2 +- pc/fns.h | 1 + pc/pci.c | 20 ++++++++++++++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/pc/devpccard.c b/pc/devpccard.c index 1d109bace54f6b3f4528f77a2b0d1e6a7686aae4..41899949a706b34f476615fa9bc6bc3920739c2f 100644 --- a/pc/devpccard.c +++ b/pc/devpccard.c @@ -18,6 +18,7 @@ enum { Ricoh_vid = 0x1180, Ricoh_476_did = 0x0476, + Ricoh_478_did = 0x0478, Nslots = 4, /* Maximum number of CardBus slots to use */ @@ -36,6 +37,7 @@ typedef struct { static variant_t variant[] = { { Ricoh_vid, Ricoh_476_did, "Ricoh 476 PCI/Cardbus bridge", }, +{ Ricoh_vid, Ricoh_478_did, "Ricoh 478 PCI/Cardbus bridge", }, { TI_vid, TI_1450_did, "TI PCI-1450 Cardbus Controller", }, { TI_vid, TI_1251A_did, "TI PCI-1251A Cardbus Controller", }, }; @@ -506,6 +508,7 @@ devpccardlink(void) ulong baddr; cb_t *cb; int slot; + uchar pin; for (i = 0; i != nelem(variant); i++) if (pci->vid == variant[i].r_vid && pci->did == variant[i].r_did) @@ -523,9 +526,35 @@ devpccardlink(void) if (intl != -1 && intl != pci->intl) intrenable(pci->intl, interrupt, cb, pci->tbdf, "cardbus"); intl = pci->intl; - baddr = pcicfgr32(cb->cb_pci, PciBAR0); - cb->cb_regs = (ulong *)KADDR(upamalloc(baddr, 4096, 0)); + // Set up PCI bus numbers if needed. + if (pcicfgr8(pci, PciSBN) == 0) { + static int busbase = 0x20; + + pcicfgw8(pci, PciSBN, busbase); + pcicfgw8(pci, PciUBN, busbase + 2); + busbase += 3; + } + + // Patch up intl if needed. + if ((pin = pcicfgr8(pci, PciINTP)) != 0 && + (pci->intl == 0xff || pci->intl == 0)) { + pci->intl = pciipin(nil, pin); + pcicfgw8(pci, PciINTL, pci->intl); + + if (pci->intl == 0xff || pci->intl == 0) + print("#Y%d: No interrupt?\n", (int)(cb - cbslots)); + } + + if ((baddr = pcicfgr32(cb->cb_pci, PciBAR0)) == 0) { + int align = (pci->did == Ricoh_478_did)? 0x10000: 0x1000; + + baddr = upamalloc(baddr, align, align); + pcicfgw32(cb->cb_pci, PciBAR0, baddr); + cb->cb_regs = (ulong *)KADDR(baddr); + } + else + cb->cb_regs = (ulong *)KADDR(upamalloc(baddr, 4096, 0)); cb->cb_state = SlotEmpty; /* Don't really know what to do with this... */ diff --git a/pc/devusb.c b/pc/devusb.c index a8a7739bcfa305bd10446c554f8846e783275de9..1173bffe355fdbcaa2a4d215b75b27c5ea9f8fcf 100644 --- a/pc/devusb.c +++ b/pc/devusb.c @@ -1965,7 +1965,7 @@ usbwrite(Chan *c, void *a, long n, vlong) e->err = nil; }else if(nf == 6 && strcmp(fields[0], "ep") == 0){ /* ep n `bulk' mode maxpkt nbuf OR - * ep n period mode samplesize KHz + * ep n period mode samplesize hz */ i = strtoul(fields[1], nil, 0); if(i < 0 || i >= nelem(d->ep)) { diff --git a/pc/fns.h b/pc/fns.h index 406f150975e01983cf46f376913543286bb7fa4d..5886deff8eea6463a634ca1f51e345fc7994b815 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -100,6 +100,7 @@ void pcicfgw16(Pcidev*, int, int); void pcicfgw32(Pcidev*, int, int); void pciclrbme(Pcidev*); void pcihinv(Pcidev*); +uchar pciipin(Pcidev *, uchar); Pcidev* pcimatch(Pcidev*, int, int); Pcidev* pcimatchtbdf(int); void pcireset(void); diff --git a/pc/pci.c b/pc/pci.c index f3f386adc6b141424065c834b8a9af8c943c0096..660ff0e377a8a6f6455a9c8208cf67700b63d95a 100644 --- a/pc/pci.c +++ b/pc/pci.c @@ -819,6 +819,26 @@ pcimatchtbdf(int tbdf) return pcidev; } +uchar +pciipin(Pcidev *pci, uchar pin) +{ + if (pci == nil) + pci = pcilist; + + while (pci) { + uchar intl; + + if (pcicfgr8(pci, PciINTP) == pin && pci->intl != 0 && pci->intl != 0xff) + return pci->intl; + + if (pci->bridge && (intl = pciipin(pci->bridge, pin)) != 0) + return intl; + + pci = pci->list; + } + return 0; +} + static void pcilhinv(Pcidev* p) {