static int lqfs_initialize(qfsvfs_t *qfsvfsp, daddr_t bno, int ord, size_t nb, struct fiolog *flp) { ml_odunit_t *ud, *ud2; buf_t *bp; timeval_lqfs_common_t tv; int error = 0; /* LINTED: warning: logical expression always true: op "||" */ ASSERT(sizeof (ml_odunit_t) < DEV_BSIZE); ASSERT(nb >= ldl_minlogsize); bp = QFS_GETBLK(qfsvfsp, qfsvfsp->mi.m_fs[ord].dev, bno, dbtob(LS_SECTORS)); bzero(bp->b_un.b_addr, bp->b_bcount); ud = (void *)bp->b_un.b_addr; ud->od_version = LQFS_VERSION_LATEST; ud->od_maxtransfer = MIN(VFS_IOTRANSZ(qfsvfsp), ldl_maxtransfer); if (ud->od_maxtransfer < ldl_mintransfer) { ud->od_maxtransfer = ldl_mintransfer; } ud->od_devbsize = DEV_BSIZE; ud->od_requestsize = flp->nbytes_actual; ud->od_statesize = dbtob(LS_SECTORS); ud->od_logsize = nb - ud->od_statesize; ud->od_statebno = INT32_C(0); uniqtime(&tv); if (tv.tv_usec == last_loghead_ident) { tv.tv_usec++; } last_loghead_ident = tv.tv_usec; ud->od_head_ident = tv.tv_usec; ud->od_tail_ident = ud->od_head_ident; ud->od_chksum = ud->od_head_ident + ud->od_tail_ident; ud->od_bol_lof = dbtob(ud->od_statebno) + ud->od_statesize; ud->od_eol_lof = ud->od_bol_lof + ud->od_logsize; ud->od_head_lof = ud->od_bol_lof; ud->od_tail_lof = ud->od_bol_lof; ASSERT(lqfs_initialize_debug(ud)); ml_odunit_validate(ud); ud2 = (void *)(bp->b_un.b_addr + DEV_BSIZE); bcopy(ud, ud2, sizeof (*ud)); if ((error = SAM_BWRITE2(qfsvfsp, bp)) != 0) { brelse(bp); return (error); } brelse(bp); return (0); }
static void md_put_event(md_tags_t tag, set_t sp, md_dev64_t dev, int event, u_longlong_t user) { md_event_queue_t *queue; md_event_t *entry; if (!md_event_queue) return; mutex_enter(&md_eventq_mx); for (queue = md_event_queue; queue; queue = queue->mdn_nextq) { if (queue->mdn_size >= md_max_notify_queue) { ASSERT(queue->mdn_front != NULL); ASSERT(queue->mdn_front->mdn_next != NULL); entry = queue->mdn_front; queue->mdn_front = entry->mdn_next; queue->mdn_size--; queue->mdn_flags |= MD_EVENT_QUEUE_FULL; } else entry = (md_event_t *)kmem_alloc(sizeof (md_event_t), KM_NOSLEEP); if (entry == NULL) { queue->mdn_flags |= MD_EVENT_QUEUE_INVALID; continue; } entry->mdn_tag = tag; entry->mdn_set = sp; entry->mdn_dev = dev; entry->mdn_event = event; entry->mdn_user = user; entry->mdn_next = NULL; uniqtime(&entry->mdn_time); if (queue->mdn_front == NULL) { queue->mdn_front = entry; queue->mdn_tail = entry; } else { queue->mdn_tail->mdn_next = entry; queue->mdn_tail = entry; } if (queue->mdn_waiting) cv_signal(&queue->mdn_cv); queue->mdn_size++; } md_reap++; mutex_exit(&md_eventq_mx); if (md_reap > md_reap_count) md_reaper(); }
/* * convert incoming data */ static int parserput( queue_t *q, mblk_t *mp ) { unsigned char type; switch (type = mp->b_datap->db_type) { default: /* * anything we don't know will be put on queue * the service routine will move it to the next one */ parseprintf(DD_RPUT,("parse: parserput - forward type 0x%x\n", type)); if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL)) { putnext(q, mp); } else putq(q, mp); break; case M_BREAK: case M_DATA: { register parsestream_t * parse = (parsestream_t *)(void *)q->q_ptr; register mblk_t *nmp; register unsigned long ch; timestamp_t ctime; /* * get time on packet delivery */ uniqtime(&ctime.tv); if (!(parse->parse_status & PARSE_ENABLE)) { parseprintf(DD_RPUT,("parse: parserput - parser disabled - forward type 0x%x\n", type)); if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL)) { putnext(q, mp); } else putq(q, mp); } else { parseprintf(DD_RPUT,("parse: parserput - M_%s\n", (type == M_DATA) ? "DATA" : "BREAK")); if (type == M_DATA) { /* * parse packet looking for start an end characters */ while (mp != (mblk_t *)NULL) { ch = rdchar(&mp); if (ch != ~0 && parse_ioread(&parse->parse_io, (unsigned int)ch, &ctime)) { /* * up up and away (hopefully ...) * don't press it if resources are tight or nobody wants it */ nmp = (mblk_t *)NULL; if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED))) { bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t)); nmp->b_wptr += sizeof(parsetime_t); putnext(parse->parse_queue, nmp); } else if (nmp) freemsg(nmp); parse_iodone(&parse->parse_io); } } } else { if (parse_ioread(&parse->parse_io, (unsigned int)0, &ctime)) { /* * up up and away (hopefully ...) * don't press it if resources are tight or nobody wants it */ nmp = (mblk_t *)NULL; if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED))) { bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t)); nmp->b_wptr += sizeof(parsetime_t); putnext(parse->parse_queue, nmp); } else if (nmp) freemsg(nmp); parse_iodone(&parse->parse_io); } freemsg(mp); } break; } } /* * CD PPS support for non direct ISR hack */ case M_HANGUP: case M_UNHANGUP: { register parsestream_t * parse = (parsestream_t *)(void *)q->q_ptr; timestamp_t ctime; register mblk_t *nmp; register int status = cd_invert ^ (type == M_UNHANGUP); uniqtime(&ctime.tv); parseprintf(DD_RPUT,("parse: parserput - M_%sHANGUP\n", (type == M_HANGUP) ? "" : "UN")); if ((parse->parse_status & PARSE_ENABLE) && parse_iopps(&parse->parse_io, (int)(status ? SYNC_ONE : SYNC_ZERO), &ctime)) { nmp = (mblk_t *)NULL; if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED))) { bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t)); nmp->b_wptr += sizeof(parsetime_t); putnext(parse->parse_queue, nmp); } else if (nmp) freemsg(nmp); parse_iodone(&parse->parse_io); freemsg(mp); } else if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL)) { putnext(q, mp); } else putq(q, mp); if (status) { parse->parse_ppsclockev.tv = ctime.tv; ++(parse->parse_ppsclockev.serial); } } } return 0; }
/* * take external status interrupt (only CD interests us) */ static int zs_xsisr( struct zscom *zs ) { register struct zsaline *za = (struct zsaline *)(void *)zs->zs_priv; register struct zscc_device *zsaddr = zs->zs_addr; register queue_t *q; register unsigned char zsstatus; register int loopcheck; register char *dname; #ifdef PPS_SYNC register unsigned int s; register long usec; #endif /* * pick up current state */ zsstatus = zsaddr->zscc_control; if ((za->za_rr0 ^ zsstatus) & (cdmask)) { timestamp_t cdevent; register int status; za->za_rr0 = (za->za_rr0 & ~(cdmask)) | (zsstatus & (cdmask)); #ifdef PPS_SYNC s = splclock(); #ifdef PPS_NEW usec = timestamp.tv_usec; #else usec = pps_time.tv_usec; #endif #endif /* * time stamp */ uniqtime(&cdevent.tv); #ifdef PPS_SYNC (void)splx(s); #endif /* * logical state */ status = cd_invert ? (zsstatus & cdmask) == 0 : (zsstatus & cdmask) != 0; #ifdef PPS_SYNC if (status) { usec = cdevent.tv.tv_usec - usec; if (usec < 0) usec += 1000000; hardpps(&cdevent.tv, usec); } #endif q = za->za_ttycommon.t_readq; /* * ok - now the hard part - find ourself */ loopcheck = MAXDEPTH; while (q) { if (q->q_qinfo && q->q_qinfo->qi_minfo) { dname = q->q_qinfo->qi_minfo->mi_idname; if (!Strcmp(dname, parseinfo.st_rdinit->qi_minfo->mi_idname)) { /* * back home - phew (hopping along stream queues might * prove dangerous to your health) */ if ((((parsestream_t *)(void *)q->q_ptr)->parse_status & PARSE_ENABLE) && parse_iopps(&((parsestream_t *)(void *)q->q_ptr)->parse_io, (int)(status ? SYNC_ONE : SYNC_ZERO), &cdevent)) { /* * XXX - currently we do not pass up the message, as * we should. * for a correct behaviour wee need to block out * processing until parse_iodone has been posted via * a softcall-ed routine which does the message pass-up * right now PPS information relies on input being * received */ parse_iodone(&((parsestream_t *)(void *)q->q_ptr)->parse_io); } if (status) { ((parsestream_t *)(void *)q->q_ptr)->parse_ppsclockev.tv = cdevent.tv; ++(((parsestream_t *)(void *)q->q_ptr)->parse_ppsclockev.serial); } parseprintf(DD_ISR, ("zs_xsisr: CD event %s has been posted for \"%s\"\n", status ? "ONE" : "ZERO", dname)); break; } } q = q->q_next; if (!loopcheck--) { panic("zs_xsisr: STREAMS Queue corrupted - CD event"); } } /* * only pretend that CD has been handled */ ZSDELAY(2); if (!((za->za_rr0 ^ zsstatus) & ~(cdmask))) { /* * all done - kill status indication and return */ zsaddr->zscc_control = ZSWR0_RESET_STATUS; /* might kill other conditions here */ return 0; } } if (zsstatus & cdmask) /* fake CARRIER status */ za->za_flags |= ZAS_CARR_ON; else za->za_flags &= ~ZAS_CARR_ON; /* * we are now gathered here to process some unusual external status * interrupts. * any CD events have also been handled and shouldn't be processed * by the original routine (unless we have a VERY busy port pin) * some initializations are done here, which could have been done before for * both code paths but have been avoided for minimum path length to * the uniq_time routine */ dname = (char *) 0; q = za->za_ttycommon.t_readq; loopcheck = MAXDEPTH; /* * the real thing for everything else ... */ while (q) { if (q->q_qinfo && q->q_qinfo->qi_minfo) { dname = q->q_qinfo->qi_minfo->mi_idname; if (!Strcmp(dname, parseinfo.st_rdinit->qi_minfo->mi_idname)) { register int (*zsisr) (struct zscom *); /* * back home - phew (hopping along stream queues might * prove dangerous to your health) */ if ((zsisr = ((struct savedzsops *)((parsestream_t *)(void *)q->q_ptr)->parse_data)->oldzsops->zsop_xsint)) return zsisr(zs); else panic("zs_xsisr: unable to locate original ISR"); parseprintf(DD_ISR, ("zs_xsisr: non CD event was processed for \"%s\"\n", dname)); /* * now back to our program ... */ return 0; } } q = q->q_next; if (!loopcheck--) { panic("zs_xsisr: STREAMS Queue corrupted - non CD event"); } } /* * last resort - shouldn't even come here as it indicates * corrupted TTY structures */ printf("zs_zsisr: looking for \"%s\" - found \"%s\" - taking EMERGENCY path\n", parseinfo.st_rdinit->qi_minfo->mi_idname, dname ? dname : "-NIL-"); if (emergencyzs && emergencyzs->zsop_xsint) emergencyzs->zsop_xsint(zs); else panic("zs_xsisr: no emergency ISR handler"); return 0; }