17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
27a5eb7107SBryan Cantrill /*
2880d5689fSPatrick Mooney * Copyright 2017 Joyent, Inc.
29a5eb7107SBryan Cantrill */
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate /*
327c478bd9Sstevel@tonic-gate * av1394 asynchronous module
337c478bd9Sstevel@tonic-gate */
347c478bd9Sstevel@tonic-gate #include <sys/stat.h>
357c478bd9Sstevel@tonic-gate #include <sys/file.h>
367c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
377c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
387c478bd9Sstevel@tonic-gate #include <sys/1394/targets/av1394/av1394_impl.h>
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate /* configuration routines */
417c478bd9Sstevel@tonic-gate static void av1394_async_cleanup(av1394_inst_t *, int);
427c478bd9Sstevel@tonic-gate static int av1394_async_create_minor_node(av1394_inst_t *);
437c478bd9Sstevel@tonic-gate static void av1394_async_remove_minor_node(av1394_inst_t *);
447c478bd9Sstevel@tonic-gate static int av1394_async_update_targetinfo(av1394_inst_t *);
457c478bd9Sstevel@tonic-gate static int av1394_async_db2arq_type(int);
467c478bd9Sstevel@tonic-gate static void av1394_async_putbq(av1394_queue_t *, mblk_t *);
477c478bd9Sstevel@tonic-gate
487c478bd9Sstevel@tonic-gate static int av1394_ioctl_arq_get_ibuf_size(av1394_inst_t *, void *, int);
497c478bd9Sstevel@tonic-gate static int av1394_ioctl_arq_set_ibuf_size(av1394_inst_t *, void *, int);
507c478bd9Sstevel@tonic-gate
517c478bd9Sstevel@tonic-gate /* tunables */
527c478bd9Sstevel@tonic-gate int av1394_ibuf_size_default = 64 * 1024; /* default ibuf size */
537c478bd9Sstevel@tonic-gate int av1394_ibuf_size_max = 1024 * 1024; /* max ibuf size */
547c478bd9Sstevel@tonic-gate
557c478bd9Sstevel@tonic-gate /*
567c478bd9Sstevel@tonic-gate *
577c478bd9Sstevel@tonic-gate * --- configuration entry points
587c478bd9Sstevel@tonic-gate *
597c478bd9Sstevel@tonic-gate */
607c478bd9Sstevel@tonic-gate int
av1394_async_attach(av1394_inst_t * avp)617c478bd9Sstevel@tonic-gate av1394_async_attach(av1394_inst_t *avp)
627c478bd9Sstevel@tonic-gate {
637c478bd9Sstevel@tonic-gate av1394_async_t *ap = &avp->av_a;
647c478bd9Sstevel@tonic-gate ddi_iblock_cookie_t ibc = avp->av_attachinfo.iblock_cookie;
657c478bd9Sstevel@tonic-gate
667c478bd9Sstevel@tonic-gate mutex_init(&ap->a_mutex, NULL, MUTEX_DRIVER, ibc);
677c478bd9Sstevel@tonic-gate av1394_initq(&ap->a_rq, ibc, av1394_ibuf_size_default);
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate if (av1394_fcp_attach(avp) != DDI_SUCCESS) {
707c478bd9Sstevel@tonic-gate av1394_async_cleanup(avp, 1);
717c478bd9Sstevel@tonic-gate return (DDI_FAILURE);
727c478bd9Sstevel@tonic-gate }
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate if (av1394_cfgrom_init(avp) != DDI_SUCCESS) {
757c478bd9Sstevel@tonic-gate av1394_async_cleanup(avp, 2);
767c478bd9Sstevel@tonic-gate return (DDI_FAILURE);
777c478bd9Sstevel@tonic-gate }
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gate if (av1394_async_create_minor_node(avp) != DDI_SUCCESS) {
807c478bd9Sstevel@tonic-gate av1394_async_cleanup(avp, 3);
817c478bd9Sstevel@tonic-gate return (DDI_FAILURE);
827c478bd9Sstevel@tonic-gate }
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate if (av1394_async_update_targetinfo(avp) != DDI_SUCCESS) {
857c478bd9Sstevel@tonic-gate av1394_async_cleanup(avp, 4);
867c478bd9Sstevel@tonic-gate return (DDI_FAILURE);
877c478bd9Sstevel@tonic-gate }
887c478bd9Sstevel@tonic-gate
897c478bd9Sstevel@tonic-gate return (DDI_SUCCESS);
907c478bd9Sstevel@tonic-gate }
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate void
av1394_async_detach(av1394_inst_t * avp)937c478bd9Sstevel@tonic-gate av1394_async_detach(av1394_inst_t *avp)
947c478bd9Sstevel@tonic-gate {
957c478bd9Sstevel@tonic-gate av1394_async_cleanup(avp, AV1394_CLEANUP_LEVEL_MAX);
967c478bd9Sstevel@tonic-gate }
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate void
av1394_async_bus_reset(av1394_inst_t * avp)997c478bd9Sstevel@tonic-gate av1394_async_bus_reset(av1394_inst_t *avp)
1007c478bd9Sstevel@tonic-gate {
1017c478bd9Sstevel@tonic-gate av1394_async_t *ap = &avp->av_a;
1027c478bd9Sstevel@tonic-gate mblk_t *bp;
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate (void) av1394_async_update_targetinfo(avp);
1057c478bd9Sstevel@tonic-gate
1067c478bd9Sstevel@tonic-gate mutex_enter(&ap->a_mutex);
1077c478bd9Sstevel@tonic-gate if (ap->a_nopen > 0) {
1087c478bd9Sstevel@tonic-gate mutex_exit(&ap->a_mutex);
1097c478bd9Sstevel@tonic-gate return;
1107c478bd9Sstevel@tonic-gate }
1117c478bd9Sstevel@tonic-gate mutex_exit(&ap->a_mutex);
1127c478bd9Sstevel@tonic-gate
1137c478bd9Sstevel@tonic-gate /* queue up a bus reset message */
114*2570281cSToomas Soome if ((bp = allocb(1, BPRI_HI)) != NULL) {
1157c478bd9Sstevel@tonic-gate DB_TYPE(bp) = AV1394_M_BUS_RESET;
1167c478bd9Sstevel@tonic-gate av1394_async_putq_rq(avp, bp);
1177c478bd9Sstevel@tonic-gate }
1187c478bd9Sstevel@tonic-gate }
1197c478bd9Sstevel@tonic-gate
1207c478bd9Sstevel@tonic-gate int
av1394_async_cpr_resume(av1394_inst_t * avp)1217c478bd9Sstevel@tonic-gate av1394_async_cpr_resume(av1394_inst_t *avp)
1227c478bd9Sstevel@tonic-gate {
1237c478bd9Sstevel@tonic-gate int ret;
1247c478bd9Sstevel@tonic-gate
1257c478bd9Sstevel@tonic-gate ret = av1394_async_update_targetinfo(avp);
1267c478bd9Sstevel@tonic-gate
1277c478bd9Sstevel@tonic-gate return (ret);
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate void
av1394_async_reconnect(av1394_inst_t * avp)1317c478bd9Sstevel@tonic-gate av1394_async_reconnect(av1394_inst_t *avp)
1327c478bd9Sstevel@tonic-gate {
1337c478bd9Sstevel@tonic-gate (void) av1394_async_update_targetinfo(avp);
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate int
av1394_async_open(av1394_inst_t * avp,int flag)1377c478bd9Sstevel@tonic-gate av1394_async_open(av1394_inst_t *avp, int flag)
1387c478bd9Sstevel@tonic-gate {
1397c478bd9Sstevel@tonic-gate av1394_async_t *ap = &avp->av_a;
1407c478bd9Sstevel@tonic-gate
1417c478bd9Sstevel@tonic-gate mutex_enter(&ap->a_mutex);
1427c478bd9Sstevel@tonic-gate if (ap->a_nopen == 0) {
1437c478bd9Sstevel@tonic-gate ap->a_pollevents = 0;
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate ap->a_nopen++;
1467c478bd9Sstevel@tonic-gate ap->a_oflag = flag;
1477c478bd9Sstevel@tonic-gate mutex_exit(&ap->a_mutex);
1487c478bd9Sstevel@tonic-gate
1497c478bd9Sstevel@tonic-gate return (0);
1507c478bd9Sstevel@tonic-gate }
1517c478bd9Sstevel@tonic-gate
1527c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1537c478bd9Sstevel@tonic-gate int
av1394_async_close(av1394_inst_t * avp,int flag)1547c478bd9Sstevel@tonic-gate av1394_async_close(av1394_inst_t *avp, int flag)
1557c478bd9Sstevel@tonic-gate {
1567c478bd9Sstevel@tonic-gate av1394_async_t *ap = &avp->av_a;
1577c478bd9Sstevel@tonic-gate
1587c478bd9Sstevel@tonic-gate av1394_cfgrom_close(avp);
1597c478bd9Sstevel@tonic-gate
1607c478bd9Sstevel@tonic-gate av1394_flushq(&ap->a_rq);
1617c478bd9Sstevel@tonic-gate
1627c478bd9Sstevel@tonic-gate mutex_enter(&ap->a_mutex);
1637c478bd9Sstevel@tonic-gate ap->a_nopen = 0;
1647c478bd9Sstevel@tonic-gate ap->a_pollevents = 0;
1657c478bd9Sstevel@tonic-gate mutex_exit(&ap->a_mutex);
1667c478bd9Sstevel@tonic-gate
1677c478bd9Sstevel@tonic-gate return (0);
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate
1707c478bd9Sstevel@tonic-gate int
av1394_async_read(av1394_inst_t * avp,struct uio * uiop)1717c478bd9Sstevel@tonic-gate av1394_async_read(av1394_inst_t *avp, struct uio *uiop)
1727c478bd9Sstevel@tonic-gate {
1737c478bd9Sstevel@tonic-gate av1394_async_t *ap = &avp->av_a;
1747c478bd9Sstevel@tonic-gate av1394_queue_t *q = &ap->a_rq;
1757c478bd9Sstevel@tonic-gate iec61883_arq_t arq;
1767c478bd9Sstevel@tonic-gate int ret = 0;
1777c478bd9Sstevel@tonic-gate mblk_t *mp;
1787c478bd9Sstevel@tonic-gate int dbtype;
1797c478bd9Sstevel@tonic-gate int len;
1807c478bd9Sstevel@tonic-gate
1817c478bd9Sstevel@tonic-gate /* copyout as much as we can */
1827c478bd9Sstevel@tonic-gate while ((uiop->uio_resid > 0) && (ret == 0)) {
1837c478bd9Sstevel@tonic-gate /*
1847c478bd9Sstevel@tonic-gate * if data is available, copy it out. otherwise wait until
1857c478bd9Sstevel@tonic-gate * data arrives, unless opened with non-blocking flag
1867c478bd9Sstevel@tonic-gate */
1877c478bd9Sstevel@tonic-gate if ((mp = av1394_getq(q)) == NULL) {
1887c478bd9Sstevel@tonic-gate if (ap->a_oflag & FNDELAY) {
1897c478bd9Sstevel@tonic-gate return (EAGAIN);
1907c478bd9Sstevel@tonic-gate }
1917c478bd9Sstevel@tonic-gate if (av1394_qwait_sig(q) <= 0) {
1927c478bd9Sstevel@tonic-gate ret = EINTR;
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate continue;
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate dbtype = AV1394_DBTYPE(mp);
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate /* generate and copyout ARQ header, if not already */
1997c478bd9Sstevel@tonic-gate if (!AV1394_IS_NOHDR(mp)) {
2007c478bd9Sstevel@tonic-gate /* headers cannot be partially read */
2017c478bd9Sstevel@tonic-gate if (uiop->uio_resid < sizeof (arq)) {
2027c478bd9Sstevel@tonic-gate av1394_async_putbq(q, mp);
2037c478bd9Sstevel@tonic-gate ret = EINVAL;
2047c478bd9Sstevel@tonic-gate break;
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate
2077c478bd9Sstevel@tonic-gate arq.arq_type = av1394_async_db2arq_type(dbtype);
2087c478bd9Sstevel@tonic-gate arq.arq_len = MBLKL(mp);
2097c478bd9Sstevel@tonic-gate arq.arq_data.octlet = 0;
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gate /* copy ARQ-embedded data */
2127c478bd9Sstevel@tonic-gate len = min(arq.arq_len, sizeof (arq.arq_data));
2137c478bd9Sstevel@tonic-gate bcopy(mp->b_rptr, &arq.arq_data.buf[0], len);
2147c478bd9Sstevel@tonic-gate
2157c478bd9Sstevel@tonic-gate /* copyout the ARQ */
2167c478bd9Sstevel@tonic-gate ret = uiomove(&arq, sizeof (arq), UIO_READ, uiop);
2177c478bd9Sstevel@tonic-gate if (ret != 0) {
2187c478bd9Sstevel@tonic-gate av1394_async_putbq(q, mp);
2197c478bd9Sstevel@tonic-gate break;
2207c478bd9Sstevel@tonic-gate }
2217c478bd9Sstevel@tonic-gate mp->b_rptr += len;
2227c478bd9Sstevel@tonic-gate AV1394_MARK_NOHDR(mp);
2237c478bd9Sstevel@tonic-gate }
2247c478bd9Sstevel@tonic-gate
2257c478bd9Sstevel@tonic-gate /* any data left? */
2267c478bd9Sstevel@tonic-gate if (MBLKL(mp) == 0) {
2277c478bd9Sstevel@tonic-gate freemsg(mp);
2287c478bd9Sstevel@tonic-gate continue;
2297c478bd9Sstevel@tonic-gate }
2307c478bd9Sstevel@tonic-gate
2317c478bd9Sstevel@tonic-gate /* now we have some data and some user buffer space to fill */
2327c478bd9Sstevel@tonic-gate len = min(uiop->uio_resid, MBLKL(mp));
2337c478bd9Sstevel@tonic-gate if (len > 0) {
2347c478bd9Sstevel@tonic-gate ret = uiomove(mp->b_rptr, len, UIO_READ, uiop);
2357c478bd9Sstevel@tonic-gate if (ret != 0) {
2367c478bd9Sstevel@tonic-gate av1394_async_putbq(q, mp);
2377c478bd9Sstevel@tonic-gate break;
2387c478bd9Sstevel@tonic-gate }
2397c478bd9Sstevel@tonic-gate mp->b_rptr += len;
2407c478bd9Sstevel@tonic-gate }
2417c478bd9Sstevel@tonic-gate
2427c478bd9Sstevel@tonic-gate /* save the rest of the data for later */
2437c478bd9Sstevel@tonic-gate if (MBLKL(mp) > 0) {
2447c478bd9Sstevel@tonic-gate av1394_async_putbq(q, mp);
2457c478bd9Sstevel@tonic-gate }
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate
2487c478bd9Sstevel@tonic-gate return (0);
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate
2517c478bd9Sstevel@tonic-gate int
av1394_async_write(av1394_inst_t * avp,struct uio * uiop)2527c478bd9Sstevel@tonic-gate av1394_async_write(av1394_inst_t *avp, struct uio *uiop)
2537c478bd9Sstevel@tonic-gate {
2547c478bd9Sstevel@tonic-gate iec61883_arq_t arq;
2557c478bd9Sstevel@tonic-gate int ret;
2567c478bd9Sstevel@tonic-gate
2577c478bd9Sstevel@tonic-gate /* all data should arrive in ARQ format */
2587c478bd9Sstevel@tonic-gate while (uiop->uio_resid >= sizeof (arq)) {
2597c478bd9Sstevel@tonic-gate if ((ret = uiomove(&arq, sizeof (arq), UIO_WRITE, uiop)) != 0) {
2607c478bd9Sstevel@tonic-gate break;
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate
2637c478bd9Sstevel@tonic-gate switch (arq.arq_type) {
2647c478bd9Sstevel@tonic-gate case IEC61883_ARQ_FCP_CMD:
2657c478bd9Sstevel@tonic-gate case IEC61883_ARQ_FCP_RESP:
2667c478bd9Sstevel@tonic-gate ret = av1394_fcp_write(avp, &arq, uiop);
2677c478bd9Sstevel@tonic-gate break;
2687c478bd9Sstevel@tonic-gate default:
2697c478bd9Sstevel@tonic-gate ret = EINVAL;
2707c478bd9Sstevel@tonic-gate }
2717c478bd9Sstevel@tonic-gate if (ret != 0) {
2727c478bd9Sstevel@tonic-gate break;
2737c478bd9Sstevel@tonic-gate }
2747c478bd9Sstevel@tonic-gate }
2757c478bd9Sstevel@tonic-gate
2767c478bd9Sstevel@tonic-gate return (ret);
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate
2797c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2807c478bd9Sstevel@tonic-gate int
av1394_async_ioctl(av1394_inst_t * avp,int cmd,intptr_t arg,int mode,int * rvalp)2817c478bd9Sstevel@tonic-gate av1394_async_ioctl(av1394_inst_t *avp, int cmd, intptr_t arg, int mode,
28280d5689fSPatrick Mooney int *rvalp)
2837c478bd9Sstevel@tonic-gate {
2847c478bd9Sstevel@tonic-gate int ret = EINVAL;
2857c478bd9Sstevel@tonic-gate
2867c478bd9Sstevel@tonic-gate switch (cmd) {
2877c478bd9Sstevel@tonic-gate case IEC61883_ARQ_GET_IBUF_SIZE:
2887c478bd9Sstevel@tonic-gate ret = av1394_ioctl_arq_get_ibuf_size(avp, (void *)arg, mode);
2897c478bd9Sstevel@tonic-gate break;
2907c478bd9Sstevel@tonic-gate case IEC61883_ARQ_SET_IBUF_SIZE:
2917c478bd9Sstevel@tonic-gate ret = av1394_ioctl_arq_set_ibuf_size(avp, (void *)arg, mode);
2927c478bd9Sstevel@tonic-gate break;
2937c478bd9Sstevel@tonic-gate case IEC61883_NODE_GET_BUS_NAME:
2947c478bd9Sstevel@tonic-gate ret = av1394_ioctl_node_get_bus_name(avp, (void *)arg, mode);
2957c478bd9Sstevel@tonic-gate break;
2967c478bd9Sstevel@tonic-gate case IEC61883_NODE_GET_UID:
2977c478bd9Sstevel@tonic-gate ret = av1394_ioctl_node_get_uid(avp, (void *)arg, mode);
2987c478bd9Sstevel@tonic-gate break;
2997c478bd9Sstevel@tonic-gate case IEC61883_NODE_GET_TEXT_LEAF:
3007c478bd9Sstevel@tonic-gate ret = av1394_ioctl_node_get_text_leaf(avp, (void *)arg, mode);
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate
3037c478bd9Sstevel@tonic-gate return (ret);
3047c478bd9Sstevel@tonic-gate }
3057c478bd9Sstevel@tonic-gate
3067c478bd9Sstevel@tonic-gate int
av1394_async_poll(av1394_inst_t * avp,short events,int anyyet,short * reventsp,struct pollhead ** phpp)3077c478bd9Sstevel@tonic-gate av1394_async_poll(av1394_inst_t *avp, short events, int anyyet, short *reventsp,
30880d5689fSPatrick Mooney struct pollhead **phpp)
3097c478bd9Sstevel@tonic-gate {
3107c478bd9Sstevel@tonic-gate av1394_async_t *ap = &avp->av_a;
3117c478bd9Sstevel@tonic-gate av1394_queue_t *rq = &ap->a_rq;
3127c478bd9Sstevel@tonic-gate
31380d5689fSPatrick Mooney if (events & (POLLIN | POLLET)) {
31480d5689fSPatrick Mooney if ((events & POLLIN) && av1394_peekq(rq)) {
3157c478bd9Sstevel@tonic-gate *reventsp |= POLLIN;
31680d5689fSPatrick Mooney }
317a5eb7107SBryan Cantrill
318a5eb7107SBryan Cantrill if ((!*reventsp && !anyyet) || (events & POLLET)) {
3197c478bd9Sstevel@tonic-gate mutex_enter(&ap->a_mutex);
32080d5689fSPatrick Mooney if (events & POLLIN) {
32180d5689fSPatrick Mooney ap->a_pollevents |= POLLIN;
32280d5689fSPatrick Mooney }
3237c478bd9Sstevel@tonic-gate *phpp = &ap->a_pollhead;
3247c478bd9Sstevel@tonic-gate mutex_exit(&ap->a_mutex);
3257c478bd9Sstevel@tonic-gate }
3267c478bd9Sstevel@tonic-gate }
3277c478bd9Sstevel@tonic-gate
3287c478bd9Sstevel@tonic-gate return (0);
3297c478bd9Sstevel@tonic-gate }
3307c478bd9Sstevel@tonic-gate
3317c478bd9Sstevel@tonic-gate
3327c478bd9Sstevel@tonic-gate /*
3337c478bd9Sstevel@tonic-gate * put a message on the read queue, take care of polling
3347c478bd9Sstevel@tonic-gate */
3357c478bd9Sstevel@tonic-gate void
av1394_async_putq_rq(av1394_inst_t * avp,mblk_t * mp)3367c478bd9Sstevel@tonic-gate av1394_async_putq_rq(av1394_inst_t *avp, mblk_t *mp)
3377c478bd9Sstevel@tonic-gate {
3387c478bd9Sstevel@tonic-gate av1394_async_t *ap = &avp->av_a;
3397c478bd9Sstevel@tonic-gate
3407c478bd9Sstevel@tonic-gate if (!av1394_putq(&ap->a_rq, mp)) {
3417c478bd9Sstevel@tonic-gate freemsg(mp);
3427c478bd9Sstevel@tonic-gate } else {
3437c478bd9Sstevel@tonic-gate mutex_enter(&ap->a_mutex);
3447c478bd9Sstevel@tonic-gate if (ap->a_pollevents & POLLIN) {
3457c478bd9Sstevel@tonic-gate ap->a_pollevents &= ~POLLIN;
3467c478bd9Sstevel@tonic-gate mutex_exit(&ap->a_mutex);
3477c478bd9Sstevel@tonic-gate pollwakeup(&ap->a_pollhead, POLLIN);
3487c478bd9Sstevel@tonic-gate } else {
3497c478bd9Sstevel@tonic-gate mutex_exit(&ap->a_mutex);
3507c478bd9Sstevel@tonic-gate }
3517c478bd9Sstevel@tonic-gate }
3527c478bd9Sstevel@tonic-gate }
3537c478bd9Sstevel@tonic-gate
3547c478bd9Sstevel@tonic-gate /*
3557c478bd9Sstevel@tonic-gate *
3567c478bd9Sstevel@tonic-gate * --- configuration routines
3577c478bd9Sstevel@tonic-gate *
3587c478bd9Sstevel@tonic-gate * av1394_async_cleanup()
3597c478bd9Sstevel@tonic-gate * Cleanup after attach
3607c478bd9Sstevel@tonic-gate */
3617c478bd9Sstevel@tonic-gate static void
av1394_async_cleanup(av1394_inst_t * avp,int level)3627c478bd9Sstevel@tonic-gate av1394_async_cleanup(av1394_inst_t *avp, int level)
3637c478bd9Sstevel@tonic-gate {
3647c478bd9Sstevel@tonic-gate av1394_async_t *ap = &avp->av_a;
3657c478bd9Sstevel@tonic-gate
3667c478bd9Sstevel@tonic-gate ASSERT((level > 0) && (level <= AV1394_CLEANUP_LEVEL_MAX));
3677c478bd9Sstevel@tonic-gate
3687c478bd9Sstevel@tonic-gate switch (level) {
3697c478bd9Sstevel@tonic-gate default:
3707c478bd9Sstevel@tonic-gate av1394_async_remove_minor_node(avp);
3717c478bd9Sstevel@tonic-gate /* FALLTHRU */
3727c478bd9Sstevel@tonic-gate case 3:
3737c478bd9Sstevel@tonic-gate av1394_cfgrom_fini(avp);
3747c478bd9Sstevel@tonic-gate /* FALLTHRU */
3757c478bd9Sstevel@tonic-gate case 2:
3767c478bd9Sstevel@tonic-gate av1394_fcp_detach(avp);
3777c478bd9Sstevel@tonic-gate /* FALLTHRU */
3787c478bd9Sstevel@tonic-gate case 1:
3797c478bd9Sstevel@tonic-gate av1394_destroyq(&ap->a_rq);
3807c478bd9Sstevel@tonic-gate mutex_destroy(&ap->a_mutex);
3817c478bd9Sstevel@tonic-gate }
3827c478bd9Sstevel@tonic-gate }
3837c478bd9Sstevel@tonic-gate
3847c478bd9Sstevel@tonic-gate /*
3857c478bd9Sstevel@tonic-gate * av1394_async_create_minor_node()
3867c478bd9Sstevel@tonic-gate * Create async minor node
3877c478bd9Sstevel@tonic-gate */
3887c478bd9Sstevel@tonic-gate static int
av1394_async_create_minor_node(av1394_inst_t * avp)3897c478bd9Sstevel@tonic-gate av1394_async_create_minor_node(av1394_inst_t *avp)
3907c478bd9Sstevel@tonic-gate {
3917c478bd9Sstevel@tonic-gate int ret;
3927c478bd9Sstevel@tonic-gate
3937c478bd9Sstevel@tonic-gate ret = ddi_create_minor_node(avp->av_dip, "async",
394a5eb7107SBryan Cantrill S_IFCHR, AV1394_ASYNC_INST2MINOR(avp->av_instance),
39592548b6cSToomas Soome DDI_NT_AV_ASYNC, 0);
3967c478bd9Sstevel@tonic-gate return (ret);
3977c478bd9Sstevel@tonic-gate }
3987c478bd9Sstevel@tonic-gate
3997c478bd9Sstevel@tonic-gate /*
4007c478bd9Sstevel@tonic-gate * av1394_async_remove_minor_node()
4017c478bd9Sstevel@tonic-gate * Remove async minor node
4027c478bd9Sstevel@tonic-gate */
4037c478bd9Sstevel@tonic-gate static void
av1394_async_remove_minor_node(av1394_inst_t * avp)4047c478bd9Sstevel@tonic-gate av1394_async_remove_minor_node(av1394_inst_t *avp)
4057c478bd9Sstevel@tonic-gate {
4067c478bd9Sstevel@tonic-gate ddi_remove_minor_node(avp->av_dip, "async");
4077c478bd9Sstevel@tonic-gate }
4087c478bd9Sstevel@tonic-gate
4097c478bd9Sstevel@tonic-gate /*
4107c478bd9Sstevel@tonic-gate * av1394_async_update_targetinfo()
4117c478bd9Sstevel@tonic-gate * Retrieve target info and bus generation
4127c478bd9Sstevel@tonic-gate */
4137c478bd9Sstevel@tonic-gate static int
av1394_async_update_targetinfo(av1394_inst_t * avp)4147c478bd9Sstevel@tonic-gate av1394_async_update_targetinfo(av1394_inst_t *avp)
4157c478bd9Sstevel@tonic-gate {
4167c478bd9Sstevel@tonic-gate av1394_async_t *ap = &avp->av_a;
4177c478bd9Sstevel@tonic-gate uint_t bg;
4187c478bd9Sstevel@tonic-gate int ret;
4197c478bd9Sstevel@tonic-gate
4207c478bd9Sstevel@tonic-gate mutex_enter(&avp->av_mutex);
4217c478bd9Sstevel@tonic-gate bg = avp->av_attachinfo.localinfo.bus_generation;
4227c478bd9Sstevel@tonic-gate mutex_exit(&avp->av_mutex);
4237c478bd9Sstevel@tonic-gate
4247c478bd9Sstevel@tonic-gate mutex_enter(&ap->a_mutex);
4257c478bd9Sstevel@tonic-gate ret = t1394_get_targetinfo(avp->av_t1394_hdl, bg, 0, &ap->a_targetinfo);
4267c478bd9Sstevel@tonic-gate ap->a_bus_generation = bg;
4277c478bd9Sstevel@tonic-gate mutex_exit(&ap->a_mutex);
4287c478bd9Sstevel@tonic-gate
4297c478bd9Sstevel@tonic-gate return (ret);
4307c478bd9Sstevel@tonic-gate }
4317c478bd9Sstevel@tonic-gate
4327c478bd9Sstevel@tonic-gate static int
av1394_async_db2arq_type(int dbtype)4337c478bd9Sstevel@tonic-gate av1394_async_db2arq_type(int dbtype)
4347c478bd9Sstevel@tonic-gate {
4357c478bd9Sstevel@tonic-gate int arq_type;
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate switch (dbtype) {
4387c478bd9Sstevel@tonic-gate case AV1394_M_FCP_RESP:
4397c478bd9Sstevel@tonic-gate arq_type = IEC61883_ARQ_FCP_RESP;
4407c478bd9Sstevel@tonic-gate break;
4417c478bd9Sstevel@tonic-gate case AV1394_M_FCP_CMD:
4427c478bd9Sstevel@tonic-gate arq_type = IEC61883_ARQ_FCP_CMD;
4437c478bd9Sstevel@tonic-gate break;
4447c478bd9Sstevel@tonic-gate case AV1394_M_BUS_RESET:
4457c478bd9Sstevel@tonic-gate arq_type = IEC61883_ARQ_BUS_RESET;
4467c478bd9Sstevel@tonic-gate break;
4477c478bd9Sstevel@tonic-gate default:
4487c478bd9Sstevel@tonic-gate ASSERT(0); /* cannot happen */
4497c478bd9Sstevel@tonic-gate }
4507c478bd9Sstevel@tonic-gate return (arq_type);
4517c478bd9Sstevel@tonic-gate }
4527c478bd9Sstevel@tonic-gate
4537c478bd9Sstevel@tonic-gate static void
av1394_async_putbq(av1394_queue_t * q,mblk_t * mp)4547c478bd9Sstevel@tonic-gate av1394_async_putbq(av1394_queue_t *q, mblk_t *mp)
4557c478bd9Sstevel@tonic-gate {
4567c478bd9Sstevel@tonic-gate if (!av1394_putbq(q, mp)) {
4577c478bd9Sstevel@tonic-gate freemsg(mp);
4587c478bd9Sstevel@tonic-gate }
4597c478bd9Sstevel@tonic-gate }
4607c478bd9Sstevel@tonic-gate
4617c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4627c478bd9Sstevel@tonic-gate static int
av1394_ioctl_arq_get_ibuf_size(av1394_inst_t * avp,void * arg,int mode)4637c478bd9Sstevel@tonic-gate av1394_ioctl_arq_get_ibuf_size(av1394_inst_t *avp, void *arg, int mode)
4647c478bd9Sstevel@tonic-gate {
4657c478bd9Sstevel@tonic-gate av1394_async_t *ap = &avp->av_a;
4667c478bd9Sstevel@tonic-gate int sz;
4677c478bd9Sstevel@tonic-gate int ret = 0;
4687c478bd9Sstevel@tonic-gate
4697c478bd9Sstevel@tonic-gate sz = av1394_getmaxq(&ap->a_rq);
4707c478bd9Sstevel@tonic-gate
4717c478bd9Sstevel@tonic-gate if (ddi_copyout(&sz, arg, sizeof (sz), mode) != 0) {
4727c478bd9Sstevel@tonic-gate ret = EFAULT;
4737c478bd9Sstevel@tonic-gate }
4747c478bd9Sstevel@tonic-gate
4757c478bd9Sstevel@tonic-gate return (ret);
4767c478bd9Sstevel@tonic-gate }
4777c478bd9Sstevel@tonic-gate
4787c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4797c478bd9Sstevel@tonic-gate static int
av1394_ioctl_arq_set_ibuf_size(av1394_inst_t * avp,void * arg,int mode)4807c478bd9Sstevel@tonic-gate av1394_ioctl_arq_set_ibuf_size(av1394_inst_t *avp, void *arg, int mode)
4817c478bd9Sstevel@tonic-gate {
4827c478bd9Sstevel@tonic-gate av1394_async_t *ap = &avp->av_a;
4837c478bd9Sstevel@tonic-gate int sz;
4847c478bd9Sstevel@tonic-gate int ret = 0;
4857c478bd9Sstevel@tonic-gate
4867c478bd9Sstevel@tonic-gate sz = (int)(intptr_t)arg;
4877c478bd9Sstevel@tonic-gate
4887c478bd9Sstevel@tonic-gate if ((sz < 0) || (sz > av1394_ibuf_size_max)) {
4897c478bd9Sstevel@tonic-gate ret = EINVAL;
4907c478bd9Sstevel@tonic-gate } else {
4917c478bd9Sstevel@tonic-gate av1394_setmaxq(&ap->a_rq, sz);
4927c478bd9Sstevel@tonic-gate }
4937c478bd9Sstevel@tonic-gate
4947c478bd9Sstevel@tonic-gate return (ret);
4957c478bd9Sstevel@tonic-gate }
496