Compare commits

...

7 commits

Author SHA1 Message Date
cinap_lenrek
837c596bdf usbdwc: preserve Prtpwr bit for portstatus, turn off power by default, handle channel timeout
preserve the Prtpwr bit in portstatus instead of
unconditionally setting it.

turn off port powert on init. (let usbd will turn it on).

make chanio() halt the channel and error out
when interrupt status is 0 after timout.

this happens when the port is powered off.
2024-12-16 05:14:45 +00:00
cinap_lenrek
5028b882da usbehci: implement portpower control for rootports 2024-12-16 01:52:12 +00:00
Ori Bernstein
eff4b93652 acme/Mail: correct message line number for partially hidden threads 2024-12-15 21:56:54 +00:00
cinap_lenrek
f86cc3e912 usbxhci: preserve RsvdP bits in registers, print recovery reason, print base address.
Preserve reserved "RsvdP" bits in registers
according to 2019 xhci specification 1.2.

Print the USBSTS register and event-ring stopped flag
on recovery.

Add the controller base address in prints,
so it can be identified what errors belong
to what controller.
2024-12-15 21:27:00 +00:00
cinap_lenrek
d38dbf6415 nusb/usbd: use longer reset delay for rootports
Make reset delays more conservative:

The usb spec says root ports need 50ms reset minimum, use 100ms.
The usb spec says hub ports need 20ms minimum, use 50ms.
2024-12-15 21:19:57 +00:00
Ori Bernstein
2f685dd96b git/branch: stop emitting incorrect 'merge failed' messages 2024-12-14 05:32:05 +00:00
cinap_lenrek
473ebd0f9e ndb/dns: don't refuse queries when delegated subareas
We used to always provide soa and ns hints when
we where not authoritative.

This changed with the last commit, where we
would instead return refused error.

But this breaks when we want to explicitely
delegate to another nameserver, so add parameter
to inmyarea() to get the delegated soa out,
and provide delegated nameservers when we have one.
2024-12-14 01:49:55 +00:00
14 changed files with 119 additions and 61 deletions

View file

@ -234,14 +234,20 @@ chanwait(Ep *ep, Ctlr *ctlr, Hostchan *hc, int mask)
int intr, ointr, chan; int intr, ointr, chan;
ulong start, now; ulong start, now;
if(waserror()){
chanhalt(ep, hc);
nexterror();
}
chan = hc - ctlr->regs->hchan; chan = hc - ctlr->regs->hchan;
for(;;){ for(;;){
restart: restart:
tsleep(&ctlr->chanintr[chan], chandone, hc, 1000); tsleep(&ctlr->chanintr[chan], chandone, hc, 1000);
if((intr = hc->hcint) == 0) if((intr = hc->hcint) == 0)
goto restart; error("channel timeout");
if(intr & Chhltd) if(intr & Chhltd){
poperror();
return intr; return intr;
}
ointr = intr; ointr = intr;
now = start = fastticks(0); now = start = fastticks(0);
do{ do{
@ -252,6 +258,7 @@ restart:
(now - start) > 60) (now - start) > 60)
dprint("ep%d.%d await %x after %ldµs %x -> %x\n", dprint("ep%d.%d await %x after %ldµs %x -> %x\n",
ep->dev->nb, ep->nb, mask, now - start, ointr, intr); ep->dev->nb, ep->nb, mask, now - start, ointr, intr);
poperror();
return intr; return intr;
} }
if((intr & mask) == 0){ if((intr & mask) == 0){
@ -686,7 +693,7 @@ init(Hci *hp)
dprint("usbdwc: FIFO depth %d sizes rx/nptx/ptx %8.8ux %8.8ux %8.8ux\n", dprint("usbdwc: FIFO depth %d sizes rx/nptx/ptx %8.8ux %8.8ux %8.8ux\n",
n, r->grxfsiz, r->gnptxfsiz, r->hptxfsiz); n, r->grxfsiz, r->gnptxfsiz, r->hptxfsiz);
r->hport0 = Prtpwr|Prtconndet|Prtenchng|Prtovrcurrchng; r->hport0 = Prtconndet|Prtenchng|Prtovrcurrchng;
r->gintsts = ~0; r->gintsts = ~0;
r->gintmsk = Hcintr; r->gintmsk = Hcintr;
r->gahbcfg |= Glblintrmsk; r->gahbcfg |= Glblintrmsk;
@ -982,7 +989,7 @@ portstatus(Hci *hp, int)
s = r->hport0; s = r->hport0;
b = s & (Prtconndet|Prtenchng|Prtovrcurrchng); b = s & (Prtconndet|Prtenchng|Prtovrcurrchng);
if(b != 0) if(b != 0)
r->hport0 = Prtpwr | b; r->hport0 = (s & Prtpwr) | b;
b = 0; b = 0;
if(s & Prtconnsts) if(s & Prtconnsts)
b |= HPpresent; b |= HPpresent;

View file

@ -1639,7 +1639,7 @@ static void
portlend(Ctlr *ctlr, int port, char *ss) portlend(Ctlr *ctlr, int port, char *ss)
{ {
Eopio *opio; Eopio *opio;
ulong s; int s;
opio = ctlr->opio; opio = ctlr->opio;
dprint("ehci %#p port %d: %s speed device: no longer owned\n", dprint("ehci %#p port %d: %s speed device: no longer owned\n",
@ -1648,6 +1648,27 @@ portlend(Ctlr *ctlr, int port, char *ss)
opio->portsc[port-1] = s | Psowner; opio->portsc[port-1] = s | Psowner;
} }
static void
portpower(Hci *hp, int port, int on)
{
Ctlr *ctlr;
Eopio *opio;
int s;
ctlr = hp->aux;
opio = ctlr->opio;
eqlock(&ctlr->portlck);
ilock(ctlr);
s = opio->portsc[port-1] & ~(Pschange|Psstatuschg);
if(on)
s |= Pspower;
else
s &= ~Pspower;
opio->portsc[port-1] = s;
iunlock(ctlr);
qunlock(&ctlr->portlck);
}
static void static void
portenable(Hci *hp, int port, int on) portenable(Hci *hp, int port, int on)
{ {
@ -3221,7 +3242,6 @@ init(Hci *hp)
{ {
Ctlr *ctlr; Ctlr *ctlr;
Eopio *opio; Eopio *opio;
int i;
hp->highspeed = 1; hp->highspeed = 1;
ctlr = hp->aux; ctlr = hp->aux;
@ -3243,10 +3263,6 @@ init(Hci *hp)
/* route all ports to us */ /* route all ports to us */
opio->config = Callmine; opio->config = Callmine;
coherence();
for (i = 0; i < hp->nports; i++)
opio->portsc[i] = Pspower;
iunlock(ctlr); iunlock(ctlr);
if(ehcidebug > 1) if(ehcidebug > 1)
dump(hp); dump(hp);
@ -3263,8 +3279,9 @@ ehcilinkage(Hci *hp)
hp->epread = epread; hp->epread = epread;
hp->epwrite = epwrite; hp->epwrite = epwrite;
hp->seprintep = seprintep; hp->seprintep = seprintep;
hp->portenable = portenable; hp->portpower = portpower;
hp->portreset = portreset; hp->portreset = portreset;
hp->portenable = portenable;
hp->portstatus = portstatus; hp->portstatus = portstatus;
hp->type = "ehci"; hp->type = "ehci";
} }

View file

@ -43,6 +43,7 @@ enum {
CRS = 1<<9, /* Controller Restore State - RW */ CRS = 1<<9, /* Controller Restore State - RW */
EWE = 1<<10, /* Enable Wrap Event - RW */ EWE = 1<<10, /* Enable Wrap Event - RW */
EU3S = 1<<11, /* Enable U3 MFINDEX Stop - RW */ EU3S = 1<<11, /* Enable U3 MFINDEX Stop - RW */
USBCMD_PRES =0xfffff030,/* Reserved - RsvdP */
USBSTS = 0x04/4, /* USB Status Register */ USBSTS = 0x04/4, /* USB Status Register */
HCH = 1<<0, /* HCHalted - RO */ HCH = 1<<0, /* HCHalted - RO */
@ -54,22 +55,24 @@ enum {
SRE = 1<<10, /* Save/Restore Error - RW1C */ SRE = 1<<10, /* Save/Restore Error - RW1C */
CNR = 1<<11, /* Controller Not Ready - RO */ CNR = 1<<11, /* Controller Not Ready - RO */
HCE = 1<<12, /* Host Controller Error - RO */ HCE = 1<<12, /* Host Controller Error - RO */
USBSTS_PRES =0xffffe002,/* Reserved - RsvdP */
PAGESIZE = 0x08/4, /* Page Size - RO */ PAGESIZE = 0x08/4, /* Page Size - RO */
DNCTRL = 0x14/4, /* Device Notification Control Register - RW */ DNCTRL = 0x14/4, /* Device Notification Control Register - RW */
DNCTL_PRES =0xffff0000, /* Reserved - RsvdP */
CRCR = 0x18/4, /* Command Ring Control Register - RW */ CRCR = 0x18/4, /* Command Ring Control Register - RW */
RCS = 1<<0, /* Ring Cycle State - RW */ RCS = 1<<0, /* Ring Cycle State - RW */
CS = 1<<1, /* Command Stop - RW1S */ CS = 1<<1, /* Command Stop - RW1S */
CA = 1<<2, /* Command Abort - RW1S */ CA = 1<<2, /* Command Abort - RW1S */
CRR = 1<<3, /* Command Ring Running - RO */ CRR = 1<<3, /* Command Ring Running - RO */
CRCR_PRES = 3<<4, /* Reserved - RsvdP */
DCBAAP = 0x30/4, // 8 DCBAAP = 0x30/4, /* 64-bit */
CONFIG = 0x38/4, /* Configure Register (MaxSlotEn[7:0]) */ CONFIG = 0x38/4, /* Configure Register (MaxSlotEn[7:0]) */
U3E = 1<<8, CONFIG_PRES =0xffffff00,/* Reserved - RsvdP */
CIE = 1<<9,
/* Port Register Set */ /* Port Register Set */
PORTSC = 0x00/4, /* Port status and Control Register */ PORTSC = 0x00/4, /* Port status and Control Register */
@ -105,10 +108,16 @@ enum {
/* Interrupter Registers */ /* Interrupter Registers */
IMAN = 0x00/4, /* Interrupter Management */ IMAN = 0x00/4, /* Interrupter Management */
IP = 1<<0, /* Interrupt pending - RW1C */
IE = 1<<1, /* interrupt enable - RW */
IMAN_PRES = 0xfffffffc, /* Reserved - RsvdP */
IMOD = 0x04/4, /* Interrupter Moderation */ IMOD = 0x04/4, /* Interrupter Moderation */
ERSTSZ = 0x08/4, /* Event Ring Segment Table Size */ ERSTSZ = 0x08/4, /* Event Ring Segment Table Size */
ERSTSZ_PRES =0xffff0000,/* Reserved - RsvdP */
ERSTBA = 0x10/4, /* Event Ring Segment Table Base Address */ ERSTBA = 0x10/4, /* Event Ring Segment Table Base Address */
ERSTBA_PRES =0x3f, /* Reserved - RsvdP */
ERDP = 0x18/4, /* Event Ring Dequeue Pointer */ ERDP = 0x18/4, /* Event Ring Dequeue Pointer */
EHB = 1<<3, /* Event Handler Busy - RW1C */
/* TRB flags */ /* TRB flags */
TR_ENT = 1<<1, TR_ENT = 1<<1,
@ -420,7 +429,7 @@ xhcishutdown(Hci *hp)
Ctlr *ctlr = hp->aux; Ctlr *ctlr = hp->aux;
int i; int i;
ctlr->opr[USBCMD] = 0; ctlr->opr[USBCMD] &= USBCMD_PRES;
for(i=0; (ctlr->opr[USBSTS] & HCH) == 0 && i < 10; i++) for(i=0; (ctlr->opr[USBSTS] & HCH) == 0 && i < 10; i++)
delay(10); delay(10);
intrdisable(hp->irq, hp->interrupt, hp, hp->tbdf, hp->type); intrdisable(hp->irq, hp->interrupt, hp, hp->tbdf, hp->type);
@ -470,7 +479,7 @@ xhciinit(Hci *hp)
for(i=0; (ctlr->opr[USBSTS] & CNR) != 0 && i<100; i++) for(i=0; (ctlr->opr[USBSTS] & CNR) != 0 && i<100; i++)
tsleep(&up->sleep, return0, nil, 10); tsleep(&up->sleep, return0, nil, 10);
ctlr->opr[USBCMD] = HCRST; ctlr->opr[USBCMD] = HCRST | (ctlr->opr[USBCMD] & USBCMD_PRES);
/* some intel controllers require 1ms delay after reset */ /* some intel controllers require 1ms delay after reset */
tsleep(&up->sleep, return0, nil, 1); tsleep(&up->sleep, return0, nil, 1);
@ -544,7 +553,8 @@ xhciinit(Hci *hp)
for(i=1; i<=ctlr->nslots; i++) for(i=1; i<=ctlr->nslots; i++)
ctlr->dcba[i] = 0; ctlr->dcba[i] = 0;
ctlr->opr[CONFIG] = (ctlr->opr[CONFIG] & ~(CIE|U3E|0xFF)) | ctlr->nslots; /* MaxSlotsEn */ /* MaxSlotsEn */
ctlr->opr[CONFIG] = ctlr->nslots | (ctlr->opr[CONFIG] & CONFIG_PRES);
dmaflush(1, ctlr->dcba, (1+ctlr->nslots)*sizeof(ctlr->dcba[0])); dmaflush(1, ctlr->dcba, (1+ctlr->nslots)*sizeof(ctlr->dcba[0]));
setrptr(&ctlr->opr[DCBAAP], (*ctlr->dmaaddr)(ctlr->dcba)); setrptr(&ctlr->opr[DCBAAP], (*ctlr->dmaaddr)(ctlr->dcba));
@ -552,16 +562,18 @@ xhciinit(Hci *hp)
initring(ctlr, ctlr->cr, 8); /* 256 entries */ initring(ctlr, ctlr->cr, 8); /* 256 entries */
ctlr->cr->id = 0; ctlr->cr->id = 0;
ctlr->cr->doorbell = &ctlr->dba[0]; ctlr->cr->doorbell = &ctlr->dba[0];
setrptr(&ctlr->opr[CRCR], resetring(ctlr->cr)); setrptr(&ctlr->opr[CRCR], resetring(ctlr->cr) |
(ctlr->opr[CRCR] & CRCR_PRES));
for(i=0; i<ctlr->nintrs; i++){ for(i=0; i<ctlr->nintrs; i++){
u32int *irs = &ctlr->rts[IR0 + i*8]; u32int *irs = &ctlr->rts[IR0 + i*8];
if(i >= nelem(ctlr->er)){ if(i >= nelem(ctlr->er)){
irs[ERSTSZ] = 0; /* disable ring */ /* disable ring */
irs[IMAN] = 1; irs[ERSTSZ] = 0 | (irs[ERSTSZ] & ERSTSZ_PRES);
irs[IMAN] = irs[IMAN] & (IP | IMAN_PRES);
irs[IMOD] = 0; irs[IMOD] = 0;
setrptr(&irs[ERSTBA], 0); setrptr(&irs[ERSTBA], irs[ERSTBA] & ERSTBA_PRES);
setrptr(&irs[ERDP], 0); setrptr(&irs[ERDP], 0);
continue; continue;
} }
@ -576,19 +588,22 @@ xhciinit(Hci *hp)
ctlr->erst[i][3] = 0; ctlr->erst[i][3] = 0;
dmaflush(1, ctlr->erst[i], 4*4); dmaflush(1, ctlr->erst[i], 4*4);
irs[ERSTSZ] = 1; /* just one segment */ /* just one segment */
irs[IMAN] = 3; irs[ERSTSZ] = 1 | (irs[ERSTSZ] & ERSTSZ_PRES);
irs[IMAN] = IE | (irs[IMAN] & (IP | IMAN_PRES));
irs[IMOD] = 0; irs[IMOD] = 0;
setrptr(&irs[ERSTBA], (*ctlr->dmaaddr)(ctlr->erst[i])); setrptr(&irs[ERSTBA], (*ctlr->dmaaddr)(ctlr->erst[i]) |
setrptr(&irs[ERDP], (*ctlr->dmaaddr)(ctlr->er[i].base) | (1<<3)); (irs[ERSTBA] & ERSTBA_PRES));
setrptr(&irs[ERDP], (*ctlr->dmaaddr)(ctlr->er[i].base) | EHB);
} }
poperror(); poperror();
ctlr->µframe = 0; ctlr->µframe = 0;
ctlr->opr[USBSTS] = ctlr->opr[USBSTS] & (HSE|EINT|PCD|SRE); ctlr->opr[USBSTS] = ctlr->opr[USBSTS] & (HSE|EINT|PCD|SRE | USBSTS_PRES);
coherence(); coherence();
ctlr->opr[USBCMD] = RUNSTOP|INTE|HSEE|EWE; ctlr->opr[USBCMD] = RUNSTOP|INTE|HSEE|EWE | (ctlr->opr[USBCMD] & USBCMD_PRES);
for(i=0; (ctlr->opr[USBSTS] & (CNR|HCH)) != 0 && i<100; i++) for(i=0; (ctlr->opr[USBSTS] & (CNR|HCH)) != 0 && i<100; i++)
tsleep(&up->sleep, return0, nil, 10); tsleep(&up->sleep, return0, nil, 10);
@ -613,6 +628,10 @@ recover(void *arg)
; ;
while(!needrecover(ctlr)) while(!needrecover(ctlr))
tsleep(&ctlr->recover, needrecover, ctlr, 1000); tsleep(&ctlr->recover, needrecover, ctlr, 1000);
print("usbxhci %llux: need recover: USBSTS=%ux, er stopped=%d\n",
ctlr->base, ctlr->opr[USBSTS], ctlr->er->stopped);
(*hp->shutdown)(hp); (*hp->shutdown)(hp);
/* /*
@ -654,12 +673,11 @@ recover(void *arg)
qlock(&ctlr->cmdlock); qlock(&ctlr->cmdlock);
release(ctlr); release(ctlr);
if(waserror()) { if(waserror()) {
print("xhci recovery failed: %s\n", up->errstr); print("usbxhci %llux: recovery failed: %s\n", ctlr->base, up->errstr);
} else { } else {
(*hp->init)(hp); (*hp->init)(hp);
poperror(); poperror();
} }
qunlock(&ctlr->cmdlock); qunlock(&ctlr->cmdlock);
qunlock(&ctlr->slotlock); qunlock(&ctlr->slotlock);
@ -881,7 +899,7 @@ interrupt(Ureg*, void *arg)
irs = &ctlr->rts[IR0]; irs = &ctlr->rts[IR0];
x = irs[IMAN]; x = irs[IMAN];
if(x & 1) irs[IMAN] = x & 3; if(x & IP) irs[IMAN] = x;
for(x = ring->rp;; x=++ring->rp){ for(x = ring->rp;; x=++ring->rp){
td = ring->base + 4*(x & ring->mask); td = ring->base + 4*(x & ring->mask);
@ -908,8 +926,8 @@ interrupt(Ureg*, void *arg)
(ctlr->µframe+(1<<14) & ~((1<<14)-1)); (ctlr->µframe+(1<<14) & ~((1<<14)-1));
break; break;
case ER_HCE: case ER_HCE:
iprint("xhci: host controller error: %ux %ux %ux %ux\n", iprint("usbxhci %llux: host controller error: %ux %ux %ux %ux\n",
td[0], td[1], td[2], td[3]); ctlr->base, td[0], td[1], td[2], td[3]);
ctlr->er->stopped = 1; ctlr->er->stopped = 1;
wakeup(&ctlr->recover); wakeup(&ctlr->recover);
return; return;
@ -919,12 +937,12 @@ interrupt(Ureg*, void *arg)
case ER_DOORBELL: case ER_DOORBELL:
case ER_DEVNOTE: case ER_DEVNOTE:
default: default:
iprint("xhci: event %ud: %ux %ux %ux %ux\n", iprint("usbxhci %llux: event %ud: %ux %ux %ux %ux\n",
x, td[0], td[1], td[2], td[3]); ctlr->base, x, td[0], td[1], td[2], td[3]);
} }
} }
setrptr(&irs[ERDP], (*ctlr->dmaaddr)(td) | (1<<3)); setrptr(&irs[ERDP], (*ctlr->dmaaddr)(td) | EHB);
} }
static void static void
@ -1855,7 +1873,7 @@ xhcialloc(u32int *mmio, u64int base, u64int size)
ctlr = malloc(sizeof(Ctlr)); ctlr = malloc(sizeof(Ctlr));
if(ctlr == nil){ if(ctlr == nil){
print("usbxhci: no memory for controller\n"); print("usbxhci %llux: no memory for controller\n", base);
return nil; return nil;
} }
ctlr->mmio = mmio; ctlr->mmio = mmio;

View file

@ -114,8 +114,9 @@ for(m in $cleanpaths){
for(ours in $dirtypaths){ for(ours in $dirtypaths){
common=$gitfs/object/$orig/tree/$ours common=$gitfs/object/$orig/tree/$ours
theirs=$gitfs/object/$base/tree/$ours theirs=$gitfs/object/$base/tree/$ours
merge1 $ours $ours $common $theirs || st=$status merge1 $ours $ours $common $theirs
if(! ~ $#st 1) st=$status
if(! ~ $st '')
>[1=2] echo merge failed $ours: $st >[1=2] echo merge failed $ours: $st
} }
if(~ $new */*) if(~ $new */*)

View file

@ -164,7 +164,7 @@ out:
* don't call it non-existent if it's not ours * don't call it non-existent if it's not ours
* (unless we're a resolver). * (unless we're a resolver).
*/ */
if(err == Rname && (!inmyarea(dp->name) || cfg.resolver)) if(err == Rname && (!inmyarea(dp->name, nil) || cfg.resolver))
err = Rserver; err = Rserver;
dp->respcode = err; dp->respcode = err;
} }
@ -848,7 +848,7 @@ baddelegation(RR *rp, RR *nsrp, uchar *addr)
for(nt = mydoms; nt != nil; nt = nt->entry) for(nt = mydoms; nt != nil; nt = nt->entry)
if(rp->host && cistrcmp(rp->host->name, nt->val) == 0) if(rp->host && cistrcmp(rp->host->name, nt->val) == 0)
break; break;
if(nt == nil || inmyarea(rp->owner->name)) if(nt == nil || inmyarea(rp->owner->name, nil))
return 0; return 0;
dnslog("bad delegation %R from %I/%s; " dnslog("bad delegation %R from %I/%s; "
"no further logging of them", "no further logging of them",

View file

@ -526,7 +526,7 @@ dnauthdb(void)
for(i = 0; i < HTLEN; i++) for(i = 0; i < HTLEN; i++)
for(dp = ht[i]; dp; dp = dp->next){ for(dp = ht[i]; dp; dp = dp->next){
area = inmyarea(dp->name); area = inmyarea(dp->name, nil);
l = &dp->rr; l = &dp->rr;
for(rp = *l; rp; rp = *l){ for(rp = *l; rp; rp = *l){
if(rp->db){ if(rp->db){
@ -539,7 +539,7 @@ dnauthdb(void)
if(rp->ttl < minttl) if(rp->ttl < minttl)
rp->ttl = minttl; rp->ttl = minttl;
rp->auth = 1; rp->auth = 1;
} else if(rp->type == Tns && inmyarea(rp->host->name)) } else if(rp->type == Tns && inmyarea(rp->host->name, nil))
rp->auth = 1; rp->auth = 1;
} else if(area){ } else if(area){
/* no outside spoofing */ /* no outside spoofing */
@ -707,7 +707,7 @@ rrattach(RR *rp, int auth)
next = rp->next; next = rp->next;
rp->next = nil; rp->next = nil;
if(rp->type == Tall || rp->type == Topt || !rrsupported(rp->type) if(rp->type == Tall || rp->type == Topt || !rrsupported(rp->type)
|| cfg.cachedb && !rp->db && inmyarea(rp->owner->name)) || cfg.cachedb && !rp->db && inmyarea(rp->owner->name, nil))
rrfree(rp); rrfree(rp);
else else
rrattach1(rp, auth); rrattach1(rp, auth);

View file

@ -26,17 +26,22 @@ nameinarea(char *name, Area *s)
* true if a name is in our area * true if a name is in our area
*/ */
Area* Area*
inmyarea(char *name) inmyarea(char *name, Area **delegation)
{ {
Area *s, *d; Area *s, *d;
s = nameinarea(name, owned); s = nameinarea(name, owned);
if(s == nil) if(s == nil){
if(delegation)
*delegation = nil;
return nil; return nil;
}
d = nameinarea(name, delegated); d = nameinarea(name, delegated);
if(d && d->len > s->len) if(delegation)
*delegation = d;
if(d != nil && d->len > s->len)
return nil; return nil;
return s; /* name is in owned area `s' and not in a delegated subarea */ return s; /* name is in owned area `s' and not in a delegated subarea `d' */
} }
/* /*

View file

@ -26,7 +26,7 @@ dnnotify(DNSmsg *reqp, DNSmsg *repp, Request *req)
return; return;
/* is it something we care about? */ /* is it something we care about? */
a = inmyarea(repp->qd->owner->name); a = inmyarea(repp->qd->owner->name, nil);
if(a == nil) if(a == nil)
return; return;

View file

@ -403,7 +403,7 @@ dnresolve1(char *name, int class, int type, Request *req, int depth, int recurse
* if the domain name is within an area of ours, * if the domain name is within an area of ours,
* we should have found its data in memory by now. * we should have found its data in memory by now.
*/ */
area = inmyarea(dp->name); area = inmyarea(dp->name, nil);
if (area || strncmp(dp->name, "local#", 6) == 0) if (area || strncmp(dp->name, "local#", 6) == 0)
return nil; return nil;

View file

@ -489,7 +489,7 @@ extern Area *delegated;
extern Area *owned; extern Area *owned;
void addarea(RR *rp, Ndbtuple *t); void addarea(RR *rp, Ndbtuple *t);
void freeareas(Area**); void freeareas(Area**);
Area* inmyarea(char*); Area* inmyarea(char*, Area**);
/* dblookup.c */ /* dblookup.c */
int baddelegation(RR*, RR*, uchar*); int baddelegation(RR*, RR*, uchar*);

View file

@ -14,7 +14,7 @@ dnserver(DNSmsg *reqp, DNSmsg *repp, Request *req, uchar *srcip, int rcode)
{ {
char tname[32], *cp; char tname[32], *cp;
DN *nsdp; DN *nsdp;
Area *myarea; Area *myarea, *delegation;
RR *rp, *neg; RR *rp, *neg;
repp->id = reqp->id; repp->id = reqp->id;
@ -49,7 +49,7 @@ dnserver(DNSmsg *reqp, DNSmsg *repp, Request *req, uchar *srcip, int rcode)
return; return;
} }
myarea = inmyarea(repp->qd->owner->name); myarea = inmyarea(repp->qd->owner->name, &delegation);
if(myarea){ if(myarea){
if(repp->qd->type == Tixfr || repp->qd->type == Taxfr){ if(repp->qd->type == Tixfr || repp->qd->type == Taxfr){
if(debug) if(debug)
@ -64,9 +64,15 @@ dnserver(DNSmsg *reqp, DNSmsg *repp, Request *req, uchar *srcip, int rcode)
} else { } else {
if(cfg.nonrecursive if(cfg.nonrecursive
|| cfg.localrecursive && !localip(srcip)){ || cfg.localrecursive && !localip(srcip)){
/* we don't recurse and we're not authoritative */ if(delegation == nil){
/*
* we don't recurse and we're not authoritative
* nor lies the domain in a delegated sub area.
*/
setercode(repp, Rrefused); setercode(repp, Rrefused);
return; return;
}
neg = nil;
} else { } else {
repp->flags |= Fcanrec; repp->flags |= Fcanrec;
if(reqp->flags & Frecurse){ if(reqp->flags & Frecurse){

View file

@ -56,8 +56,9 @@ enum
Pconfigured, Pconfigured,
/* Delays, timeouts (ms) */ /* Delays, timeouts (ms) */
Resetdelay = 20, /* how much to wait after a reset */ Rootresetdelay = 100, /* how much to wait after a root port reset (50ms by standard) */
Resumedelay = 20, /* how much to wait after a resume */ Portresetdelay = 50, /* how much to wait after a hub port reset (20ms by standard) */
Resumedelay = 50, /* how much to wait after a resume (20ms by standard) */
Powerdelay = 100, /* after powering up ports */ Powerdelay = 100, /* after powering up ports */
Pollms = 250, /* port poll interval */ Pollms = 250, /* port poll interval */

View file

@ -452,7 +452,7 @@ portattach(Hub *h, int p)
dprint(2, "%s: %s: port %d: set reset: %r\n", argv0, d->dir, p); dprint(2, "%s: %s: port %d: set reset: %r\n", argv0, d->dir, p);
return -1; return -1;
} }
sleep(Resetdelay); sleep(d->depth<0? Rootresetdelay: Portresetdelay);
if((sts = portstatus(h, p)) == -1) if((sts = portstatus(h, p)) == -1)
return -1; return -1;
sp = "full"; sp = "full";

View file

@ -159,8 +159,9 @@ nsub(Mesg *m)
n = 0; n = 0;
for(i = 0; i < m->nchild; i++){ for(i = 0; i < m->nchild; i++){
c = m->child[i]; c = m->child[i];
n += nsub(c);
if(!(c->state & (Sdummy|Shide))) if(!(c->state & (Sdummy|Shide)))
n += nsub(c)+1; n++;
} }
return n; return n;
} }
@ -183,7 +184,9 @@ mesglineno(Mesg *msg, int *depth)
for(i = 0; i < p->nchild; i++){ for(i = 0; i < p->nchild; i++){
if(p->child[i] == m) if(p->child[i] == m)
break; break;
o += nsub(p->child[i]) + 1; o += nsub(p->child[i]);
if(!(p->state & (Sdummy|Shide)))
o++;
} }
if(!(p->state & (Sdummy|Shide))){ if(!(p->state & (Sdummy|Shide))){
o++; o++;