1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*
28*7c478bd9Sstevel@tonic-gate  * 1394 mass storage SBP-2 bus routines
29*7c478bd9Sstevel@tonic-gate  */
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
32*7c478bd9Sstevel@tonic-gate #include <sys/errno.h>
33*7c478bd9Sstevel@tonic-gate #include <sys/cred.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/conf.h>
35*7c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
37*7c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
38*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate #include <sys/sbp2/bus.h>
41*7c478bd9Sstevel@tonic-gate #include <sys/1394/targets/scsa1394/impl.h>
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate static ddi_iblock_cookie_t scsa1394_bus_get_iblock_cookie(void *);
44*7c478bd9Sstevel@tonic-gate static uint_t	scsa1394_bus_get_node_id(void *);
45*7c478bd9Sstevel@tonic-gate static int	scsa1394_bus_alloc_cmd(void *, void **, int);
46*7c478bd9Sstevel@tonic-gate static void	scsa1394_bus_free_cmd(void *, void *);
47*7c478bd9Sstevel@tonic-gate static int	scsa1394_bus_rq(void *, void *, uint64_t, uint32_t *, int *);
48*7c478bd9Sstevel@tonic-gate static int	scsa1394_bus_rb(void *, void *, uint64_t, mblk_t **, int,
49*7c478bd9Sstevel@tonic-gate 		int *);
50*7c478bd9Sstevel@tonic-gate static int	scsa1394_bus_wq(void *, void *, uint64_t, uint32_t, int *);
51*7c478bd9Sstevel@tonic-gate static int	scsa1394_bus_wb(void *, void *, uint64_t, mblk_t *, int,
52*7c478bd9Sstevel@tonic-gate 		int *);
53*7c478bd9Sstevel@tonic-gate static int	scsa1394_bus_alloc_buf(void *, sbp2_bus_buf_t *);
54*7c478bd9Sstevel@tonic-gate static int	scsa1394_bus_alloc_buf_phys(void *, sbp2_bus_buf_t *);
55*7c478bd9Sstevel@tonic-gate static void	scsa1394_bus_free_buf_phys(void *, sbp2_bus_buf_t *);
56*7c478bd9Sstevel@tonic-gate static int	scsa1394_bus_alloc_buf_normal(void *, sbp2_bus_buf_t *,
57*7c478bd9Sstevel@tonic-gate 		boolean_t);
58*7c478bd9Sstevel@tonic-gate static void	scsa1394_bus_free_buf_normal(void *, sbp2_bus_buf_t *);
59*7c478bd9Sstevel@tonic-gate static void	scsa1394_bus_free_buf(void *, sbp2_bus_buf_t *);
60*7c478bd9Sstevel@tonic-gate static int	scsa1394_bus_sync_buf(void *, sbp2_bus_buf_t *, off_t, size_t,
61*7c478bd9Sstevel@tonic-gate 		int);
62*7c478bd9Sstevel@tonic-gate static void	scsa1394_bus_buf_rw_done(void *, sbp2_bus_buf_t *, void *, int);
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate /* callbacks */
65*7c478bd9Sstevel@tonic-gate static void	scsa1394_bus_recv_read_request(cmd1394_cmd_t *);
66*7c478bd9Sstevel@tonic-gate static void	scsa1394_bus_recv_write_request(cmd1394_cmd_t *);
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate sbp2_bus_t scsa1394_sbp2_bus = {
69*7c478bd9Sstevel@tonic-gate 	SBP2_BUS_REV,			/* rev */
70*7c478bd9Sstevel@tonic-gate 	0xFFFFF0000000LL,		/* csr_base */
71*7c478bd9Sstevel@tonic-gate 	IEEE1394_CONFIG_ROM_ADDR,	/* cfgrom_addr */
72*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_get_iblock_cookie,	/* get_iblock_cookie */
73*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_get_node_id,	/* get_node_id */
74*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_alloc_buf,		/* alloc_buf */
75*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_free_buf,		/* free_buf */
76*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_sync_buf,		/* sync_buf */
77*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_buf_rw_done,	/* buf_rd_done */
78*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_buf_rw_done,	/* buf_wr_done */
79*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_alloc_cmd,		/* alloc_cmd */
80*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_free_cmd,		/* free_cmd */
81*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_rq,		/* rq */
82*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_rb,		/* rb */
83*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_wq,		/* wq */
84*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_wb			/* wb */
85*7c478bd9Sstevel@tonic-gate };
86*7c478bd9Sstevel@tonic-gate 
87*7c478bd9Sstevel@tonic-gate /*
88*7c478bd9Sstevel@tonic-gate  * fault injector
89*7c478bd9Sstevel@tonic-gate  *
90*7c478bd9Sstevel@tonic-gate  * global on/off switch
91*7c478bd9Sstevel@tonic-gate  */
92*7c478bd9Sstevel@tonic-gate int scsa1394_bus_fi_on = 0;
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate /* fault probabilities per operation, in tenths of percent, i.e. 10 is 1% */
95*7c478bd9Sstevel@tonic-gate int scsa1394_bus_fi_prob_alloc_buf = 10;
96*7c478bd9Sstevel@tonic-gate int scsa1394_bus_fi_prob_alloc_cmd = 10;
97*7c478bd9Sstevel@tonic-gate int scsa1394_bus_fi_prob_rq = 10;
98*7c478bd9Sstevel@tonic-gate int scsa1394_bus_fi_prob_rb = 10;
99*7c478bd9Sstevel@tonic-gate int scsa1394_bus_fi_prob_wq = 10;
100*7c478bd9Sstevel@tonic-gate int scsa1394_bus_fi_prob_wb = 10;
101*7c478bd9Sstevel@tonic-gate 
102*7c478bd9Sstevel@tonic-gate #define	SCSA1394_BUS_FI_POSITIVE(p) (scsa1394_bus_fi_on &&	\
103*7c478bd9Sstevel@tonic-gate 	((p) > 0) && ((gethrtime() % (p)) == 0))
104*7c478bd9Sstevel@tonic-gate 
105*7c478bd9Sstevel@tonic-gate /*
106*7c478bd9Sstevel@tonic-gate  * translate command result to SBP2 error code
107*7c478bd9Sstevel@tonic-gate  */
108*7c478bd9Sstevel@tonic-gate static int
scsa1394_bus_rw_result2code(int result)109*7c478bd9Sstevel@tonic-gate scsa1394_bus_rw_result2code(int result)
110*7c478bd9Sstevel@tonic-gate {
111*7c478bd9Sstevel@tonic-gate 	int	code;
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate 	switch (result) {
114*7c478bd9Sstevel@tonic-gate 	case CMD1394_EDEVICE_BUSY:
115*7c478bd9Sstevel@tonic-gate 		code = SBP2_EBUSY;
116*7c478bd9Sstevel@tonic-gate 		break;
117*7c478bd9Sstevel@tonic-gate 	case CMD1394_EADDRESS_ERROR:
118*7c478bd9Sstevel@tonic-gate 		code = SBP2_EADDR;
119*7c478bd9Sstevel@tonic-gate 		break;
120*7c478bd9Sstevel@tonic-gate 	case CMD1394_ETIMEOUT:
121*7c478bd9Sstevel@tonic-gate 	case CMD1394_ERETRIES_EXCEEDED:
122*7c478bd9Sstevel@tonic-gate 		code = SBP2_ETIMEOUT;
123*7c478bd9Sstevel@tonic-gate 		break;
124*7c478bd9Sstevel@tonic-gate 	case CMD1394_EDEVICE_REMOVED:
125*7c478bd9Sstevel@tonic-gate 		code = SBP2_ENODEV;
126*7c478bd9Sstevel@tonic-gate 		break;
127*7c478bd9Sstevel@tonic-gate 	default:
128*7c478bd9Sstevel@tonic-gate 		code = SBP2_EIO;
129*7c478bd9Sstevel@tonic-gate 		break;
130*7c478bd9Sstevel@tonic-gate 	}
131*7c478bd9Sstevel@tonic-gate 	return (code);
132*7c478bd9Sstevel@tonic-gate }
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate static ddi_iblock_cookie_t
scsa1394_bus_get_iblock_cookie(void * hdl)135*7c478bd9Sstevel@tonic-gate scsa1394_bus_get_iblock_cookie(void *hdl)
136*7c478bd9Sstevel@tonic-gate {
137*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t *sp = hdl;
138*7c478bd9Sstevel@tonic-gate 
139*7c478bd9Sstevel@tonic-gate 	return (sp->s_attachinfo.iblock_cookie);
140*7c478bd9Sstevel@tonic-gate }
141*7c478bd9Sstevel@tonic-gate 
142*7c478bd9Sstevel@tonic-gate static uint_t
scsa1394_bus_get_node_id(void * hdl)143*7c478bd9Sstevel@tonic-gate scsa1394_bus_get_node_id(void *hdl)
144*7c478bd9Sstevel@tonic-gate {
145*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t *sp = hdl;
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate 	return (sp->s_attachinfo.localinfo.local_nodeID);
148*7c478bd9Sstevel@tonic-gate }
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate 
151*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
152*7c478bd9Sstevel@tonic-gate static int
scsa1394_bus_alloc_cmd(void * hdl,void ** cmdp,int flags)153*7c478bd9Sstevel@tonic-gate scsa1394_bus_alloc_cmd(void *hdl, void **cmdp, int flags)
154*7c478bd9Sstevel@tonic-gate {
155*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t *sp = hdl;
156*7c478bd9Sstevel@tonic-gate 	cmd1394_cmd_t	*cmd;
157*7c478bd9Sstevel@tonic-gate 
158*7c478bd9Sstevel@tonic-gate 	if (SCSA1394_BUS_FI_POSITIVE(scsa1394_bus_fi_prob_alloc_cmd)) {
159*7c478bd9Sstevel@tonic-gate 		return (SBP2_ENOMEM);
160*7c478bd9Sstevel@tonic-gate 	}
161*7c478bd9Sstevel@tonic-gate 
162*7c478bd9Sstevel@tonic-gate 	if (t1394_alloc_cmd(sp->s_t1394_hdl, 0, &cmd) != DDI_SUCCESS) {
163*7c478bd9Sstevel@tonic-gate 		return (SBP2_ENOMEM);
164*7c478bd9Sstevel@tonic-gate 	}
165*7c478bd9Sstevel@tonic-gate 	*cmdp = cmd;
166*7c478bd9Sstevel@tonic-gate 	return (SBP2_SUCCESS);
167*7c478bd9Sstevel@tonic-gate }
168*7c478bd9Sstevel@tonic-gate 
169*7c478bd9Sstevel@tonic-gate 
170*7c478bd9Sstevel@tonic-gate static void
scsa1394_bus_free_cmd(void * hdl,void * argcmd)171*7c478bd9Sstevel@tonic-gate scsa1394_bus_free_cmd(void *hdl, void *argcmd)
172*7c478bd9Sstevel@tonic-gate {
173*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t *sp = hdl;
174*7c478bd9Sstevel@tonic-gate 	cmd1394_cmd_t	*cmd = argcmd;
175*7c478bd9Sstevel@tonic-gate 
176*7c478bd9Sstevel@tonic-gate 	(void) t1394_free_cmd(sp->s_t1394_hdl, 0, &cmd);
177*7c478bd9Sstevel@tonic-gate }
178*7c478bd9Sstevel@tonic-gate 
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
181*7c478bd9Sstevel@tonic-gate static int
scsa1394_bus_rq(void * hdl,void * argcmd,uint64_t addr,uint32_t * q,int * berr)182*7c478bd9Sstevel@tonic-gate scsa1394_bus_rq(void *hdl, void *argcmd, uint64_t addr, uint32_t *q, int *berr)
183*7c478bd9Sstevel@tonic-gate {
184*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t *sp = hdl;
185*7c478bd9Sstevel@tonic-gate 	cmd1394_cmd_t	*cmd = argcmd;
186*7c478bd9Sstevel@tonic-gate 
187*7c478bd9Sstevel@tonic-gate 	if (SCSA1394_BUS_FI_POSITIVE(scsa1394_bus_fi_prob_rq)) {
188*7c478bd9Sstevel@tonic-gate 		return (SBP2_EIO);
189*7c478bd9Sstevel@tonic-gate 	}
190*7c478bd9Sstevel@tonic-gate 
191*7c478bd9Sstevel@tonic-gate 	cmd->cmd_addr = addr;
192*7c478bd9Sstevel@tonic-gate 	cmd->cmd_type = CMD1394_ASYNCH_RD_QUAD;
193*7c478bd9Sstevel@tonic-gate 	cmd->cmd_options = CMD1394_BLOCKING;
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate 	if ((t1394_read(sp->s_t1394_hdl, cmd) != DDI_SUCCESS) ||
196*7c478bd9Sstevel@tonic-gate 	    (cmd->cmd_result != CMD1394_CMDSUCCESS)) {
197*7c478bd9Sstevel@tonic-gate 		*berr = cmd->cmd_result;
198*7c478bd9Sstevel@tonic-gate 		return (scsa1394_bus_rw_result2code(cmd->cmd_result));
199*7c478bd9Sstevel@tonic-gate 	}
200*7c478bd9Sstevel@tonic-gate 
201*7c478bd9Sstevel@tonic-gate 	*q = cmd->cmd_u.q.quadlet_data;
202*7c478bd9Sstevel@tonic-gate 	return (SBP2_SUCCESS);
203*7c478bd9Sstevel@tonic-gate }
204*7c478bd9Sstevel@tonic-gate 
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
207*7c478bd9Sstevel@tonic-gate static int
scsa1394_bus_rb(void * hdl,void * argcmd,uint64_t addr,mblk_t ** bpp,int len,int * berr)208*7c478bd9Sstevel@tonic-gate scsa1394_bus_rb(void *hdl, void *argcmd, uint64_t addr, mblk_t **bpp, int len,
209*7c478bd9Sstevel@tonic-gate     int *berr)
210*7c478bd9Sstevel@tonic-gate {
211*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t *sp = hdl;
212*7c478bd9Sstevel@tonic-gate 	cmd1394_cmd_t	*cmd = argcmd;
213*7c478bd9Sstevel@tonic-gate 	mblk_t		*bp = *bpp;
214*7c478bd9Sstevel@tonic-gate 
215*7c478bd9Sstevel@tonic-gate 	/* caller wants us to allocate memory */
216*7c478bd9Sstevel@tonic-gate 	if ((bp == NULL) && ((bp = allocb(len, BPRI_HI)) == NULL)) {
217*7c478bd9Sstevel@tonic-gate 		return (SBP2_ENOMEM);
218*7c478bd9Sstevel@tonic-gate 	}
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate 	cmd->cmd_addr = addr;
221*7c478bd9Sstevel@tonic-gate 	cmd->cmd_type = CMD1394_ASYNCH_RD_BLOCK;
222*7c478bd9Sstevel@tonic-gate 	cmd->cmd_u.b.data_block = bp;
223*7c478bd9Sstevel@tonic-gate 	cmd->cmd_u.b.blk_length = len;
224*7c478bd9Sstevel@tonic-gate 	cmd->cmd_options = CMD1394_BLOCKING;
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate 	if ((t1394_read(sp->s_t1394_hdl, cmd) != DDI_SUCCESS) ||
227*7c478bd9Sstevel@tonic-gate 	    (cmd->cmd_result != CMD1394_CMDSUCCESS)) {
228*7c478bd9Sstevel@tonic-gate 		freeb(bp);
229*7c478bd9Sstevel@tonic-gate 		*berr = cmd->cmd_result;
230*7c478bd9Sstevel@tonic-gate 		return (scsa1394_bus_rw_result2code(cmd->cmd_result));
231*7c478bd9Sstevel@tonic-gate 	}
232*7c478bd9Sstevel@tonic-gate 
233*7c478bd9Sstevel@tonic-gate 	*bpp = bp;
234*7c478bd9Sstevel@tonic-gate 	return (SBP2_SUCCESS);
235*7c478bd9Sstevel@tonic-gate }
236*7c478bd9Sstevel@tonic-gate 
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
239*7c478bd9Sstevel@tonic-gate static int
scsa1394_bus_wq(void * hdl,void * argcmd,uint64_t addr,uint32_t q,int * berr)240*7c478bd9Sstevel@tonic-gate scsa1394_bus_wq(void *hdl, void *argcmd, uint64_t addr, uint32_t q, int *berr)
241*7c478bd9Sstevel@tonic-gate {
242*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t *sp = hdl;
243*7c478bd9Sstevel@tonic-gate 	cmd1394_cmd_t	*cmd = argcmd;
244*7c478bd9Sstevel@tonic-gate 
245*7c478bd9Sstevel@tonic-gate 	cmd->cmd_addr = addr;
246*7c478bd9Sstevel@tonic-gate 	cmd->cmd_type = CMD1394_ASYNCH_WR_QUAD;
247*7c478bd9Sstevel@tonic-gate 	cmd->cmd_u.q.quadlet_data = q;
248*7c478bd9Sstevel@tonic-gate 	cmd->cmd_options = CMD1394_BLOCKING;
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate 	if ((t1394_write(sp->s_t1394_hdl, cmd) != DDI_SUCCESS) ||
251*7c478bd9Sstevel@tonic-gate 	    (cmd->cmd_result != CMD1394_CMDSUCCESS)) {
252*7c478bd9Sstevel@tonic-gate 		*berr = cmd->cmd_result;
253*7c478bd9Sstevel@tonic-gate 		return (scsa1394_bus_rw_result2code(cmd->cmd_result));
254*7c478bd9Sstevel@tonic-gate 	}
255*7c478bd9Sstevel@tonic-gate 
256*7c478bd9Sstevel@tonic-gate 	return (SBP2_SUCCESS);
257*7c478bd9Sstevel@tonic-gate }
258*7c478bd9Sstevel@tonic-gate 
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
261*7c478bd9Sstevel@tonic-gate static int
scsa1394_bus_wb(void * hdl,void * argcmd,uint64_t addr,mblk_t * bp,int len,int * berr)262*7c478bd9Sstevel@tonic-gate scsa1394_bus_wb(void *hdl, void *argcmd, uint64_t addr, mblk_t *bp, int len,
263*7c478bd9Sstevel@tonic-gate     int *berr)
264*7c478bd9Sstevel@tonic-gate {
265*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t *sp = hdl;
266*7c478bd9Sstevel@tonic-gate 	cmd1394_cmd_t	*cmd = argcmd;
267*7c478bd9Sstevel@tonic-gate 
268*7c478bd9Sstevel@tonic-gate 	cmd->cmd_addr = addr;
269*7c478bd9Sstevel@tonic-gate 	cmd->cmd_type = CMD1394_ASYNCH_WR_BLOCK;
270*7c478bd9Sstevel@tonic-gate 	cmd->cmd_u.b.data_block = bp;
271*7c478bd9Sstevel@tonic-gate 	cmd->cmd_u.b.blk_length = len;
272*7c478bd9Sstevel@tonic-gate 	cmd->cmd_options = CMD1394_BLOCKING;
273*7c478bd9Sstevel@tonic-gate 
274*7c478bd9Sstevel@tonic-gate 	if ((t1394_write(sp->s_t1394_hdl, cmd) != DDI_SUCCESS) ||
275*7c478bd9Sstevel@tonic-gate 	    (cmd->cmd_result != CMD1394_CMDSUCCESS)) {
276*7c478bd9Sstevel@tonic-gate 		*berr = cmd->cmd_result;
277*7c478bd9Sstevel@tonic-gate 		return (scsa1394_bus_rw_result2code(cmd->cmd_result));
278*7c478bd9Sstevel@tonic-gate 	}
279*7c478bd9Sstevel@tonic-gate 
280*7c478bd9Sstevel@tonic-gate 	return (SBP2_SUCCESS);
281*7c478bd9Sstevel@tonic-gate }
282*7c478bd9Sstevel@tonic-gate 
283*7c478bd9Sstevel@tonic-gate 
284*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
285*7c478bd9Sstevel@tonic-gate static int
scsa1394_bus_alloc_buf(void * hdl,sbp2_bus_buf_t * buf)286*7c478bd9Sstevel@tonic-gate scsa1394_bus_alloc_buf(void *hdl, sbp2_bus_buf_t *buf)
287*7c478bd9Sstevel@tonic-gate {
288*7c478bd9Sstevel@tonic-gate 	if (SCSA1394_BUS_FI_POSITIVE(scsa1394_bus_fi_prob_alloc_buf)) {
289*7c478bd9Sstevel@tonic-gate 		return (SBP2_ENOMEM);
290*7c478bd9Sstevel@tonic-gate 	}
291*7c478bd9Sstevel@tonic-gate 
292*7c478bd9Sstevel@tonic-gate 	if (buf->bb_flags & SBP2_BUS_BUF_DMA) {
293*7c478bd9Sstevel@tonic-gate 		return (scsa1394_bus_alloc_buf_phys(hdl, buf));
294*7c478bd9Sstevel@tonic-gate 	} else {
295*7c478bd9Sstevel@tonic-gate 		return (scsa1394_bus_alloc_buf_normal(hdl, buf,
296*7c478bd9Sstevel@tonic-gate 		    ((buf->bb_flags & SBP2_BUS_BUF_POSTED) != 0)));
297*7c478bd9Sstevel@tonic-gate 	}
298*7c478bd9Sstevel@tonic-gate }
299*7c478bd9Sstevel@tonic-gate 
300*7c478bd9Sstevel@tonic-gate 
301*7c478bd9Sstevel@tonic-gate static void
scsa1394_bus_free_buf(void * hdl,sbp2_bus_buf_t * buf)302*7c478bd9Sstevel@tonic-gate scsa1394_bus_free_buf(void *hdl, sbp2_bus_buf_t *buf)
303*7c478bd9Sstevel@tonic-gate {
304*7c478bd9Sstevel@tonic-gate 	if (buf->bb_flags & SBP2_BUS_BUF_DMA) {
305*7c478bd9Sstevel@tonic-gate 		scsa1394_bus_free_buf_phys(hdl, buf);
306*7c478bd9Sstevel@tonic-gate 	} else {
307*7c478bd9Sstevel@tonic-gate 		scsa1394_bus_free_buf_normal(hdl, buf);
308*7c478bd9Sstevel@tonic-gate 	}
309*7c478bd9Sstevel@tonic-gate }
310*7c478bd9Sstevel@tonic-gate 
311*7c478bd9Sstevel@tonic-gate 
312*7c478bd9Sstevel@tonic-gate static int
scsa1394_bus_alloc_buf_phys(void * hdl,sbp2_bus_buf_t * buf)313*7c478bd9Sstevel@tonic-gate scsa1394_bus_alloc_buf_phys(void *hdl, sbp2_bus_buf_t *buf)
314*7c478bd9Sstevel@tonic-gate {
315*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t	*sp = hdl;
316*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_buf_t	*sbb;		/* bus private structure */
317*7c478bd9Sstevel@tonic-gate 	size_t			real_length;	/* real allocated length */
318*7c478bd9Sstevel@tonic-gate 	ddi_dma_cookie_t	cookie;		/* cookies */
319*7c478bd9Sstevel@tonic-gate 	uint_t			ccount;		/* cookie count */
320*7c478bd9Sstevel@tonic-gate 	t1394_alloc_addr_t	aa;
321*7c478bd9Sstevel@tonic-gate 	int			result;
322*7c478bd9Sstevel@tonic-gate 
323*7c478bd9Sstevel@tonic-gate 	/* allocate bus private structure */
324*7c478bd9Sstevel@tonic-gate 	sbb = kmem_zalloc(sizeof (scsa1394_bus_buf_t), KM_SLEEP);
325*7c478bd9Sstevel@tonic-gate 	sbb->sbb_state = sp;
326*7c478bd9Sstevel@tonic-gate 
327*7c478bd9Sstevel@tonic-gate 	/* allocate DMA resources */
328*7c478bd9Sstevel@tonic-gate 	if (ddi_dma_alloc_handle(sp->s_dip, &sp->s_attachinfo.dma_attr,
329*7c478bd9Sstevel@tonic-gate 	    DDI_DMA_SLEEP, NULL, &sbb->sbb_dma_hdl) != DDI_SUCCESS) {
330*7c478bd9Sstevel@tonic-gate 		kmem_free(sbb, sizeof (scsa1394_bus_buf_t));
331*7c478bd9Sstevel@tonic-gate 		return (SBP2_ENOMEM);
332*7c478bd9Sstevel@tonic-gate 	}
333*7c478bd9Sstevel@tonic-gate 
334*7c478bd9Sstevel@tonic-gate 	if (ddi_dma_mem_alloc(sbb->sbb_dma_hdl, buf->bb_len,
335*7c478bd9Sstevel@tonic-gate 	    &sp->s_attachinfo.acc_attr,
336*7c478bd9Sstevel@tonic-gate 	    buf->bb_flags & (DDI_DMA_STREAMING | DDI_DMA_CONSISTENT),
337*7c478bd9Sstevel@tonic-gate 	    DDI_DMA_SLEEP, NULL, &buf->bb_kaddr, &real_length,
338*7c478bd9Sstevel@tonic-gate 	    &sbb->sbb_acc_hdl) != DDI_SUCCESS) {
339*7c478bd9Sstevel@tonic-gate 		ddi_dma_free_handle(&sbb->sbb_dma_hdl);
340*7c478bd9Sstevel@tonic-gate 		kmem_free(sbb, sizeof (scsa1394_bus_buf_t));
341*7c478bd9Sstevel@tonic-gate 		return (SBP2_ENOMEM);
342*7c478bd9Sstevel@tonic-gate 	}
343*7c478bd9Sstevel@tonic-gate 
344*7c478bd9Sstevel@tonic-gate 	buf->bb_flags &= ~DDI_DMA_PARTIAL;
345*7c478bd9Sstevel@tonic-gate 	if (ddi_dma_addr_bind_handle(sbb->sbb_dma_hdl, NULL, buf->bb_kaddr,
346*7c478bd9Sstevel@tonic-gate 	    buf->bb_len, buf->bb_flags, DDI_DMA_SLEEP, NULL,
347*7c478bd9Sstevel@tonic-gate 	    &cookie, &ccount) != DDI_DMA_MAPPED) {
348*7c478bd9Sstevel@tonic-gate 		ddi_dma_mem_free(&sbb->sbb_acc_hdl);
349*7c478bd9Sstevel@tonic-gate 		ddi_dma_free_handle(&sbb->sbb_dma_hdl);
350*7c478bd9Sstevel@tonic-gate 		kmem_free(sbb, sizeof (scsa1394_bus_buf_t));
351*7c478bd9Sstevel@tonic-gate 		return (SBP2_ENOMEM);
352*7c478bd9Sstevel@tonic-gate 	}
353*7c478bd9Sstevel@tonic-gate 	ASSERT(ccount == 1);
354*7c478bd9Sstevel@tonic-gate 	buf->bb_paddr = cookie.dmac_address;	/* 32-bit address */
355*7c478bd9Sstevel@tonic-gate 
356*7c478bd9Sstevel@tonic-gate 	/* allocate 1394 resources */
357*7c478bd9Sstevel@tonic-gate 	bzero(&aa, sizeof (aa));
358*7c478bd9Sstevel@tonic-gate 	aa.aa_type = T1394_ADDR_FIXED;
359*7c478bd9Sstevel@tonic-gate 	aa.aa_length = buf->bb_len;
360*7c478bd9Sstevel@tonic-gate 	if (buf->bb_flags & SBP2_BUS_BUF_RD) {
361*7c478bd9Sstevel@tonic-gate 		aa.aa_enable |= T1394_ADDR_RDENBL;
362*7c478bd9Sstevel@tonic-gate 	}
363*7c478bd9Sstevel@tonic-gate 	if (buf->bb_flags & SBP2_BUS_BUF_WR) {
364*7c478bd9Sstevel@tonic-gate 		aa.aa_enable |= T1394_ADDR_WRENBL;
365*7c478bd9Sstevel@tonic-gate 	}
366*7c478bd9Sstevel@tonic-gate 	aa.aa_address = buf->bb_paddr;		/* PCI-1394 mapping is 1-1 */
367*7c478bd9Sstevel@tonic-gate 
368*7c478bd9Sstevel@tonic-gate 	if (t1394_alloc_addr(sp->s_t1394_hdl, &aa, 0, &result) != DDI_SUCCESS) {
369*7c478bd9Sstevel@tonic-gate 		(void) ddi_dma_unbind_handle(sbb->sbb_dma_hdl);
370*7c478bd9Sstevel@tonic-gate 		ddi_dma_mem_free(&sbb->sbb_acc_hdl);
371*7c478bd9Sstevel@tonic-gate 		ddi_dma_free_handle(&sbb->sbb_dma_hdl);
372*7c478bd9Sstevel@tonic-gate 		kmem_free(sbb, sizeof (scsa1394_bus_buf_t));
373*7c478bd9Sstevel@tonic-gate 		return (SBP2_ENOMEM);
374*7c478bd9Sstevel@tonic-gate 	}
375*7c478bd9Sstevel@tonic-gate 	sbb->sbb_addr_hdl = aa.aa_hdl;
376*7c478bd9Sstevel@tonic-gate 	buf->bb_baddr = aa.aa_address;
377*7c478bd9Sstevel@tonic-gate 
378*7c478bd9Sstevel@tonic-gate 	buf->bb_hdl = sbb;
379*7c478bd9Sstevel@tonic-gate 	return (SBP2_SUCCESS);
380*7c478bd9Sstevel@tonic-gate }
381*7c478bd9Sstevel@tonic-gate 
382*7c478bd9Sstevel@tonic-gate 
383*7c478bd9Sstevel@tonic-gate static void
scsa1394_bus_free_buf_phys(void * hdl,sbp2_bus_buf_t * buf)384*7c478bd9Sstevel@tonic-gate scsa1394_bus_free_buf_phys(void *hdl, sbp2_bus_buf_t *buf)
385*7c478bd9Sstevel@tonic-gate {
386*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t	*sp = hdl;
387*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_buf_t	*sbb = buf->bb_hdl;
388*7c478bd9Sstevel@tonic-gate 
389*7c478bd9Sstevel@tonic-gate 	(void) t1394_free_addr(sp->s_t1394_hdl, &sbb->sbb_addr_hdl, 0);
390*7c478bd9Sstevel@tonic-gate 	(void) ddi_dma_unbind_handle(sbb->sbb_dma_hdl);
391*7c478bd9Sstevel@tonic-gate 	ddi_dma_mem_free(&sbb->sbb_acc_hdl);
392*7c478bd9Sstevel@tonic-gate 	ddi_dma_free_handle(&sbb->sbb_dma_hdl);
393*7c478bd9Sstevel@tonic-gate 	kmem_free(sbb, sizeof (scsa1394_bus_buf_t));
394*7c478bd9Sstevel@tonic-gate 	buf->bb_hdl = NULL;
395*7c478bd9Sstevel@tonic-gate }
396*7c478bd9Sstevel@tonic-gate 
397*7c478bd9Sstevel@tonic-gate 
398*7c478bd9Sstevel@tonic-gate static int
scsa1394_bus_alloc_buf_normal(void * hdl,sbp2_bus_buf_t * buf,boolean_t posted)399*7c478bd9Sstevel@tonic-gate scsa1394_bus_alloc_buf_normal(void *hdl, sbp2_bus_buf_t *buf, boolean_t posted)
400*7c478bd9Sstevel@tonic-gate {
401*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t 	*sp = hdl;
402*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_buf_t	*sbb;		/* bus private structure */
403*7c478bd9Sstevel@tonic-gate 	t1394_alloc_addr_t	aa;
404*7c478bd9Sstevel@tonic-gate 	int			result;
405*7c478bd9Sstevel@tonic-gate 
406*7c478bd9Sstevel@tonic-gate 	/* allocate bus private structure */
407*7c478bd9Sstevel@tonic-gate 	sbb = kmem_zalloc(sizeof (scsa1394_bus_buf_t), KM_SLEEP);
408*7c478bd9Sstevel@tonic-gate 	sbb->sbb_state = sp;
409*7c478bd9Sstevel@tonic-gate 
410*7c478bd9Sstevel@tonic-gate 	/* allocate 1394 resources */
411*7c478bd9Sstevel@tonic-gate 	bzero(&aa, sizeof (aa));
412*7c478bd9Sstevel@tonic-gate 	aa.aa_type = posted ? T1394_ADDR_POSTED_WRITE : T1394_ADDR_NORMAL;
413*7c478bd9Sstevel@tonic-gate 	aa.aa_length = buf->bb_len;
414*7c478bd9Sstevel@tonic-gate 	if (buf->bb_flags & SBP2_BUS_BUF_RD) {
415*7c478bd9Sstevel@tonic-gate 		aa.aa_enable |= T1394_ADDR_RDENBL;
416*7c478bd9Sstevel@tonic-gate 		aa.aa_evts.recv_read_request = scsa1394_bus_recv_read_request;
417*7c478bd9Sstevel@tonic-gate 	}
418*7c478bd9Sstevel@tonic-gate 	if (buf->bb_flags & SBP2_BUS_BUF_WR) {
419*7c478bd9Sstevel@tonic-gate 		aa.aa_enable |= T1394_ADDR_WRENBL;
420*7c478bd9Sstevel@tonic-gate 		aa.aa_evts.recv_write_request = scsa1394_bus_recv_write_request;
421*7c478bd9Sstevel@tonic-gate 	}
422*7c478bd9Sstevel@tonic-gate 	aa.aa_arg = buf;
423*7c478bd9Sstevel@tonic-gate 
424*7c478bd9Sstevel@tonic-gate 	if (t1394_alloc_addr(sp->s_t1394_hdl, &aa, 0, &result) != DDI_SUCCESS) {
425*7c478bd9Sstevel@tonic-gate 		kmem_free(sbb, sizeof (scsa1394_bus_buf_t));
426*7c478bd9Sstevel@tonic-gate 		return (SBP2_ENOMEM);
427*7c478bd9Sstevel@tonic-gate 	}
428*7c478bd9Sstevel@tonic-gate 	sbb->sbb_addr_hdl = aa.aa_hdl;
429*7c478bd9Sstevel@tonic-gate 	buf->bb_baddr = aa.aa_address;
430*7c478bd9Sstevel@tonic-gate 
431*7c478bd9Sstevel@tonic-gate 	buf->bb_hdl = sbb;
432*7c478bd9Sstevel@tonic-gate 	return (SBP2_SUCCESS);
433*7c478bd9Sstevel@tonic-gate }
434*7c478bd9Sstevel@tonic-gate 
435*7c478bd9Sstevel@tonic-gate static void
scsa1394_bus_free_buf_normal(void * hdl,sbp2_bus_buf_t * buf)436*7c478bd9Sstevel@tonic-gate scsa1394_bus_free_buf_normal(void *hdl, sbp2_bus_buf_t *buf)
437*7c478bd9Sstevel@tonic-gate {
438*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t 	*sp = hdl;
439*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_buf_t	*sbb = buf->bb_hdl;
440*7c478bd9Sstevel@tonic-gate 
441*7c478bd9Sstevel@tonic-gate 	(void) t1394_free_addr(sp->s_t1394_hdl, &sbb->sbb_addr_hdl, 0);
442*7c478bd9Sstevel@tonic-gate 	kmem_free(sbb, sizeof (scsa1394_bus_buf_t));
443*7c478bd9Sstevel@tonic-gate 	buf->bb_hdl = NULL;
444*7c478bd9Sstevel@tonic-gate }
445*7c478bd9Sstevel@tonic-gate 
446*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
447*7c478bd9Sstevel@tonic-gate static int
scsa1394_bus_sync_buf(void * hdl,sbp2_bus_buf_t * buf,off_t offset,size_t length,int type)448*7c478bd9Sstevel@tonic-gate scsa1394_bus_sync_buf(void *hdl, sbp2_bus_buf_t *buf, off_t offset,
449*7c478bd9Sstevel@tonic-gate     size_t length, int type)
450*7c478bd9Sstevel@tonic-gate {
451*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_buf_t	*sbb = buf->bb_hdl;
452*7c478bd9Sstevel@tonic-gate 
453*7c478bd9Sstevel@tonic-gate 	if (buf->bb_flags & SBP2_BUS_BUF_DMA) {
454*7c478bd9Sstevel@tonic-gate 		return (ddi_dma_sync(sbb->sbb_dma_hdl, offset, length, type));
455*7c478bd9Sstevel@tonic-gate 	} else {
456*7c478bd9Sstevel@tonic-gate 		return (SBP2_SUCCESS);
457*7c478bd9Sstevel@tonic-gate 	}
458*7c478bd9Sstevel@tonic-gate }
459*7c478bd9Sstevel@tonic-gate 
460*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
461*7c478bd9Sstevel@tonic-gate static void
scsa1394_bus_buf_rw_done(void * hdl,sbp2_bus_buf_t * buf,void * reqh,int error)462*7c478bd9Sstevel@tonic-gate scsa1394_bus_buf_rw_done(void *hdl, sbp2_bus_buf_t *buf, void *reqh, int error)
463*7c478bd9Sstevel@tonic-gate {
464*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t	*sp = hdl;
465*7c478bd9Sstevel@tonic-gate 	cmd1394_cmd_t		*req = reqh;
466*7c478bd9Sstevel@tonic-gate 
467*7c478bd9Sstevel@tonic-gate 	/* complete request */
468*7c478bd9Sstevel@tonic-gate 	switch (error) {
469*7c478bd9Sstevel@tonic-gate 	case SBP2_BUS_BUF_SUCCESS:
470*7c478bd9Sstevel@tonic-gate 		req->cmd_result = IEEE1394_RESP_COMPLETE;
471*7c478bd9Sstevel@tonic-gate 		break;
472*7c478bd9Sstevel@tonic-gate 	case SBP2_BUS_BUF_ELENGTH:
473*7c478bd9Sstevel@tonic-gate 		req->cmd_result = IEEE1394_RESP_DATA_ERROR;
474*7c478bd9Sstevel@tonic-gate 		break;
475*7c478bd9Sstevel@tonic-gate 	case SBP2_BUS_BUF_EBUSY:
476*7c478bd9Sstevel@tonic-gate 		req->cmd_result = IEEE1394_RESP_CONFLICT_ERROR;
477*7c478bd9Sstevel@tonic-gate 		break;
478*7c478bd9Sstevel@tonic-gate 	default:
479*7c478bd9Sstevel@tonic-gate 		req->cmd_result = IEEE1394_RESP_TYPE_ERROR;
480*7c478bd9Sstevel@tonic-gate 	}
481*7c478bd9Sstevel@tonic-gate 	(void) t1394_recv_request_done(sp->s_t1394_hdl, req, 0);
482*7c478bd9Sstevel@tonic-gate }
483*7c478bd9Sstevel@tonic-gate 
484*7c478bd9Sstevel@tonic-gate 
485*7c478bd9Sstevel@tonic-gate /*
486*7c478bd9Sstevel@tonic-gate  *
487*7c478bd9Sstevel@tonic-gate  * --- callbacks
488*7c478bd9Sstevel@tonic-gate  *
489*7c478bd9Sstevel@tonic-gate  */
490*7c478bd9Sstevel@tonic-gate static void
scsa1394_bus_recv_read_request(cmd1394_cmd_t * req)491*7c478bd9Sstevel@tonic-gate scsa1394_bus_recv_read_request(cmd1394_cmd_t *req)
492*7c478bd9Sstevel@tonic-gate {
493*7c478bd9Sstevel@tonic-gate 	sbp2_bus_buf_t		*buf = req->cmd_callback_arg;
494*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_buf_t	*sbb = buf->bb_hdl;
495*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t	*sp = sbb->sbb_state;
496*7c478bd9Sstevel@tonic-gate 
497*7c478bd9Sstevel@tonic-gate 	/* XXX sanity checks: addr, etc */
498*7c478bd9Sstevel@tonic-gate 	if (req->cmd_type == CMD1394_ASYNCH_RD_QUAD) {
499*7c478bd9Sstevel@tonic-gate 		if (buf->bb_rq_cb) {
500*7c478bd9Sstevel@tonic-gate 			buf->bb_rq_cb(buf, req, &req->cmd_u.q.quadlet_data);
501*7c478bd9Sstevel@tonic-gate 			return;
502*7c478bd9Sstevel@tonic-gate 		}
503*7c478bd9Sstevel@tonic-gate 	} else {
504*7c478bd9Sstevel@tonic-gate 		if (buf->bb_rb_cb) {
505*7c478bd9Sstevel@tonic-gate 			buf->bb_rb_cb(buf, req, &req->cmd_u.b.data_block,
506*7c478bd9Sstevel@tonic-gate 			    req->cmd_u.b.blk_length);
507*7c478bd9Sstevel@tonic-gate 			return;
508*7c478bd9Sstevel@tonic-gate 		}
509*7c478bd9Sstevel@tonic-gate 	}
510*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_buf_rw_done(sp, buf, req, SBP2_BUS_BUF_FAILURE);
511*7c478bd9Sstevel@tonic-gate }
512*7c478bd9Sstevel@tonic-gate 
513*7c478bd9Sstevel@tonic-gate 
514*7c478bd9Sstevel@tonic-gate static void
scsa1394_bus_recv_write_request(cmd1394_cmd_t * req)515*7c478bd9Sstevel@tonic-gate scsa1394_bus_recv_write_request(cmd1394_cmd_t *req)
516*7c478bd9Sstevel@tonic-gate {
517*7c478bd9Sstevel@tonic-gate 	sbp2_bus_buf_t		*buf = req->cmd_callback_arg;
518*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_buf_t	*sbb = buf->bb_hdl;
519*7c478bd9Sstevel@tonic-gate 	scsa1394_state_t	*sp = sbb->sbb_state;
520*7c478bd9Sstevel@tonic-gate 
521*7c478bd9Sstevel@tonic-gate 	/* XXX sanity checks: addr, etc */
522*7c478bd9Sstevel@tonic-gate 	if (req->cmd_type == CMD1394_ASYNCH_WR_QUAD) {
523*7c478bd9Sstevel@tonic-gate 		if (buf->bb_wq_cb) {
524*7c478bd9Sstevel@tonic-gate 			buf->bb_wq_cb(buf, req, req->cmd_u.q.quadlet_data);
525*7c478bd9Sstevel@tonic-gate 			return;
526*7c478bd9Sstevel@tonic-gate 		}
527*7c478bd9Sstevel@tonic-gate 	} else {
528*7c478bd9Sstevel@tonic-gate 		if (buf->bb_wb_cb) {
529*7c478bd9Sstevel@tonic-gate 			buf->bb_wb_cb(buf, req, &req->cmd_u.b.data_block);
530*7c478bd9Sstevel@tonic-gate 			return;
531*7c478bd9Sstevel@tonic-gate 		}
532*7c478bd9Sstevel@tonic-gate 	}
533*7c478bd9Sstevel@tonic-gate 	scsa1394_bus_buf_rw_done(sp, buf, req, SBP2_BUS_BUF_FAILURE);
534*7c478bd9Sstevel@tonic-gate }
535