X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/de355530ae67247cbd0da700edb3a2a1dae884c2..0c530ab8987f0ae6a1a3d9284f40182b88852816:/bsd/netat/atp_write.c diff --git a/bsd/netat/atp_write.c b/bsd/netat/atp_write.c index 4fea05d13..3fcbecea4 100644 --- a/bsd/netat/atp_write.c +++ b/bsd/netat/atp_write.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -64,24 +65,22 @@ static int loop_cnt; /* for debugging loops */ } \ } -static void atp_pack_bdsp(struct atp_trans *, struct atpBDS *); +static int atp_pack_bdsp(struct atp_trans *, struct atpBDS *); static int atp_unpack_bdsp(struct atp_state *, gbuf_t *, struct atp_rcb *, int, int); -void atp_retry_req(), atp_trp_clock(), asp_clock(), asp_clock_funnel(), atp_trp_clock_funnel();; +void atp_trp_clock(), asp_clock(), asp_clock_locked(), atp_trp_clock_locked();; extern struct atp_rcb_qhead atp_need_rel; extern int atp_inited; extern struct atp_state *atp_used_list; extern asp_scb_t *scb_free_list; -extern atlock_t atpgen_lock; -extern atlock_t atpall_lock; -extern atlock_t atptmo_lock; extern gbuf_t *scb_resource_m; extern gbuf_t *atp_resource_m; extern gref_t *atp_inputQ[]; extern int atp_pidM[]; extern at_ifaddr_t *ifID_home; +extern lck_mtx_t * atalk_mutex; static struct atp_trans *trp_tmo_list; struct atp_trans *trp_tmo_rcb; @@ -104,8 +103,8 @@ void atp_link() void atp_unlink() { - untimeout(asp_clock_funnel, (void *)&atp_inited); - untimeout(atp_trp_clock_funnel, (void *)&atp_inited); + untimeout(asp_clock_locked, (void *)&atp_inited); + untimeout(atp_trp_clock_locked, (void *)&atp_inited); atp_untimout(atp_rcb_timer, trp_tmo_rcb); trp_tmo_list = 0; @@ -137,7 +136,7 @@ atp_wput(gref, m) register gbuf_t *m; { register ioc_t *iocbp; - int i, xcnt, s; + int i, xcnt; struct atp_state *atp; struct atp_trans *trp; struct atp_rcb *rcbp; @@ -235,18 +234,16 @@ atp_wput(gref, m) atp->atp_msgq = 0; } - ATDISABLE(s, atp->atp_lock); /* * search for the corresponding rcb */ for (rcbp = atp->atp_rcb.head; rcbp; rcbp = rcbp->rc_list.next) { - if (rcbp->rc_tid == UAS_VALUE(athp->tid) && + if (rcbp->rc_tid == UAS_VALUE_NTOH(athp->tid) && rcbp->rc_socket.node == ddp->dst_node && rcbp->rc_socket.net == NET_VALUE(ddp->dst_net) && rcbp->rc_socket.socket == ddp->dst_socket) break; } - ATENABLE(s, atp->atp_lock); /* * If it has already been sent then return an error @@ -267,13 +264,11 @@ atp_wput(gref, m) rcbp->rc_socket.socket = ddp->dst_socket; rcbp->rc_socket.node = ddp->dst_node; rcbp->rc_socket.net = NET_VALUE(ddp->dst_net); - rcbp->rc_tid = UAS_VALUE(athp->tid); + rcbp->rc_tid = UAS_VALUE_NTOH(athp->tid); rcbp->rc_bitmap = 0xff; rcbp->rc_xo = 0; - ATDISABLE(s, atp->atp_lock); rcbp->rc_state = RCB_SENDING; ATP_Q_APPEND(atp->atp_rcb, rcbp, rc_list); - ATENABLE(s, atp->atp_lock); } xcnt = get_bds_entries(m2); if ((i = atp_unpack_bdsp(atp, m2, rcbp, xcnt, FALSE))) { @@ -301,7 +296,6 @@ atp_wput(gref, m) /* * search for a waiting request */ - ATDISABLE(s, atp->atp_lock); if ((rcbp = atp->atp_attached.head)) { /* * Got one, move it to the active response Q @@ -318,13 +312,11 @@ atp_wput(gref, m) */ atp_rcb_free(rcbp); } - ATENABLE(s, atp->atp_lock); atp_iocack(atp, m); } else { /* * None available - can out */ - ATENABLE(s, atp->atp_lock); atp_iocnak(atp, m, EAGAIN); } break; @@ -341,16 +333,13 @@ atp_wput(gref, m) i = *(int *)gbuf_rptr(gbuf_cont(m)); gbuf_freem(gbuf_cont(m)); gbuf_cont(m) = NULL; - ATDISABLE(s, atp->atp_lock); for (trp = atp->atp_trans_wait.head; trp; trp = trp->tr_list.next) { if (trp->tr_tid == i) break; } - if (trp == NULL) { - ATENABLE(s, atp->atp_lock); + if (trp == NULL) atp_iocnak(atp, m, ENOENT); - } else { - ATENABLE(s, atp->atp_lock); + else { atp_free(trp); atp_iocack(atp, m); } @@ -428,7 +417,7 @@ register struct atp_trans *trp; gbuf_wset(m,TOTAL_ATP_HDR_SIZE); ddp = AT_DDP_HDR(m); ddp->type = DDP_ATP; - UAS_ASSIGN(ddp->checksum, 0); + UAS_ASSIGN_HTON(ddp->checksum, 0); ddp->dst_socket = trp->tr_socket.socket; ddp->dst_node = trp->tr_socket.node; NET_ASSIGN(ddp->dst_net, trp->tr_socket.net); @@ -441,7 +430,7 @@ register struct atp_trans *trp; athp = AT_ATP_HDR(m); ATP_CLEAR_CONTROL(athp); athp->cmd = ATP_CMD_TREL; - UAS_ASSIGN(athp->tid, trp->tr_tid); + UAS_ASSIGN_HTON(athp->tid, trp->tr_tid); } return (m); @@ -452,11 +441,11 @@ void atp_send_replies(atp, rcbp) register struct atp_rcb *rcbp; { register gbuf_t *m; register int i, len; - int s_gen, s, cnt; + int s_gen, cnt, err, offset, space; unsigned char *m0_rptr = NULL, *m0_wptr = NULL; register at_atp_t *athp; register struct atpBDS *bdsp; - register gbuf_t *m2, *m1, *m0, *m3; + register gbuf_t *m2, *m1, *m0, *mhdr; caddr_t lastPage; gbuf_t *mprev, *mlist = 0; at_socket src_socket = (at_socket)atp->atp_socket_no; @@ -464,12 +453,10 @@ void atp_send_replies(atp, rcbp) struct ddp_atp { char ddp_atp_hdr[TOTAL_ATP_HDR_SIZE]; }; + struct timeval timenow; - ATDISABLE(s, atp->atp_lock); - if (rcbp->rc_queue != atp) { - ATENABLE(s, atp->atp_lock); + if (rcbp->rc_queue != atp) return; - } if (rcbp->rc_not_sent_bitmap == 0) goto nothing_to_send; @@ -494,124 +481,80 @@ void atp_send_replies(atp, rcbp) m = rcbp->rc_xmt; m0 = gbuf_cont(m); - if (m0) { - m0_rptr = gbuf_rptr(m0); - m0_wptr = gbuf_wptr(m0); - } if (gbuf_len(m) > TOTAL_ATP_HDR_SIZE) bdsp = (struct atpBDS *)(AT_ATP_HDR(m)->data); else bdsp = 0; - + offset = 0; + if (m0) + space = gbuf_msgsize(m0); + else + space = 0; for (i = 0; i < cnt; i++) { - if (rcbp->rc_snd[i] == 0) { - if ((len = UAS_VALUE(bdsp->bdsBuffSz))) - gbuf_rinc(m0,len); - - } else { - m2 = rc_xmt[i]; - gbuf_rinc(m2,AT_WR_OFFSET); - gbuf_wset(m2,TOTAL_ATP_HDR_SIZE); - *(struct ddp_atp *)(gbuf_rptr(m2))= *(struct ddp_atp *)(gbuf_rptr(m)); - athp = AT_ATP_HDR(m2); - ATP_CLEAR_CONTROL(athp); - athp->cmd = ATP_CMD_TRESP; - athp->bitmap = i; - if (i == (cnt - 1)) - athp->eom = 1; /* for the last fragment */ - if (bdsp) - UAL_UAL(athp->user_bytes, bdsp->bdsUserData); - - if (bdsp) - if (len = UAS_VALUE(bdsp->bdsBuffSz)) { /* copy in data */ - if (m0 && gbuf_len(m0)) { - if ((m1 = gbuf_dupb(m0)) == NULL) { - for (i = 0; i < cnt; i++) - if (rc_xmt[i]) - gbuf_freem(rc_xmt[i]); - gbuf_rptr(m0) = m0_rptr; - gbuf_wset(m0,(m0_wptr-m0_rptr)); - goto nothing_to_send; + if (rcbp->rc_snd[i] == 0) { + if ((len = UAS_VALUE(bdsp->bdsBuffSz))) { + offset += len; + space -= len; } - gbuf_wset(m1,len); - gbuf_rinc(m0,len); - if ((len = gbuf_len(m0)) < 0) { - gbuf_rdec(m0,len); - gbuf_wdec(m1,len); - if (!append_copy((struct mbuf *)m1, - (struct mbuf *)gbuf_cont(m0), FALSE)) { - for (i = 0; i < cnt; i++) - if (rc_xmt[i]) - gbuf_freem(rc_xmt[i]); - gbuf_rptr(m0) = m0_rptr; - gbuf_wset(m0,(m0_wptr-m0_rptr)); - goto nothing_to_send; + } else { + mhdr = rc_xmt[i]; + /* setup header fields */ + gbuf_rinc(mhdr,AT_WR_OFFSET); + gbuf_wset(mhdr,TOTAL_ATP_HDR_SIZE); + *(struct ddp_atp *)(gbuf_rptr(mhdr))= *(struct ddp_atp *)(gbuf_rptr(m)); + athp = AT_ATP_HDR(mhdr); + ATP_CLEAR_CONTROL(athp); + athp->cmd = ATP_CMD_TRESP; + athp->bitmap = i; + if (i == (cnt - 1)) + athp->eom = 1; /* for the last fragment */ + if (bdsp) { + UAL_UAL(athp->user_bytes, bdsp->bdsUserData); + if ((len = UAS_VALUE(bdsp->bdsBuffSz)) && m0 != 0 && space > 0) { + if ((m1 = m_copym(m0, offset, len, M_DONTWAIT)) == 0) { + for (i = 0; i < cnt; i++) + if (rc_xmt[i]) + gbuf_freem(rc_xmt[i]); + goto nothing_to_send; + } + offset += len; + space -= len; + gbuf_cont(mhdr) = m1; } - } else - gbuf_cont(m1) = 0; - gbuf_cont(m2) = m1; + } - /* temp fix for page boundary problem - bug# 2703163 */ - lastPage = (caddr_t)((int)(gbuf_wptr(m1) - 1) & ~PAGE_MASK); /* 4k page of last byte */ - if (lastPage != (caddr_t)((int)(gbuf_rptr(m1)) & ~PAGE_MASK)) { /* 1st byte and last on same page ? */ - if ((m3 = gbuf_dupb(m1)) == NULL) { - for (i = 0; i < cnt; i++) - if (rc_xmt[i]) - gbuf_freem(rc_xmt[i]); - (gbuf_rptr(m0)) = m0_rptr; - gbuf_wset(m0, (m0_wptr - m0_rptr)); - goto nothing_to_send; - } - (gbuf_rptr(m3)) = lastPage; /* new mbuf starts at beginning of page */ - gbuf_wset(m3, (gbuf_wptr(m1) - lastPage)); /* len = remaining data crossing over page boundary */ - gbuf_wset(m1, (lastPage - (gbuf_rptr(m1)))); /* adjust len of m1 */ - (gbuf_cont(m1)) = m3; - (gbuf_cont(m3)) = 0; - } - } + AT_DDP_HDR(mhdr)->src_socket = src_socket; + dPrintf(D_M_ATP_LOW, D_L_OUTPUT, + ("atp_send_replies: %d, socket=%d, size=%d\n", + i, atp->atp_socket_no, gbuf_msgsize(gbuf_cont(m2)))); + + if (mlist) + gbuf_next(mprev) = mhdr; + else + mlist = mhdr; + mprev = mhdr; + + rcbp->rc_snd[i] = 0; + rcbp->rc_not_sent_bitmap &= ~atp_mask[i]; + if (rcbp->rc_not_sent_bitmap == 0) + break; } - - AT_DDP_HDR(m2)->src_socket = src_socket; - dPrintf(D_M_ATP_LOW, D_L_OUTPUT, - ("atp_send_replies: %d, socket=%d, size=%d\n", - i, atp->atp_socket_no, gbuf_msgsize(gbuf_cont(m2)))); - - if (mlist) - gbuf_next(mprev) = m2; - else - mlist = m2; - mprev = m2; - - rcbp->rc_snd[i] = 0; - rcbp->rc_not_sent_bitmap &= ~atp_mask[i]; - if (rcbp->rc_not_sent_bitmap == 0) - break; - } - /* - * on to the next frag - */ - bdsp++; - } - if (m0) { - gbuf_rptr(m0) = m0_rptr; - gbuf_wset(m0,(m0_wptr-m0_rptr)); + /* + * on to the next frag + */ + bdsp++; } - - if (mlist) { - ATENABLE(s, atp->atp_lock); + if (mlist) DDP_OUTPUT(mlist); - ATDISABLE(s, atp->atp_lock); - } + nothing_to_send: /* * If all replies from this reply block have been sent then * remove it from the queue and mark it so */ - if (rcbp->rc_queue != atp) { - ATENABLE(s, atp->atp_lock); + if (rcbp->rc_queue != atp) return; - } rcbp->rc_rep_waiting = 0; /* @@ -625,22 +568,20 @@ nothing_to_send: * resources. */ if (rcbp->rc_xo && rcbp->rc_state != RCB_RELEASED) { - ATDISABLE(s_gen, atpgen_lock); + getmicrouptime(&timenow); if (rcbp->rc_timestamp == 0) { - rcbp->rc_timestamp = time.tv_sec; + rcbp->rc_timestamp = timenow.tv_sec; if (rcbp->rc_timestamp == 0) rcbp->rc_timestamp = 1; ATP_Q_APPEND(atp_need_rel, rcbp, rc_tlist); } rcbp->rc_state = RCB_RESPONSE_FULL; - ATENABLE(s_gen, atpgen_lock); } else atp_rcb_free(rcbp); - ATENABLE(s, atp->atp_lock); } /* atp_send_replies */ -static void +static int atp_pack_bdsp(trp, bdsp) register struct atp_trans *trp; register struct atpBDS *bdsp; @@ -648,12 +589,13 @@ atp_pack_bdsp(trp, bdsp) register gbuf_t *m = NULL; register int i, datsize = 0; struct atpBDS *bdsbase = bdsp; + int error = 0; dPrintf(D_M_ATP, D_L_INFO, ("atp_pack_bdsp: socket=%d\n", trp->tr_queue->atp_socket_no)); for (i = 0; i < ATP_TRESP_MAX; i++, bdsp++) { - short bufsize = UAS_VALUE(bdsp->bdsBuffSz); + unsigned short bufsize = UAS_VALUE(bdsp->bdsBuffSz); long bufaddr = UAL_VALUE(bdsp->bdsBuffAddr); if ((m = trp->tr_rcv[i]) == NULL) @@ -675,15 +617,17 @@ atp_pack_bdsp(trp, bdsp) register char *buf = (char *)bufaddr; while (m) { - short len = (short)(gbuf_len(m)); + unsigned short len = (unsigned short)(gbuf_len(m)); if (len) { if (len > bufsize) len = bufsize; - copyout((caddr_t)gbuf_rptr(m), - (caddr_t)&buf[tmp], - len); + if ((error = copyout((caddr_t)gbuf_rptr(m), + CAST_USER_ADDR_T(&buf[tmp]), + len)) != 0) { + return error; + } bufsize -= len; - tmp =+ len; + tmp += len; } m = gbuf_cont(m); } @@ -700,9 +644,16 @@ atp_pack_bdsp(trp, bdsp) dPrintf(D_M_ATP, D_L_INFO, (" : size=%d\n", datsize)); + + return 0; } /* atp_pack_bdsp */ +/* create an mbuf chain with mbuf packet headers for each ATP response packet + * to be sent. m contains the DDP hdr, ATP hdr, and and array of atpBDS structs. + * chained to m is an mbuf that contians the actual data pointed to by the atpBDS + * structs. + */ static int atp_unpack_bdsp(atp, m, rcbp, cnt, wait) struct atp_state *atp; @@ -711,17 +662,20 @@ atp_unpack_bdsp(atp, m, rcbp, cnt, wait) register int cnt, wait; { register struct atpBDS *bdsp; - register gbuf_t *m2, *m1, *m0, *m3; - caddr_t lastPage; - register at_atp_t *athp; - register int i, len, s_gen; - at_socket src_socket; - struct ddp_atp { + register gbuf_t *m2, *m1, *m0, *mhdr; + caddr_t lastPage; + at_atp_t *athp; + int i, len; + at_socket src_socket; + + struct ddp_atp { char ddp_atp_hdr[TOTAL_ATP_HDR_SIZE]; }; - gbuf_t *mprev, *mlist = 0; - gbuf_t *rc_xmt[ATP_TRESP_MAX]; - unsigned char *m0_rptr, *m0_wptr; + gbuf_t *mprev, *mlist = 0; + gbuf_t *rc_xmt[ATP_TRESP_MAX]; + unsigned char *m0_rptr, *m0_wptr; + int err, offset, space; + struct timeval timenow; /* * get the user data structure pointer @@ -787,117 +741,86 @@ atp_unpack_bdsp(atp, m, rcbp, cnt, wait) goto l_send; } + /* create an array of mbuf packet headers for the packets to be sent + * to contain the atp and ddp headers with room at the front for the + * datalink header. + */ for (i = 0; i < cnt; i++) { /* all hdrs, packet data and dst addr storage */ if ((rc_xmt[i] = - gbuf_alloc_wait(AT_WR_OFFSET+TOTAL_ATP_HDR_SIZE, - wait)) == NULL) { - for (cnt = 0; cnt < i; cnt++) - if (rc_xmt[cnt]) - gbuf_freeb(rc_xmt[cnt]); - return 0; + gbuf_alloc_wait(AT_WR_OFFSET+TOTAL_ATP_HDR_SIZE, wait)) == NULL) { + for (cnt = 0; cnt < i; cnt++) + if (rc_xmt[cnt]) + gbuf_freeb(rc_xmt[cnt]); + return 0; } } - if (m0) { - m0_rptr = gbuf_rptr(m0); - m0_wptr = gbuf_wptr(m0); - } - for (i = 0; i < cnt; i++) { - m2 = rc_xmt[i]; - gbuf_rinc(m2,AT_WR_OFFSET); - gbuf_wset(m2,TOTAL_ATP_HDR_SIZE); - *(struct ddp_atp *)(gbuf_rptr(m2))= *(struct ddp_atp *)(gbuf_rptr(m)); - athp = AT_ATP_HDR(m2); + /* run through the atpBDS structs and create an mbuf for the data + * portion of each packet to be sent. these get chained to the mbufs + * containing the ATP and DDP headers. this code assumes that no ATP + * packet is contained in more than 2 mbufs (e.i crosses mbuf boundary + * no more than one time). + */ + offset = 0; + if (m0) + space = gbuf_msgsize(m0); + for (i = 0; i < cnt; i++) { /* for each hdr mbuf */ + mhdr = rc_xmt[i]; + /* setup header fields */ + gbuf_rinc(mhdr,AT_WR_OFFSET); + gbuf_wset(mhdr,TOTAL_ATP_HDR_SIZE); + *(struct ddp_atp *)(gbuf_rptr(mhdr))= *(struct ddp_atp *)(gbuf_rptr(m)); + athp = AT_ATP_HDR(mhdr); ATP_CLEAR_CONTROL(athp); athp->cmd = ATP_CMD_TRESP; athp->bitmap = i; if (i == (cnt - 1)) athp->eom = 1; /* for the last fragment */ UAL_UAL(athp->user_bytes, bdsp->bdsUserData); - - if ((len = UAS_VALUE(bdsp->bdsBuffSz))) { /* copy in data */ - if (m0 && gbuf_len(m0)) { - if ((m1 = gbuf_dupb_wait(m0, wait)) == NULL) { + + if ((len = UAS_VALUE(bdsp->bdsBuffSz)) != 0 && m0 != 0 && space > 0) { + if ((m1 = m_copym(m0, offset, len, wait)) == 0) { for (i = 0; i < cnt; i++) if (rc_xmt[i]) gbuf_freem(rc_xmt[i]); - gbuf_rptr(m0) = m0_rptr; - gbuf_wset(m0,(m0_wptr-m0_rptr)); return 0; } - gbuf_wset(m1,len); /* *** m1 is first len bytes of m0? *** */ - gbuf_rinc(m0,len); - if ((len = gbuf_len(m0)) < 0) { - gbuf_rdec(m0,len); - gbuf_wdec(m1,len); - if (!append_copy((struct mbuf *)m1, - (struct mbuf *)gbuf_cont(m0), wait)) { - for (i = 0; i < cnt; i++) - if (rc_xmt[i]) - gbuf_freem(rc_xmt[i]); - gbuf_rptr(m0) = m0_rptr; - gbuf_wset(m0,(m0_wptr-m0_rptr)); - return 0; - } - } else - gbuf_cont(m1) = 0; - gbuf_cont(m2) = m1; - - /* temp fix for page boundary problem - bug# 2703163 */ - lastPage = (caddr_t)((int)(gbuf_wptr(m1) - 1) & ~PAGE_MASK); /* 4k page of last byte */ - if (lastPage != (caddr_t)((int)(gbuf_rptr(m1)) & ~PAGE_MASK)) { /* 1st byte and last on same page ? */ - if ((m3 = gbuf_dupb_wait(m1, wait)) == NULL) { - for (i = 0; i < cnt; i++) - if (rc_xmt[i]) - gbuf_freem(rc_xmt[i]); - (gbuf_rptr(m0)) = m0_rptr; - gbuf_wset(m0, (m0_wptr - m0_rptr)); - return 0; - } - (gbuf_rptr(m3)) = lastPage; /* new mbuf starts at beginning of page */ - gbuf_wset(m3, (gbuf_wptr(m1) - lastPage)); /* len = remaining data crossing over page boundary */ - gbuf_wset(m1, (lastPage - (gbuf_rptr(m1)))); /* adjust len of m1 */ - (gbuf_cont(m1)) = m3; - (gbuf_cont(m3)) = 0; - } - } + gbuf_cont(mhdr) = m1; + space -= len; + offset += len; } - - AT_DDP_HDR(m2)->src_socket = src_socket; + + AT_DDP_HDR(mhdr)->src_socket = src_socket; dPrintf(D_M_ATP_LOW,D_L_INFO, ("atp_unpack_bdsp %d, socket=%d, size=%d, cnt=%d\n", - i,atp->atp_socket_no,gbuf_msgsize(gbuf_cont(m2)),cnt)); + i,atp->atp_socket_no,gbuf_msgsize(gbuf_cont(mhdr)),cnt)); if (mlist) - gbuf_next(mprev) = m2; + gbuf_next(mprev) = mhdr; else - mlist = m2; - mprev = m2; + mlist = mhdr; + mprev = mhdr; /* * on to the next frag */ bdsp++; } - if (m0) { - gbuf_rptr(m0) = m0_rptr; - gbuf_wset(m0,(m0_wptr-m0_rptr)); - } /* * send the message */ l_send: if (rcbp->rc_xo) { - ATDISABLE(s_gen, atpgen_lock); + getmicrouptime(&timenow); if (rcbp->rc_timestamp == 0) { - if ((rcbp->rc_timestamp = time.tv_sec) == 0) + if ((rcbp->rc_timestamp = timenow.tv_sec) == 0) rcbp->rc_timestamp = 1; ATP_Q_APPEND(atp_need_rel, rcbp, rc_tlist); } - ATENABLE(s_gen, atpgen_lock); } DDP_OUTPUT(mlist); return 0; + } /* atp_unpack_bdsp */ #define ATP_SOCKET_LAST (DDP_SOCKET_LAST-6) @@ -914,7 +837,6 @@ int atp_bind(gref, sVal, flag) unsigned char inpC, sNextUsed = 0; unsigned int sMin, sMax, sSav; struct atp_state *atp; - int s; atp = (struct atp_state *)gref->info; if (atp->dflag) @@ -922,7 +844,6 @@ int atp_bind(gref, sVal, flag) sMax = ATP_SOCKET_LAST; sMin = ATP_SOCKET_FIRST; - ATDISABLE(s, atpgen_lock); if (flag && (*flag == 3)) { sMin += 40; if (sMin < sNext) { @@ -935,7 +856,6 @@ int atp_bind(gref, sVal, flag) ((sVal > sMax) || (sVal < 2) || (sVal == 6) || (ddp_socket_inuse(sVal, DDP_ATP) && (atp_inputQ[sVal] != (gref_t *)1)))) { - ATENABLE(s, atpgen_lock); return 0; } @@ -965,7 +885,6 @@ again: sNext = 0; *flag = (unsigned char)sSav; } - ATENABLE(s, atpgen_lock); return 0; } } @@ -979,7 +898,6 @@ again: sNext = 0; } - ATENABLE(s, atpgen_lock); return (int)sVal; } @@ -988,19 +906,16 @@ void atp_req_ind(atp, mioc) register gbuf_t *mioc; { register struct atp_rcb *rcbp; - int s; if ((rcbp = atp->atp_attached.head) != 0) { gbuf_cont(mioc) = rcbp->rc_ioctl; rcbp->rc_ioctl = NULL; - ATDISABLE(s, atp->atp_lock); if (rcbp->rc_xo) { ATP_Q_REMOVE(atp->atp_attached, rcbp, rc_list); rcbp->rc_state = RCB_NOTIFIED; ATP_Q_APPEND(atp->atp_rcb, rcbp, rc_list); } else atp_rcb_free(rcbp); - ATENABLE(s, atp->atp_lock); if (gbuf_cont(mioc)) ((ioc_t *)gbuf_rptr(mioc))->ioc_count = gbuf_msgsize(gbuf_cont(mioc)); else @@ -1053,7 +968,6 @@ void atp_cancel_req(gref, tid) gref_t *gref; unsigned short tid; { - int s; struct atp_state *atp; struct atp_trans *trp; @@ -1061,12 +975,10 @@ void atp_cancel_req(gref, tid) if (atp->dflag) atp = (struct atp_state *)atp->atp_msgq; - ATDISABLE(s, atp->atp_lock); for (trp = atp->atp_trans_wait.head; trp; trp = trp->tr_list.next) { if (trp->tr_tid == tid) break; } - ATENABLE(s, atp->atp_lock); if (trp != NULL) atp_free(trp); } @@ -1078,9 +990,7 @@ void atp_dequeue_atp(atp) struct atp_state *atp; { - int s; - ATDISABLE(s, atpall_lock); if (atp == atp_used_list) { if ((atp_used_list = atp->atp_trans_waiting) != 0) atp->atp_trans_waiting->atp_rcb_waiting = 0; @@ -1092,7 +1002,6 @@ atp_dequeue_atp(atp) atp->atp_trans_waiting = 0; atp->atp_rcb_waiting = 0; - ATENABLE(s, atpall_lock); } void @@ -1101,15 +1010,11 @@ atp_timout(func, trp, ticks) struct atp_trans *trp; int ticks; { - int s; unsigned int sum; struct atp_trans *curr_trp, *prev_trp; - ATDISABLE(s, atptmo_lock); - if (trp->tr_tmo_func) { - ATENABLE(s, atptmo_lock); + if (trp->tr_tmo_func) return; - } trp->tr_tmo_func = func; trp->tr_tmo_delta = 1+(ticks>>5); @@ -1117,7 +1022,6 @@ atp_timout(func, trp, ticks) if (trp_tmo_list == 0) { trp->tr_tmo_next = trp->tr_tmo_prev = 0; trp_tmo_list = trp; - ATENABLE(s, atptmo_lock); return; } @@ -1151,7 +1055,6 @@ atp_timout(func, trp, ticks) trp_tmo_list->tr_tmo_prev = trp; trp_tmo_list = trp; } - ATENABLE(s, atptmo_lock); } void @@ -1159,13 +1062,9 @@ atp_untimout(func, trp) void (*func)(); struct atp_trans *trp; { - int s; - ATDISABLE(s, atptmo_lock); - if (trp->tr_tmo_func == 0) { - ATENABLE(s, atptmo_lock); + if (trp->tr_tmo_func == 0) return; - } if (trp_tmo_list == trp) { if ((trp_tmo_list = trp->tr_tmo_next) != 0) { @@ -1179,27 +1078,24 @@ atp_untimout(func, trp) } } trp->tr_tmo_func = 0; - ATENABLE(s, atptmo_lock); } void -atp_trp_clock_funnel(arg) +atp_trp_clock_locked(arg) void *arg; { - thread_funnel_set(network_flock, TRUE); + atalk_lock(); atp_trp_clock(arg); - thread_funnel_set(network_flock, FALSE); + atalk_unlock(); } void atp_trp_clock(arg) void *arg; { - int s; struct atp_trans *trp; void (*tr_tmo_func)(); - ATDISABLE(s, atptmo_lock); if (trp_tmo_list) trp_tmo_list->tr_tmo_delta--; while (((trp = trp_tmo_list) != 0) && (trp_tmo_list->tr_tmo_delta == 0)) { @@ -1207,14 +1103,11 @@ atp_trp_clock(arg) trp_tmo_list->tr_tmo_prev = 0; if ((tr_tmo_func = trp->tr_tmo_func) != 0) { trp->tr_tmo_func = 0; - ATENABLE(s, atptmo_lock); (*tr_tmo_func)(trp); - ATDISABLE(s, atptmo_lock); } } - ATENABLE(s, atptmo_lock); - timeout(atp_trp_clock_funnel, (void *)arg, (1<<5)); + timeout(atp_trp_clock_locked, (void *)arg, (1<<5)); } void @@ -1229,8 +1122,9 @@ atp_send_req(gref, mioc) register at_ddp_t *ddp; gbuf_t *m, *m2, *bds; struct atp_set_default *sdb; - int s, old; + int old; unsigned int timer; + u_short temp_net; atp = (struct atp_state *)((struct atp_state *)gref->info)->atp_msgq; iocbp = (ioc_t *)gbuf_rptr(mioc); @@ -1278,7 +1172,7 @@ l_retry: */ athp = AT_ATP_HDR(m2); athp->cmd = ATP_CMD_TREQ; - UAS_ASSIGN(athp->tid, trp->tr_tid); + UAS_ASSIGN_HTON(athp->tid, trp->tr_tid); athp->eom = 0; athp->sts = 0; trp->tr_xo = athp->xo; @@ -1291,7 +1185,8 @@ l_retry: trp->tr_socket.net = NET_VALUE(ddp->dst_net); trp->tr_local_socket = atp->atp_socket_no; trp->tr_local_node = ddp->src_node; - NET_NET(trp->tr_local_net, ddp->src_net); + temp_net = NET_VALUE(ddp->src_net); + NET_ASSIGN_NOSWAP(trp->tr_local_net, temp_net); #ifdef NOT_YET /* save the local information in the gref */ @@ -1304,9 +1199,7 @@ l_retry: /* * Put us in the transaction waiting queue */ - ATDISABLE(s, atp->atp_lock); ATP_Q_APPEND(atp->atp_trans_wait, trp, tr_list); - ATENABLE(s, atp->atp_lock); /* * Send the message and set the timer @@ -1322,20 +1215,20 @@ l_retry: } } /* atp_send_req */ -void atp_retry_req(m) - gbuf_t *m; +void atp_retry_req(arg) + void *arg; { + gbuf_t *m = (gbuf_t *)arg; gref_t *gref; - boolean_t funnel_state; - funnel_state = thread_funnel_set(network_flock, TRUE); + atalk_lock(); gref = (gref_t *)((ioc_t *)gbuf_rptr(m))->ioc_private; if (gref->info) { ((asp_scb_t *)gref->info)->stat_msg = 0; atp_send_req(gref, m); } - (void) thread_funnel_set(network_flock, FALSE); + atalk_unlock(); } void atp_send_rsp(gref, m, wait) @@ -1348,6 +1241,7 @@ void atp_send_rsp(gref, m, wait) register at_atp_t *athp; register at_ddp_t *ddp; int s, xcnt; + u_short temp_net; atp = (struct atp_state *)gref->info; if (atp->dflag) @@ -1358,9 +1252,8 @@ void atp_send_rsp(gref, m, wait) /* * search for the corresponding rcb */ - ATDISABLE(s, atp->atp_lock); for (rcbp = atp->atp_rcb.head; rcbp; rcbp = rcbp->rc_list.next) { - if ( (rcbp->rc_tid == UAS_VALUE(athp->tid)) && + if ( (rcbp->rc_tid == UAS_VALUE_NTOH(athp->tid)) && (rcbp->rc_socket.node == ddp->dst_node) && (rcbp->rc_socket.net == NET_VALUE(ddp->dst_net)) && (rcbp->rc_socket.socket == ddp->dst_socket) ) @@ -1372,11 +1265,9 @@ void atp_send_rsp(gref, m, wait) */ if ((rcbp && (rcbp->rc_state != RCB_NOTIFIED)) || (rcbp == NULL && athp->xo) ) { - ATENABLE(s, atp->atp_lock); gbuf_freem(m); return; } - ATENABLE(s, atp->atp_lock); if (rcbp == NULL) { /* a response is being sent for an ALO transaction */ if ((rcbp = atp_rcb_alloc(atp)) == NULL) { @@ -1387,16 +1278,15 @@ void atp_send_rsp(gref, m, wait) rcbp->rc_socket.socket = ddp->dst_socket; rcbp->rc_socket.node = ddp->dst_node; rcbp->rc_socket.net = NET_VALUE(ddp->dst_net); - rcbp->rc_tid = UAS_VALUE(athp->tid); + rcbp->rc_tid = UAS_VALUE_NTOH(athp->tid); rcbp->rc_bitmap = 0xff; rcbp->rc_xo = 0; rcbp->rc_state = RCB_RESPONSE_FULL; - ATDISABLE(s, atp->atp_lock); ATP_Q_APPEND(atp->atp_rcb, rcbp, rc_list); - ATENABLE(s, atp->atp_lock); } else if (ddp->src_node == 0) { - NET_NET(ddp->src_net, rcbp->rc_local_net); + temp_net = NET_VALUE_NOSWAP(rcbp->rc_local_net); + NET_ASSIGN(ddp->src_net, temp_net); ddp->src_node = rcbp->rc_local_node; } @@ -1436,7 +1326,7 @@ int asp_pack_bdsp(trp, xm) gbuf_rinc(m, ATP_HDR_SIZE); if (UAL_VALUE(bdsp->bdsBuffAddr)) { - short tmp; + short tmp = 0; /* user expects data back */ m = gbuf_strip(m); @@ -1494,7 +1384,7 @@ _ATPsndreq(fd, buf, len, nowait, err, proc) void *proc; { gref_t *gref; - int s, rc; + int rc; unsigned short tid; unsigned int timer; register struct atp_state *atp; @@ -1506,24 +1396,36 @@ _ATPsndreq(fd, buf, len, nowait, err, proc) gbuf_t *m2, *m, *mioc; char bds[atpBDSsize]; - if ((*err = atalk_getref(0, fd, &gref, proc)) != 0) + if ((*err = atalk_getref(0, fd, &gref, proc, 1)) != 0) return -1; if ((gref == 0) || ((atp = (struct atp_state *)gref->info) == 0) || (atp->atp_flags & ATP_CLOSING)) { dPrintf(D_M_ATP, D_L_ERROR, ("ATPsndreq: stale handle=0x%x, pid=%d\n", (u_int) gref, gref->pid)); + file_drop(fd); + *err = EINVAL; + return -1; + } + if (len < atpBDSsize + sizeof(struct atp_set_default) + TOTAL_ATP_HDR_SIZE || + len > atpBDSsize + sizeof(struct atp_set_default) + TOTAL_ATP_HDR_SIZE + + ATP_DATA_SIZE) { + file_drop(fd); *err = EINVAL; return -1; } while ((mioc = gbuf_alloc(sizeof(ioc_t), PRI_MED)) == 0) { - ATDISABLE(s, atp->atp_delay_lock); - rc = tsleep(&atp->atp_delay_event, PSOCK | PCATCH, "atpmioc", 10); - ATENABLE(s, atp->atp_delay_lock); + struct timespec ts; + /* the vaue of 10n terms of hz is 100ms */ + ts.tv_sec = 0; + ts.tv_nsec = 100 *1000 * NSEC_PER_USEC; + + rc = msleep(&atp->atp_delay_event, atalk_mutex, PSOCK | PCATCH, "atpmioc", &ts); if (rc != 0) { *err = rc; + file_drop(fd); return -1; } @@ -1531,21 +1433,26 @@ _ATPsndreq(fd, buf, len, nowait, err, proc) gbuf_wset(mioc,sizeof(ioc_t)); len -= atpBDSsize; while ((m2 = gbuf_alloc(len, PRI_MED)) == 0) { - ATDISABLE(s, atp->atp_delay_lock); - rc = tsleep(&atp->atp_delay_event, PSOCK | PCATCH, "atpm2", 10); - ATENABLE(s, atp->atp_delay_lock); + struct timespec ts; + /* the vaue of 10n terms of hz is 100ms */ + ts.tv_sec = 0; + ts.tv_nsec = 100 *1000 * NSEC_PER_USEC; + + rc = msleep(&atp->atp_delay_event, atalk_mutex, PSOCK | PCATCH, "atpm2", &ts); if (rc != 0) { gbuf_freeb(mioc); + file_drop(fd); *err = rc; return -1; } } gbuf_wset(m2, len); gbuf_cont(mioc) = m2; - if (((*err = copyin((caddr_t)buf, (caddr_t)bds, atpBDSsize)) != 0) - || ((*err = copyin((caddr_t)&buf[atpBDSsize], + if (((*err = copyin(CAST_USER_ADDR_T(buf), (caddr_t)bds, atpBDSsize)) != 0) + || ((*err = copyin(CAST_USER_ADDR_T(&buf[atpBDSsize]), (caddr_t)gbuf_rptr(m2), len)) != 0)) { gbuf_freem(mioc); + file_drop(fd); return -1; } gbuf_set_type(mioc, MSG_IOCTL); @@ -1567,11 +1474,15 @@ _ATPsndreq(fd, buf, len, nowait, err, proc) * allocate and set up the transaction record */ while ((trp = atp_trans_alloc(atp)) == 0) { - ATDISABLE(s, atp->atp_delay_lock); - rc = tsleep(&atp->atp_delay_event, PSOCK | PCATCH, "atptrp", 10); - ATENABLE(s, atp->atp_delay_lock); + struct timespec ts; + /* the vaue of 10n terms of hz is 100ms */ + ts.tv_sec = 0; + ts.tv_nsec = 100 *1000 * NSEC_PER_USEC; + + rc = msleep(&atp->atp_delay_event, atalk_mutex, PSOCK | PCATCH, "atptrp", &ts); if (rc != 0) { gbuf_freem(mioc); + file_drop(fd); *err = rc; return -1; } @@ -1594,7 +1505,7 @@ _ATPsndreq(fd, buf, len, nowait, err, proc) */ athp = AT_ATP_HDR(m2); athp->cmd = ATP_CMD_TREQ; - UAS_ASSIGN(athp->tid, trp->tr_tid); + UAS_ASSIGN_HTON(athp->tid, trp->tr_tid); athp->eom = 0; athp->sts = 0; trp->tr_xo = athp->xo; @@ -1619,9 +1530,7 @@ _ATPsndreq(fd, buf, len, nowait, err, proc) /* * Put us in the transaction waiting queue */ - ATDISABLE(s, atp->atp_lock); ATP_Q_APPEND(atp->atp_trans_wait, trp, tr_list); - ATENABLE(s, atp->atp_lock); /* * Send the message and set the timer @@ -1634,26 +1543,26 @@ _ATPsndreq(fd, buf, len, nowait, err, proc) if (m) DDP_OUTPUT(m); - if (nowait) + if (nowait) { + file_drop(fd); return (int)tid; + } /* * wait for the transaction to complete */ - ATDISABLE(s, trp->tr_lock); while ((trp->tr_state != TRANS_DONE) && (trp->tr_state != TRANS_FAILED) && (trp->tr_state != TRANS_ABORTING)) { trp->tr_rsp_wait = 1; - rc = tsleep(&trp->tr_event, PSOCK | PCATCH, "atpsndreq", 0); + rc = msleep(&trp->tr_event, atalk_mutex, PSOCK | PCATCH, "atpsndreq", 0); if (rc != 0) { trp->tr_rsp_wait = 0; - ATENABLE(s, trp->tr_lock); + file_drop(fd); *err = rc; return -1; } } trp->tr_rsp_wait = 0; - ATENABLE(s, trp->tr_lock); if (trp->tr_state == TRANS_FAILED || trp->tr_state == TRANS_ABORTING) { @@ -1661,6 +1570,7 @@ _ATPsndreq(fd, buf, len, nowait, err, proc) * transaction timed out, return error */ atp_free(trp); + file_drop(fd); *err = ETIMEDOUT; return -1; } @@ -1668,18 +1578,35 @@ _ATPsndreq(fd, buf, len, nowait, err, proc) /* * copy out the recv data */ - atp_pack_bdsp(trp, bds); + if ((*err = atp_pack_bdsp(trp, (struct atpBDS *)bds)) != 0) { + atp_free(trp); + file_drop(fd); + return -1; + } /* * copyout the result info */ - copyout((caddr_t)bds, (caddr_t)buf, atpBDSsize); + if ((*err = copyout((caddr_t)bds, CAST_USER_ADDR_T(buf), atpBDSsize)) != 0) { + atp_free(trp); + file_drop(fd); + return -1; + } atp_free(trp); + file_drop(fd); return (int)tid; } /* _ATPsndreq */ + +/* entry point for ATP send response. respbuf contains a DDP hdr, + * ATP hdr, and atpBDS array. The bdsDataSz field of the first atpBDS + * struct contains the number of atpBDS structs in the array. resplen + * contains the len of the data in respbuf and datalen contains the + * len of the data buffer holding the response packets which the atpBDS + * struct entries point to. + */ int _ATPsndrsp(fd, respbuff, resplen, datalen, err, proc) int fd; @@ -1689,17 +1616,20 @@ _ATPsndrsp(fd, respbuff, resplen, datalen, err, proc) int *err; void *proc; { - gref_t *gref; - int s, rc; - long bufaddr; - gbuf_t *m, *mdata; - register short len; - register int size; - register struct atp_state *atp; - register struct atpBDS *bdsp; - register char *buf; + gref_t *gref; + int s, rc; + long bufaddr; + gbuf_t *m, *mdata; + short space; + int size; + struct atp_state *atp; + struct atpBDS *bdsp; + u_int16_t *bufsz; + char *buf; + int bds_cnt, count, len; + caddr_t dataptr; - if ((*err = atalk_getref(0, fd, &gref, proc)) != 0) + if ((*err = atalk_getref(0, fd, &gref, proc, 1)) != 0) return -1; if ((gref == 0) || ((atp = (struct atp_state *)gref->info) == 0) @@ -1707,6 +1637,7 @@ _ATPsndrsp(fd, respbuff, resplen, datalen, err, proc) dPrintf(D_M_ATP, D_L_ERROR, ("ATPsndrsp: stale handle=0x%x, pid=%d\n", (u_int) gref, gref->pid)); + file_drop(fd); *err = EINVAL; return -1; } @@ -1714,46 +1645,101 @@ _ATPsndrsp(fd, respbuff, resplen, datalen, err, proc) /* * allocate buffer and copy in the response info */ + if (resplen < 0 || resplen > TOTAL_ATP_HDR_SIZE + sizeof(struct atpBDS)*ATP_TRESP_MAX) { + file_drop(fd); + *err = EINVAL; + return -1; + } if ((m = gbuf_alloc_wait(resplen, TRUE)) == 0) { *err = ENOMEM; + file_drop(fd); return -1; } - if ((*err = copyin((caddr_t)respbuff, (caddr_t)gbuf_rptr(m), resplen)) != 0) { + if ((*err = copyin(CAST_USER_ADDR_T(respbuff), (caddr_t)gbuf_rptr(m), resplen)) != 0) { gbuf_freeb(m); + file_drop(fd); return -1; } gbuf_wset(m,resplen); ((at_ddp_t *)gbuf_rptr(m))->src_node = 0; bdsp = (struct atpBDS *)(gbuf_rptr(m) + TOTAL_ATP_HDR_SIZE); - if ((resplen == TOTAL_ATP_HDR_SIZE) || ((len = UAS_VALUE(bdsp->bdsDataSz)) == 1)) - len = 0; - else - len = 16 * sizeof(gbuf_t); /* - * allocate buffer and copy in the response data + * allocate buffers and copy in the response data. + * note that only the size field of the atpBDS field + * is used internally in the kernel. */ - if ((mdata = gbuf_alloc_wait(datalen+len, TRUE)) == 0) { - gbuf_freem(m); + bds_cnt = get_bds_entries(m); /* count of # entries */ + /* check correctness of parameters */ + if (bds_cnt > ATP_TRESP_MAX) { + gbuf_freem(m); + *err = EINVAL; + file_drop(fd); + return -1; + } + + for (size = 0, count = 0; count < bds_cnt; count++) { + if (UAS_VALUE(bdsp[count].bdsBuffSz) > ATP_DATA_SIZE) { + gbuf_freem(m); + *err = EINVAL; + file_drop(fd); + return -1; + } + size += UAS_VALUE(bdsp[count].bdsBuffSz); + } + if (size > datalen) { + gbuf_freem(m); + *err = EINVAL; + file_drop(fd); + return -1; + } + + /* get the first mbuf */ + if ((mdata = gbuf_alloc_wait((space = (size > MCLBYTES ? MCLBYTES : size)), TRUE)) == 0) { + gbuf_freem(m); + file_drop(fd); *err = ENOMEM; return -1; } gbuf_cont(m) = mdata; - for (size=0; bdsp < (struct atpBDS *)gbuf_wptr(m); bdsp++) { - if ((bufaddr = UAL_VALUE(bdsp->bdsBuffAddr)) != 0) { - len = UAS_VALUE(bdsp->bdsBuffSz); - buf = (char *)bufaddr; - if ((*err = copyin((caddr_t)buf, - (caddr_t)&gbuf_rptr(mdata)[size], len)) != 0) { + dataptr = mtod(mdata, caddr_t); + for (count = 0; count < bds_cnt; bdsp++, count++) { + if ((bufaddr = UAL_VALUE(bdsp->bdsBuffAddr)) != 0 && + (len = UAS_VALUE(bdsp->bdsBuffSz)) != 0) { + if (len > space) { /* enough room ? */ + gbuf_wset(mdata, dataptr - mtod(mdata, caddr_t)); /* set len of last mbuf */ + /* allocate the next mbuf */ + if ((gbuf_cont(mdata) = m_get((M_WAIT), MSG_DATA)) == 0) { + gbuf_freem(m); + file_drop(fd); + *err = ENOMEM; + return -1; + } + mdata = gbuf_cont(mdata); + MCLGET(mdata, M_WAIT); + if (!(mdata->m_flags & M_EXT)) { + m_freem(m); + file_drop(fd); + return(NULL); + } + dataptr = mtod(mdata, caddr_t); + space = MCLBYTES; + } + /* do the copyin */ + if ((*err = copyin(CAST_USER_ADDR_T(bufaddr), dataptr, len)) != 0) { gbuf_freem(m); + file_drop(fd); return -1; } - size += len; + dataptr += len; + space -= len; } } - gbuf_wset(mdata,size); + gbuf_wset(mdata, dataptr - mtod(mdata, caddr_t)); /* set len of last mbuf */ + gbuf_cont(m)->m_pkthdr.len = size; /* set packet hdr len */ atp_send_rsp(gref, m, TRUE); + file_drop(fd); return 0; } @@ -1769,20 +1755,26 @@ _ATPgetreq(fd, buf, buflen, err, proc) register struct atp_state *atp; register struct atp_rcb *rcbp; register gbuf_t *m, *m_head; - int s, size, len; + int size, len; - if ((*err = atalk_getref(0, fd, &gref, proc)) != 0) + if ((*err = atalk_getref(0, fd, &gref, proc, 1)) != 0) return -1; if ((gref == 0) || ((atp = (struct atp_state *)gref->info) == 0) || (atp->atp_flags & ATP_CLOSING)) { dPrintf(D_M_ATP, D_L_ERROR, ("ATPgetreq: stale handle=0x%x, pid=%d\n", (u_int) gref, gref->pid)); + file_drop(fd); + *err = EINVAL; + return -1; + } + + if (buflen < DDP_X_HDR_SIZE + ATP_HDR_SIZE) { + file_drop(fd); *err = EINVAL; return -1; } - ATDISABLE(s, atp->atp_lock); if ((rcbp = atp->atp_attached.head) != NULL) { /* * Got one, move it to the active response Q @@ -1800,7 +1792,6 @@ _ATPgetreq(fd, buf, buflen, err, proc) */ atp_rcb_free(rcbp); } - ATENABLE(s, atp->atp_lock); /* * copyout the request data, including the protocol header @@ -1808,17 +1799,18 @@ _ATPgetreq(fd, buf, buflen, err, proc) for (size=0, m=m_head; m; m = gbuf_cont(m)) { if ((len = gbuf_len(m)) > buflen) len = buflen; - copyout((caddr_t)gbuf_rptr(m), (caddr_t)&buf[size], len); + copyout((caddr_t)gbuf_rptr(m), CAST_USER_ADDR_T(&buf[size]), len); size += len; if ((buflen -= len) == 0) break; } gbuf_freem(m_head); + file_drop(fd); return size; } - ATENABLE(s, atp->atp_lock); + file_drop(fd); return -1; } @@ -1832,21 +1824,21 @@ _ATPgetrsp(fd, bdsp, err, proc) gref_t *gref; register struct atp_state *atp; register struct atp_trans *trp; - int s, tid; + int tid; char bds[atpBDSsize]; - if ((*err = atalk_getref(0, fd, &gref, proc)) != 0) + if ((*err = atalk_getref(0, fd, &gref, proc, 1)) != 0) return -1; if ((gref == 0) || ((atp = (struct atp_state *)gref->info) == 0) || (atp->atp_flags & ATP_CLOSING)) { dPrintf(D_M_ATP, D_L_ERROR, ("ATPgetrsp: stale handle=0x%x, pid=%d\n", (u_int) gref, gref->pid)); + file_drop(fd); *err = EINVAL; return -1; } - ATDISABLE(s, atp->atp_lock); for (trp = atp->atp_trans_wait.head; trp; trp = trp->tr_list.next) { dPrintf(D_M_ATP, D_L_INFO, ("ATPgetrsp: atp:0x%x, trp:0x%x, state:%d\n", @@ -1854,22 +1846,32 @@ _ATPgetrsp(fd, bdsp, err, proc) switch (trp->tr_state) { case TRANS_DONE: - ATENABLE(s, atp->atp_lock); - if ((*err = copyin((caddr_t)bdsp, - (caddr_t)bds, sizeof(bds))) != 0) + if ((*err = copyin(CAST_USER_ADDR_T(bdsp), + (caddr_t)bds, sizeof(bds))) != 0) { + atp_free(trp); + file_drop(fd); + return -1; + } + if ((*err = atp_pack_bdsp(trp, (struct atpBDS *)bds)) != 0) { + atp_free(trp); + file_drop(fd); return -1; - atp_pack_bdsp(trp, bds); + } tid = (int)trp->tr_tid; atp_free(trp); - copyout((caddr_t)bds, (caddr_t)bdsp, sizeof(bds)); + if ((*err = copyout((caddr_t)bds, CAST_USER_ADDR_T(bdsp), sizeof(bds))) != 0) { + file_drop(fd); + return -1; + } + file_drop(fd); return tid; case TRANS_FAILED: /* * transaction timed out, return error */ - ATENABLE(s, atp->atp_lock); atp_free(trp); + file_drop(fd); *err = ETIMEDOUT; return -1; @@ -1877,8 +1879,8 @@ _ATPgetrsp(fd, bdsp, err, proc) continue; } } - ATENABLE(s, atp->atp_lock); + file_drop(fd); *err = EINVAL; return -1; } @@ -1888,7 +1890,6 @@ atp_drop_req(gref, m) gref_t *gref; gbuf_t *m; { - int s; struct atp_state *atp; struct atp_rcb *rcbp; at_atp_t *athp; @@ -1903,9 +1904,8 @@ atp_drop_req(gref, m) /* * search for the corresponding rcb */ - ATDISABLE(s, atp->atp_lock); for (rcbp = atp->atp_rcb.head; rcbp; rcbp = rcbp->rc_list.next) { - if ( (rcbp->rc_tid == UAS_VALUE(athp->tid)) && + if ( (rcbp->rc_tid == UAS_VALUE_NTOH(athp->tid)) && (rcbp->rc_socket.node == ddp->src_node) && (rcbp->rc_socket.net == NET_VALUE(ddp->src_net)) && (rcbp->rc_socket.socket == ddp->src_socket) ) @@ -1917,7 +1917,6 @@ atp_drop_req(gref, m) */ if (rcbp) atp_rcb_free(rcbp); - ATENABLE(s, atp->atp_lock); gbuf_freem(m); }