*
* @APPLE_LICENSE_HEADER_START@
*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
*
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#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_unpack_bdsp(struct atp_state *, gbuf_t *, struct atp_rcb *,
int, int);
-void 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 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;
struct ddp_atp {
char ddp_atp_hdr[TOTAL_ATP_HDR_SIZE];
};
+ struct timeval timenow;
ATDISABLE(s, atp->atp_lock);
if (rcbp->rc_queue != atp) {
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))) {
* resources.
*/
if (rcbp->rc_xo && rcbp->rc_state != RCB_RELEASED) {
+ getmicrouptime(&timenow);
ATDISABLE(s_gen, atpgen_lock);
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);
if (len > bufsize)
len = bufsize;
copyout((caddr_t)gbuf_rptr(m),
- (caddr_t)&buf[tmp],
+ CAST_USER_ADDR_T(&buf[tmp]),
len);
bufsize -= len;
- tmp =+ len;
+ tmp += len;
}
m = gbuf_cont(m);
}
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
*/
l_send:
if (rcbp->rc_xo) {
+ getmicrouptime(&timenow);
ATDISABLE(s_gen, atpgen_lock);
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);
}
}
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
}
ATENABLE(s, atptmo_lock);
- timeout(atp_trp_clock_funnel, (void *)arg, (1<<5));
+ timeout(atp_trp_clock_locked, (void *)arg, (1<<5));
}
void
{
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)
gbuf_rinc(m, ATP_HDR_SIZE);
if (UAL_VALUE(bdsp->bdsBuffAddr)) {
- short tmp;
+ short tmp = 0;
/* user expects data back */
m = gbuf_strip(m);
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;
}
+
while ((mioc = gbuf_alloc(sizeof(ioc_t), PRI_MED)) == 0) {
+ struct timespec ts;
+ /* the vaue of 10n terms of hz is 100ms */
+ ts.tv_sec = 0;
+ ts.tv_nsec = 100 *1000 * NSEC_PER_USEC;
+
ATDISABLE(s, atp->atp_delay_lock);
- rc = tsleep(&atp->atp_delay_event, PSOCK | PCATCH, "atpmioc", 10);
+ rc = msleep(&atp->atp_delay_event, atalk_mutex, PSOCK | PCATCH, "atpmioc", &ts);
ATENABLE(s, atp->atp_delay_lock);
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) {
+ struct timespec ts;
+ /* the vaue of 10n terms of hz is 100ms */
+ ts.tv_sec = 0;
+ ts.tv_nsec = 100 *1000 * NSEC_PER_USEC;
+
ATDISABLE(s, atp->atp_delay_lock);
- rc = tsleep(&atp->atp_delay_event, PSOCK | PCATCH, "atpm2", 10);
+ rc = msleep(&atp->atp_delay_event, atalk_mutex, PSOCK | PCATCH, "atpm2", &ts);
ATENABLE(s, atp->atp_delay_lock);
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) {
+ struct timespec ts;
+ /* the vaue of 10n terms of hz is 100ms */
+ ts.tv_sec = 0;
+ ts.tv_nsec = 100 *1000 * NSEC_PER_USEC;
+
ATDISABLE(s, atp->atp_delay_lock);
- rc = tsleep(&atp->atp_delay_event, PSOCK | PCATCH, "atptrp", 10);
+ rc = msleep(&atp->atp_delay_event, atalk_mutex, PSOCK | PCATCH, "atptrp", &ts);
ATENABLE(s, atp->atp_delay_lock);
if (rc != 0) {
gbuf_freem(mioc);
+ file_drop(fd);
*err = rc;
return -1;
}
if (m)
DDP_OUTPUT(m);
- if (nowait)
+ if (nowait) {
+ file_drop(fd);
return (int)tid;
+ }
/*
* wait for the transaction to complete
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;
}
* transaction timed out, return error
*/
atp_free(trp);
+ file_drop(fd);
*err = ETIMEDOUT;
return -1;
}
/*
* copyout the result info
*/
- copyout((caddr_t)bds, (caddr_t)buf, atpBDSsize);
+ copyout((caddr_t)bds, CAST_USER_ADDR_T(buf), atpBDSsize);
atp_free(trp);
+ file_drop(fd);
return (int)tid;
} /* _ATPsndreq */
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;
}
*/
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);
if (bds_cnt > ATP_TRESP_MAX) {
gbuf_freem(m);
*err = EINVAL;
+ file_drop(fd);
return -1;
}
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;
}
/* 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;
}
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((caddr_t)bufaddr, dataptr, len)) != 0) {
+ if ((*err = copyin(CAST_USER_ADDR_T(bufaddr), dataptr, len)) != 0) {
gbuf_freem(m);
+ file_drop(fd);
return -1;
}
dataptr += len;
gbuf_cont(m)->m_pkthdr.len = size; /* set packet hdr len */
atp_send_rsp(gref, m, TRUE);
+ file_drop(fd);
return 0;
}
register gbuf_t *m, *m_head;
int s, 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;
}
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;
}
int s, 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;
}
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) {
+ file_drop(fd);
return -1;
+ }
atp_pack_bdsp(trp, (struct atpBDS *)bds);
tid = (int)trp->tr_tid;
atp_free(trp);
- copyout((caddr_t)bds, (caddr_t)bdsp, sizeof(bds));
+ copyout((caddr_t)bds, CAST_USER_ADDR_T(bdsp), sizeof(bds));
+ file_drop(fd);
return tid;
case TRANS_FAILED:
*/
ATENABLE(s, atp->atp_lock);
atp_free(trp);
+ file_drop(fd);
*err = ETIMEDOUT;
return -1;
}
ATENABLE(s, atp->atp_lock);
+ file_drop(fd);
*err = EINVAL;
return -1;
}