#include <sys/proc.h>
#include <sys/filedesc.h>
#include <sys/fcntl.h>
+#include <kern/locks.h>
#include <sys/mbuf.h>
#include <sys/ioctl.h>
#include <sys/malloc.h>
} \
}
-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;
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;
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;
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
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))) {
/*
* 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
*/
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;
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);
}
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);
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);
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;
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;
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;
/*
* 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;
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)
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);
}
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;
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
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)
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)
sMax = ATP_SOCKET_LAST;
sMin = ATP_SOCKET_FIRST;
- ATDISABLE(s, atpgen_lock);
if (flag && (*flag == 3)) {
sMin += 40;
if (sMin < sNext) {
((sVal > sMax) || (sVal < 2) || (sVal == 6) ||
(ddp_socket_inuse(sVal, DDP_ATP) &&
(atp_inputQ[sVal] != (gref_t *)1)))) {
- ATENABLE(s, atpgen_lock);
return 0;
}
sNext = 0;
*flag = (unsigned char)sSav;
}
- ATENABLE(s, atpgen_lock);
return 0;
}
}
sNext = 0;
}
- ATENABLE(s, atpgen_lock);
return (int)sVal;
}
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
gref_t *gref;
unsigned short tid;
{
- int s;
struct atp_state *atp;
struct atp_trans *trp;
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);
}
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;
atp->atp_trans_waiting = 0;
atp->atp_rcb_waiting = 0;
- ATENABLE(s, atpall_lock);
}
void
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);
if (trp_tmo_list == 0) {
trp->tr_tmo_next = trp->tr_tmo_prev = 0;
trp_tmo_list = trp;
- ATENABLE(s, atptmo_lock);
return;
}
trp_tmo_list->tr_tmo_prev = trp;
trp_tmo_list = trp;
}
- ATENABLE(s, atptmo_lock);
}
void
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) {
}
}
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)) {
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
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);
*/
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;
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 */
/*
* 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
}
} /* 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)
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)
/*
* 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) )
*/
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) {
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;
}
gbuf_rinc(m, ATP_HDR_SIZE);
if (UAL_VALUE(bdsp->bdsBuffAddr)) {
- short tmp;
+ short tmp = 0;
/* user expects data back */
m = gbuf_strip(m);
void *proc;
{
gref_t *gref;
- int s, rc;
+ int rc;
unsigned short tid;
unsigned int timer;
register struct atp_state *atp;
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;
}
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);
* 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;
}
*/
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;
/*
* 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
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) {
* transaction timed out, return error
*/
atp_free(trp);
+ file_drop(fd);
*err = ETIMEDOUT;
return -1;
}
/*
* 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;
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)
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;
}
/*
* 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;
}
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
*/
atp_rcb_free(rcbp);
}
- ATENABLE(s, atp->atp_lock);
/*
* copyout the request data, including the protocol header
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;
}
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",
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;
continue;
}
}
- ATENABLE(s, atp->atp_lock);
+ file_drop(fd);
*err = EINVAL;
return -1;
}
gref_t *gref;
gbuf_t *m;
{
- int s;
struct atp_state *atp;
struct atp_rcb *rcbp;
at_atp_t *athp;
/*
* 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) )
*/
if (rcbp)
atp_rcb_free(rcbp);
- ATENABLE(s, atp->atp_lock);
gbuf_freem(m);
}