FreeBSD/sys/dev/firewire/firewire.c
/*
 * Async. request procedure for userland application.
 */
Async. request procedure for userland application.
Async . request procedure for userland application .
int
fw_asyreq(struct firewire_comm *fc, int sub, struct fw_xfer *xfer)
{
	int err = 0;
	struct fw_xferq *xferq;
	int len;
	struct fw_pkt *fp;
	int tcode;
	struct tcode_info *info;
	if (xfer == NULL)
		return EINVAL;
	if (xfer->hand == NULL) {
		printf("hand == NULL\n");
		return EINVAL;
	}
	fp = &xfer->send.hdr;
	tcode = fp->mode.common.tcode & 0xf;
	info = &fc->tcode[tcode];
	if (info->flag == 0) {
		printf("invalid tcode=%x\n", tcode);
		return EINVAL;
	}
	if ((fc->status < FWBUSEXPLORE) &&
	    ((tcode != FWTCODE_RREQQ) || (fp->mode.rreqq.dest_hi != 0xffff) ||
	    (fp->mode.rreqq.dest_lo  < 0xf0000000) ||
	    (fp->mode.rreqq.dest_lo >= 0xf0001000))) {
		xfer->resp = EAGAIN;
		xfer->flag = FWXF_BUSY;
		return (EAGAIN);
	}
	if (info->flag & FWTI_REQ)
		xferq = fc->atq;
	else
		xferq = fc->ats;
	len = info->hdr_len;
	if (xfer->send.pay_len > MAXREC(fc->maxrec)) {
		printf("send.pay_len > maxrec\n");
		return EINVAL;
	}
	if (info->flag & FWTI_BLOCK_STR)
		len = fp->mode.stream.len;
	else if (info->flag & FWTI_BLOCK_ASY)
		len = fp->mode.rresb.len;
	else
		len = 0;
	if (len != xfer->send.pay_len) {
		printf("len(%d) != send.pay_len(%d) %s(%x)\n",
		    len, xfer->send.pay_len, tcode_str[tcode], tcode);
		return EINVAL;
	}
	if (xferq->start == NULL) {
		printf("xferq->start == NULL\n");
		return EINVAL;
	}
	if (!(xferq->queued < xferq->maxq)) {
		device_printf(fc->bdev, "Discard a packet (queued=%d)\n",
			xferq->queued);
		return EAGAIN;
	}
	xfer->tl = -1;
	if (info->flag & FWTI_TLABEL) {
		if (fw_get_tlabel(fc, xfer) < 0)
			return EAGAIN;
	}
	xfer->resp = 0;
	xfer->fc = fc;
	xfer->q = xferq;
	fw_asystart(xfer);
	return err;
}
int fw_asyreq ( struct firewire_comm * fc , int sub , struct fw_xfer * xfer ) { int err = 0 ; struct fw_xferq * xferq ; int len ; struct fw_pkt * fp ; int tcode ; struct tcode_info * info ; if ( xfer == NULL ) return EINVAL ; if ( xfer -> hand == NULL ) { printf ( " \n " ) ; return EINVAL ; } fp = & xfer -> send . hdr ; tcode = fp -> mode . common . tcode & 0xf ; info = & fc -> tcode [ tcode ] ; if ( info -> flag == 0 ) { printf ( " \n " , tcode ) ; return EINVAL ; } if ( ( fc -> status < FWBUSEXPLORE ) && ( ( tcode != FWTCODE_RREQQ ) || ( fp -> mode . rreqq . dest_hi != 0xffff ) || ( fp -> mode . rreqq . dest_lo < 0xf0000000 ) || ( fp -> mode . rreqq . dest_lo >= 0xf0001000 ) ) ) { xfer -> resp = EAGAIN ; xfer -> flag = FWXF_BUSY ; return ( EAGAIN ) ; } if ( info -> flag & FWTI_REQ ) xferq = fc -> atq ; else xferq = fc -> ats ; len = info -> hdr_len ; if ( xfer -> send . pay_len > MAXREC ( fc -> maxrec ) ) { printf ( " \n " ) ; return EINVAL ; } if ( info -> flag & FWTI_BLOCK_STR ) len = fp -> mode . stream . len ; else if ( info -> flag & FWTI_BLOCK_ASY ) len = fp -> mode . rresb . len ; else len = 0 ; if ( len != xfer -> send . pay_len ) { printf ( " \n " , len , xfer -> send . pay_len , tcode_str [ tcode ] , tcode ) ; return EINVAL ; } if ( xferq -> start == NULL ) { printf ( " \n " ) ; return EINVAL ; } if ( ! ( xferq -> queued < xferq -> maxq ) ) { device_printf ( fc -> bdev , " \n " , xferq -> queued ) ; return EAGAIN ; } xfer -> tl = -1 ; if ( info -> flag & FWTI_TLABEL ) { if ( fw_get_tlabel ( fc , xfer ) < 0 ) return EAGAIN ; } xfer -> resp = 0 ; xfer -> fc = fc ; xfer -> q = xferq ; fw_asystart ( xfer ) ; return err ; }
Async.
Async .
/* XXX allow bus explore packets only after bus rest */