#include "sys/param.h" #include "sys/systm.h" #include "sys/buf.h" #include "sys/conf.h" #include "sys/map.h" #include "sys/utsname.h" #include "sys/mba.h" #include "sys/elog.h" #include "sys/erec.h" #include "sys/err.h" #include "sys/iobuf.h" #include "sys/var.h" errinit() { if(err.e_nslot) mfree(err.e_map,err.e_nslot,1); err.e_org = err.e_ptrs; err.e_nxt = err.e_ptrs; } struct errhdr * geteslot(size) { register ns, *p; register struct errhdr *ep; int n, sps; ns = (size+sizeof(struct errhdr)+sizeof(struct errslot)-1) /sizeof(struct errslot); sps = spl7(); n = malloc(err.e_map,ns); splx(sps); if(n == 0) return(NULL); ep = (struct errhdr *)(&err.e_slot[--n]); ns *= sizeof(struct errslot)/sizeof(int); p = (int *)ep; do { *p++ = 0; } while(--ns); ep->e_len = size + sizeof(struct errhdr); return(++ep); } freeslot(ep) register struct errhdr *ep; { register ns, sps; ns = (ep->e_len+sizeof(struct errslot)-1)/sizeof(struct errslot); sps = spl7(); mfree(err.e_map,ns,(((struct errslot *)ep)-err.e_slot)+1); splx(sps); } struct errhdr * geterec() { register sps; register struct errhdr *ep; sps = spl7(); while(*err.e_org == NULL) sleep(&err.e_org,PZERO+1); ep = *err.e_org; *err.e_org++ = NULL; if(err.e_org >= &err.e_ptrs[err.e_nslot]) err.e_org = err.e_ptrs; splx(sps); return(ep); } puterec(ep,type) register struct errhdr *ep; { register sps; (--ep)->e_type = type; ep->e_time = time; sps = spl7(); *err.e_nxt++ = ep; if(err.e_nxt >= &err.e_ptrs[err.e_nslot]) err.e_nxt = err.e_ptrs; splx(sps); wakeup(&err.e_org); } logstart() { register sps; register struct estart *ep; register struct bdevsw *bdp; sps = spl7(); for(err.e_org = &err.e_ptrs[err.e_nslot-1]; err.e_org >= err.e_ptrs; err.e_org--) if(*err.e_org != NULL) { freeslot(*err.e_org); *err.e_org = NULL; } err.e_org = err.e_ptrs; err.e_nxt = err.e_ptrs; ep = (struct estart *)geteslot(sizeof(struct estart)); splx(sps); if(ep == NULL) return; ep->e_cpu = cputype; ep->e_name = utsname; for(bdp = &bdevsw[bdevcnt-1]; bdp >= bdevsw; bdp--) if(bdp->d_tab != NULL) ep->e_bconf |= 1<<major((bdp->d_tab->b_dev)); puterec(ep,E_GOTS); } logtchg(nt) time_t nt; { register struct etimchg *ep; if((ep = (struct etimchg *)geteslot(sizeof(struct etimchg))) != NULL) { ep->e_ntime = nt; puterec(ep,E_TCHG); } } logstray(addr) physadr addr; { register struct estray *ep; if((ep = (struct estray *)geteslot(sizeof(struct estray))) != NULL) { ep->e_saddr = addr; ep->e_sbacty = blkacty; puterec(ep,E_STRAY); } } fmtberr(dp,cyl) register struct iobuf *dp; { register struct eblock *ep; register struct buf *bp; register n; register short *p; struct br { struct eblock eb; short cregs[1]; }; struct iostat *iosp; physadr addr; if(dp->io_erec != NULL) { dp->io_erec->e_rtry++; return; } iosp = dp->io_stp; if(dp->io_addr == NULL || dp->io_mba == NULL || (ep = (struct eblock *)geteslot(sizeof(struct eblock)+ (dp->io_nreg*sizeof(short)))) == NULL) { iosp->io_unlog++; return; } n = major(dp->b_dev); bp = dp->b_actf; ep->e_dev = makedev(n,(bp==NULL)?minor(dp->b_dev):minor(bp->b_dev)); ep->e_regloc = addr = dp->io_addr; ep->e_bacty = blkacty; ep->e_stats.io_ops = iosp->io_ops; ep->e_stats.io_misc = iosp->io_misc; ep->e_stats.io_unlog = iosp->io_unlog; if(bp != NULL) { ep->e_bflags = (bp->b_flags&B_READ) ? E_READ : E_WRITE; if(bp->b_flags & B_PHYS) ep->e_bflags |= E_PHYS; if(bp->b_flags & B_MAP) ep->e_bflags |= E_MAP; ep->e_bnum = bp->b_blkno; ep->e_bytes = bp->b_bcount; ep->e_memadd = paddr(bp); } else ep->e_bflags = E_NOIO; ep->e_cyloff = cyl; ep->e_nreg = dp->io_nreg; ep->e_mba = ((struct mba_regs *)dp->io_mba)[0]; /* UGLY SYNTAX */ p = (short *)(&((struct br *)ep)->cregs[0]); n = dp->io_nreg; while(--n >= 0) { *p++ = addr->r[0]; addr++; } dp->io_erec = ep; } logberr(dp,err) register struct iobuf *dp; { register struct eblock *ep; if((ep = dp->io_erec) == NULL) return; if(err) ep->e_bflags |= E_ERROR; puterec(ep,E_BLK); dp->io_erec = NULL; }