1*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
2*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Use is subject to license terms.
4*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
5*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
6*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
7*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Copyright (c) 2007 by Lukas Turek <turek@ksvi.mff.cuni.cz>
8*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Copyright (c) 2007 by Jiri Svoboda <jirik.svoboda@seznam.cz>
9*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Copyright (c) 2007 by Martin Krulis <martin.krulis@matfyz.cz>
10*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr>
11*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de>
12*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
13*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Permission to use, copy, modify, and distribute this software for any
14*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * purpose with or without fee is hereby granted, provided that the above
15*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * copyright notice and this permission notice appear in all copies.
16*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
17*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
18*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
19*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
20*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
22*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
23*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
25*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
26*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
27*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
28*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * ZD1211 wLAN driver
29*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * USB communication
30*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
31*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Manage USB communication with the ZD-based device.
32*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
33*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
34*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include <sys/byteorder.h>
35*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include <sys/stream.h>
36*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include <sys/strsun.h>
37*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include <sys/mac_provider.h>
38*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
39*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include "zyd.h"
40*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include "zyd_reg.h"
41*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
42*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int zyd_usb_disconnect(dev_info_t *dip);
43*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int zyd_usb_reconnect(dev_info_t *dip);
44*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static zyd_res zyd_usb_data_in_start_request(struct zyd_usb *uc);
45*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
46*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static zyd_usb_info_t usb_ids[] = {
47*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x53, 0x5301, ZYD_ZD1211B},
48*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x105, 0x145f, ZYD_ZD1211},
49*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x411, 0xda, ZYD_ZD1211B},
50*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x471, 0x1236, ZYD_ZD1211B},
51*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x471, 0x1237, ZYD_ZD1211B},
52*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x50d, 0x705c, ZYD_ZD1211B},
53*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x586, 0x3401, ZYD_ZD1211},
54*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x586, 0x3402, ZYD_ZD1211},
55*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x586, 0x3407, ZYD_ZD1211},
56*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x586, 0x3409, ZYD_ZD1211},
57*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x586, 0x3410, ZYD_ZD1211B},
58*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x586, 0x3412, ZYD_ZD1211B},
59*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x586, 0x3413, ZYD_ZD1211B},
60*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x586, 0x340a, ZYD_ZD1211B},
61*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x586, 0x340f, ZYD_ZD1211B},
62*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x79b, 0x4a, ZYD_ZD1211},
63*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x79b, 0x62, ZYD_ZD1211B},
64*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x7b8, 0x6001, ZYD_ZD1211},
65*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x83a, 0x4505, ZYD_ZD1211B},
66*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0xace, 0x1211, ZYD_ZD1211},
67*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0xace, 0x1215, ZYD_ZD1211B},
68*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0xb05, 0x170c, ZYD_ZD1211},
69*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0xb05, 0x171b, ZYD_ZD1211B},
70*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0xb3b, 0x1630, ZYD_ZD1211},
71*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0xb3b, 0x5630, ZYD_ZD1211},
72*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0xbaf, 0x121, ZYD_ZD1211B},
73*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0xcde, 0x1a, ZYD_ZD1211B},
74*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0xdf6, 0x9071, ZYD_ZD1211},
75*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0xdf6, 0x9075, ZYD_ZD1211},
76*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x126f, 0xa006, ZYD_ZD1211},
77*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x129b, 0x1666, ZYD_ZD1211},
78*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x129b, 0x1667, ZYD_ZD1211B},
79*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x13b1, 0x1e, ZYD_ZD1211},
80*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x13b1, 0x24, ZYD_ZD1211B},
81*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x1435, 0x711, ZYD_ZD1211},
82*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x14ea, 0xab13, ZYD_ZD1211},
83*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x157e, 0x300b, ZYD_ZD1211},
84*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x157e, 0x300d, ZYD_ZD1211B},
85*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x157e, 0x3204, ZYD_ZD1211},
86*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x1582, 0x6003, ZYD_ZD1211B},
87*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x1740, 0x2000, ZYD_ZD1211},
88*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x2019, 0x5303, ZYD_ZD1211B},
89*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {0x6891, 0xa727, ZYD_ZD1211}
90*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China };
91*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
92*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
93*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Get mac rev for usb vendor/product id.
94*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
95*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_mac_rev_t
zyd_usb_mac_rev(uint16_t vendor,uint16_t product)96*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_mac_rev(uint16_t vendor, uint16_t product)
97*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
98*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int i;
99*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
100*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB, "matching device usb%x,%x\n", vendor, product));
101*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China for (i = 0; i < sizeof (usb_ids) / sizeof (zyd_usb_info_t); i++) {
102*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (vendor == usb_ids[i].vendor_id &&
103*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China product == usb_ids[i].product_id)
104*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (usb_ids[i].mac_rev);
105*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
106*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
107*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB, "assuming ZD1211B\n"));
108*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_ZD1211B);
109*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
110*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
111*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
112*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Vendor-specific write to the default control pipe.
113*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
114*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static zyd_res
zyd_usb_ctrl_send(struct zyd_usb * uc,uint8_t request,uint16_t value,uint8_t * data,uint16_t len)115*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_ctrl_send(struct zyd_usb *uc, uint8_t request, uint16_t value,
116*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint8_t *data, uint16_t len)
117*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
118*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int err;
119*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int retry = 0;
120*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk_t *msg;
121*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_ctrl_setup_t setup;
122*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
123*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Always clean structures before use */
124*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China bzero(&setup, sizeof (setup));
125*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China setup.bmRequestType =
126*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_HOST_TO_DEV;
127*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China setup.bRequest = request;
128*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China setup.wValue = value;
129*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China setup.wIndex = 0;
130*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China setup.wLength = len;
131*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China setup.attrs = USB_ATTRS_NONE;
132*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
133*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if ((msg = allocb(len, BPRI_HI)) == NULL)
134*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
135*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
136*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China bcopy(data, msg->b_wptr, len);
137*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China msg->b_wptr += len;
138*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
139*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China while ((err = usb_pipe_ctrl_xfer_wait(uc->cdata->dev_default_ph,
140*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China &setup, &msg, NULL, NULL, 0)) != USB_SUCCESS) {
141*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (retry++ > 3)
142*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break;
143*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
144*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
145*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China freemsg(msg);
146*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
147*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
148*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB,
149*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China "control pipe send failure (%d)\n", err));
150*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
151*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
152*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
153*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_SUCCESS);
154*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
155*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
156*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
157*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Vendor-specific read from the default control pipe.
158*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
159*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static zyd_res
zyd_usb_ctrl_recv(struct zyd_usb * uc,uint8_t request,uint16_t value,uint8_t * data,uint16_t len)160*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_ctrl_recv(struct zyd_usb *uc, uint8_t request, uint16_t value,
161*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint8_t *data, uint16_t len)
162*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
163*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int err;
164*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk_t *msg, *tmp_msg;
165*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_ctrl_setup_t setup;
166*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China size_t msg_len;
167*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
168*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(data != NULL);
169*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
170*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China bzero(&setup, sizeof (setup));
171*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China setup.bmRequestType =
172*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_DEV_TO_HOST;
173*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China setup.bRequest = request;
174*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China setup.wValue = value;
175*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China setup.wIndex = 0;
176*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China setup.wLength = len;
177*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China setup.attrs = USB_ATTRS_NONE;
178*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
179*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Pointer msg must be either set to NULL or point to a valid mblk! */
180*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China msg = NULL;
181*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China err = usb_pipe_ctrl_xfer_wait(uc->cdata->dev_default_ph,
182*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China &setup, &msg, NULL, NULL, 0);
183*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
184*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
185*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("control pipe receive failure (%d)\n", err);
186*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
187*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
188*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
189*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China msg_len = msgsize(msg);
190*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
191*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (msg_len != len) {
192*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("control pipe failure: "
193*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China "received %d bytes, %d expected\n", (int)msg_len, len);
194*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
195*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
196*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
197*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (msg->b_cont != NULL) {
198*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Fragmented message, concatenate */
199*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China tmp_msg = msgpullup(msg, -1);
200*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China freemsg(msg);
201*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China msg = tmp_msg;
202*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
203*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
204*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
205*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Now we can be sure the message is in a single block
206*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * so we can copy it.
207*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
208*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China bcopy(msg->b_rptr, data, len);
209*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China freemsg(msg);
210*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
211*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_SUCCESS);
212*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
213*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
214*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
215*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Load firmware into the chip.
216*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
217*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res
zyd_usb_loadfirmware(struct zyd_usb * uc,uint8_t * fw,size_t size)218*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_loadfirmware(struct zyd_usb *uc, uint8_t *fw, size_t size)
219*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
220*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint16_t addr;
221*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint8_t stat;
222*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
223*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_FW, "firmware size: %lu\n", size));
224*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
225*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China addr = ZYD_FIRMWARE_START_ADDR;
226*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China while (size > 0) {
227*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China const uint16_t mlen = (uint16_t)min(size, 4096);
228*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
229*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_usb_ctrl_send(uc, ZYD_DOWNLOADREQ, addr, fw, mlen)
230*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China != USB_SUCCESS)
231*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
232*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
233*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China addr += mlen / 2;
234*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China fw += mlen;
235*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China size -= mlen;
236*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
237*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
238*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* check whether the upload succeeded */
239*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_usb_ctrl_recv(uc, ZYD_DOWNLOADSTS, 0, &stat, sizeof (stat))
240*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China != ZYD_SUCCESS)
241*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
242*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
243*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return ((stat & 0x80) ? ZYD_FAILURE : ZYD_SUCCESS);
244*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
245*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
246*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
247*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Return a specific alt_if from the device descriptor tree.
248*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
249*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static usb_alt_if_data_t *
usb_lookup_alt_if(usb_client_dev_data_t * cdd,uint_t config,uint_t interface,uint_t alt)250*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_lookup_alt_if(usb_client_dev_data_t *cdd, uint_t config,
251*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint_t interface, uint_t alt)
252*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
253*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_cfg_data_t *dcfg;
254*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_if_data_t *cfgif;
255*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_alt_if_data_t *ifalt;
256*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
257*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
258*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Assume everything is in the tree for now,
259*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * (USB_PARSE_LVL_ALL)
260*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * so we can directly index the array.
261*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
262*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
263*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Descend to configuration, configs are 1-based */
264*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (config < 1 || config > cdd->dev_n_cfg)
265*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (NULL);
266*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China dcfg = &cdd->dev_cfg[config - 1];
267*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
268*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Descend to interface */
269*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (interface > dcfg->cfg_n_if - 1)
270*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (NULL);
271*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China cfgif = &dcfg->cfg_if[interface];
272*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
273*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Descend to alt */
274*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (alt > cfgif->if_n_alt - 1)
275*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (NULL);
276*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ifalt = &cfgif->if_alt[alt];
277*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
278*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ifalt);
279*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
280*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
281*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
282*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Print all endpoints of an alt_if.
283*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
284*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static void
usb_list_all_endpoints(usb_alt_if_data_t * ifalt)285*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_list_all_endpoints(usb_alt_if_data_t *ifalt)
286*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
287*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_ep_data_t *ep_data;
288*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_ep_descr_t *ep_descr;
289*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int i;
290*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
291*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China for (i = 0; i < ifalt->altif_n_ep; i++) {
292*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ep_data = &ifalt->altif_ep[i];
293*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ep_descr = &ep_data->ep_descr;
294*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China cmn_err(CE_NOTE, "EP: %u\n", ep_descr->bEndpointAddress);
295*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
296*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
297*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
298*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
299*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * For the given alt_if, find an endpoint with the given
300*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * address and direction.
301*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
302*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * ep_direction USB_EP_DIR_IN or USB_EP_DIR_OUT
303*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
304*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static usb_ep_data_t *
usb_find_endpoint(usb_alt_if_data_t * alt_if,uint_t ep_address,uint_t ep_direction)305*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_find_endpoint(usb_alt_if_data_t *alt_if,
306*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint_t ep_address, uint_t ep_direction)
307*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
308*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_ep_data_t *ep_data;
309*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_ep_descr_t *ep_descr;
310*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint_t ep_addr, ep_dir;
311*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int i;
312*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
313*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China for (i = 0; i < alt_if->altif_n_ep; i++) {
314*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ep_data = &alt_if->altif_ep[i];
315*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ep_descr = &ep_data->ep_descr;
316*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ep_addr = ep_descr->bEndpointAddress & USB_EP_NUM_MASK;
317*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ep_dir = ep_descr->bEndpointAddress & USB_EP_DIR_MASK;
318*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
319*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (ep_addr == ep_address && ep_dir == ep_direction) {
320*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ep_data);
321*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
322*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
323*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
324*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("no endpoint with addr %u, dir %u\n", ep_address,
325*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ep_direction);
326*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (NULL);
327*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
328*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
329*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China enum zyd_usb_use_attr
330*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
331*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_USB_USE_ATTR = 1,
332*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_USB_NO_ATTR = 0
333*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China };
334*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
335*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
336*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Open a pipe to a given endpoint address/direction in the given
337*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * alt_if. Furthemore, if use_attr == ZYD_USB_USE_ATTR,
338*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * check whether the endpoint's transfer type is attr.
339*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
340*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static zyd_res
zyd_usb_open_pipe(struct zyd_usb * uc,usb_alt_if_data_t * alt_if,uint_t ep_address,uint_t ep_direction,uint_t attr,enum zyd_usb_use_attr use_attr,usb_pipe_handle_t * pipe,usb_ep_data_t * endpoint)341*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_open_pipe(struct zyd_usb *uc,
342*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_alt_if_data_t *alt_if,
343*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint_t ep_address,
344*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint_t ep_direction,
345*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint_t attr,
346*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China enum zyd_usb_use_attr use_attr,
347*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_pipe_handle_t *pipe, usb_ep_data_t *endpoint)
348*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
349*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_pipe_policy_t pipe_policy;
350*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
351*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *endpoint = *usb_find_endpoint(alt_if, ep_address, ep_direction);
352*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
353*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if ((use_attr == ZYD_USB_USE_ATTR) &&
354*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (endpoint->ep_descr.bmAttributes & USB_EP_ATTR_MASK) != attr) {
355*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
356*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("endpoint %u/%s is not of type %s\n", ep_address,
357*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (ep_direction == USB_EP_DIR_IN) ? "IN" : "OUT",
358*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (attr == USB_EP_ATTR_BULK) ? "bulk" : "intr");
359*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
360*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
361*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
362*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China bzero(&pipe_policy, sizeof (usb_pipe_policy_t));
363*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China pipe_policy.pp_max_async_reqs = ZYD_USB_REQ_COUNT;
364*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
365*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (usb_pipe_open(uc->dip, &endpoint->ep_descr,
366*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China &pipe_policy, USB_FLAGS_SLEEP, pipe) != USB_SUCCESS) {
367*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to open pipe %u\n", ep_address);
368*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
369*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
370*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
371*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_SUCCESS);
372*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
373*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
374*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
375*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Open communication pipes.
376*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
377*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * The following pipes are used by the ZD1211:
378*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
379*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 1/OUT BULK
380*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 2/IN BULK
381*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 3/IN INTR
382*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 4/OUT BULK or INTR
383*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
384*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res
zyd_usb_open_pipes(struct zyd_usb * uc)385*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_open_pipes(struct zyd_usb *uc)
386*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
387*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_alt_if_data_t *alt_if;
388*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
389*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB, "opening pipes\n"));
390*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
391*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China alt_if = usb_lookup_alt_if(uc->cdata, ZYD_USB_CONFIG_NUMBER,
392*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_USB_IFACE_INDEX, ZYD_USB_ALT_IF_INDEX);
393*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
394*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (alt_if == NULL) {
395*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("alt_if not found\n");
396*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
397*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
398*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
399*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #ifdef DEBUG
400*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_dbg_flags & ZYD_DBG_USB)
401*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_list_all_endpoints(alt_if);
402*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #endif
403*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
404*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_usb_open_pipe(uc, alt_if, 1, USB_EP_DIR_OUT, USB_EP_ATTR_BULK,
405*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_USB_USE_ATTR, &uc->pipe_data_out, &uc->ep_data_out) !=
406*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_SUCCESS) {
407*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to open data OUT pipe\n");
408*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China goto fail;
409*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
410*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
411*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_usb_open_pipe(uc, alt_if, 2, USB_EP_DIR_IN, USB_EP_ATTR_BULK,
412*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_USB_USE_ATTR, &uc->pipe_data_in, &uc->ep_data_in) !=
413*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_SUCCESS) {
414*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to open data IN pipe\n");
415*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China goto fail;
416*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
417*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
418*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_usb_open_pipe(uc, alt_if, 3, USB_EP_DIR_IN, USB_EP_ATTR_INTR,
419*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_USB_USE_ATTR, &uc->pipe_cmd_in, &uc->ep_cmd_in) !=
420*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_SUCCESS) {
421*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to open command IN pipe\n");
422*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China goto fail;
423*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
424*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
425*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
426*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Pipe 4/OUT is either a bulk or interrupt pipe.
427*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
428*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_usb_open_pipe(uc, alt_if, 4, USB_EP_DIR_OUT, 0,
429*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_USB_NO_ATTR, &uc->pipe_cmd_out, &uc->ep_cmd_out) !=
430*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_SUCCESS) {
431*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to open command OUT pipe\n");
432*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China goto fail;
433*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
434*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
435*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_SUCCESS);
436*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
437*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China fail:
438*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_close_pipes(uc);
439*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
440*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
441*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
442*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
443*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Close communication pipes.
444*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
445*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China void
zyd_usb_close_pipes(struct zyd_usb * uc)446*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_close_pipes(struct zyd_usb *uc)
447*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
448*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB, "closing pipes\n"));
449*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
450*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (uc->pipe_data_out != NULL) {
451*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_pipe_close(uc->dip, uc->pipe_data_out, USB_FLAGS_SLEEP,
452*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China NULL, NULL);
453*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->pipe_data_out = NULL;
454*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
455*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
456*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (uc->pipe_data_in != NULL) {
457*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_pipe_close(uc->dip, uc->pipe_data_in, USB_FLAGS_SLEEP,
458*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China NULL, NULL);
459*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->pipe_data_in = NULL;
460*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
461*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
462*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (uc->pipe_cmd_in != NULL) {
463*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_pipe_close(uc->dip, uc->pipe_cmd_in, USB_FLAGS_SLEEP,
464*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China NULL, NULL);
465*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->pipe_cmd_in = NULL;
466*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
467*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
468*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (uc->pipe_cmd_out != NULL) {
469*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_pipe_close(uc->dip, uc->pipe_cmd_out, USB_FLAGS_SLEEP,
470*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China NULL, NULL);
471*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->pipe_cmd_out = NULL;
472*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
473*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
474*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
475*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
476*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Send a sequence of bytes to a bulk pipe.
477*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
478*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * uc pointer to usb module state
479*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * data pointer to a buffer of bytes
480*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * len size of the buffer (bytes)
481*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
482*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*ARGSUSED*/
483*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static void
zyd_data_out_cb(usb_pipe_handle_t pipe,usb_bulk_req_t * req)484*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_data_out_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
485*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
486*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc = (struct zyd_softc *)req->bulk_client_private;
487*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->ic;
488*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China boolean_t resched;
489*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
490*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (req->bulk_completion_reason != USB_CR_OK)
491*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB, "data OUT exception\n"));
492*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
493*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) zyd_serial_enter(sc, ZYD_NO_SIG);
494*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (sc->tx_queued > 0)
495*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->tx_queued--;
496*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China else
497*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_TX, "tx queue underrun\n"));
498*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
499*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (sc->resched && (sc->tx_queued < ZYD_TX_LIST_COUNT)) {
500*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China resched = sc->resched;
501*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->resched = B_FALSE;
502*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
503*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc);
504*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
505*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (resched)
506*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mac_tx_update(ic->ic_mach);
507*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
508*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_free_bulk_req(req);
509*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
510*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
511*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
512*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Called when the transfer from zyd_usb_bulk_pipe_send() terminates
513*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * or an exception occurs on the pipe.
514*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
515*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*ARGSUSED*/
516*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static void
zyd_bulk_pipe_cb(usb_pipe_handle_t pipe,struct usb_bulk_req * req)517*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_bulk_pipe_cb(usb_pipe_handle_t pipe, struct usb_bulk_req *req)
518*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
519*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_cb_lock *lock;
520*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China lock = (struct zyd_cb_lock *)req->bulk_client_private;
521*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
522*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Just signal that something happened */
523*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_cb_lock_signal(lock);
524*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
525*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
526*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static zyd_res
zyd_usb_bulk_pipe_send(struct zyd_usb * uc,usb_pipe_handle_t pipe,const void * data,size_t len)527*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_bulk_pipe_send(struct zyd_usb *uc,
528*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_pipe_handle_t pipe, const void *data, size_t len)
529*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
530*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_bulk_req_t *send_req;
531*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk_t *mblk;
532*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int res;
533*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_cb_lock lock;
534*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
535*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req = usb_alloc_bulk_req(uc->dip, len, USB_FLAGS_SLEEP);
536*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (send_req == NULL) {
537*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to allocate bulk request\n");
538*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
539*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
540*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_len = (uint_t)len;
541*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_client_private = (usb_opaque_t)&lock;
542*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_attributes = USB_ATTRS_AUTOCLEARING;
543*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_timeout = 5;
544*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_cb = zyd_bulk_pipe_cb;
545*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_exc_cb = zyd_bulk_pipe_cb;
546*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
547*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk = send_req->bulk_data;
548*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China bcopy(data, mblk->b_wptr, len);
549*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk->b_wptr += len;
550*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
551*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_cb_lock_init(&lock);
552*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
553*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = usb_pipe_bulk_xfer(pipe, send_req, USB_FLAGS_NOSLEEP);
554*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (res != USB_SUCCESS) {
555*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB,
556*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China "failed writing to bulk OUT pipe (%d)\n", res));
557*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_free_bulk_req(send_req);
558*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_cb_lock_destroy(&lock);
559*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
560*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
561*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
562*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_cb_lock_wait(&lock, 1000000) != ZYD_SUCCESS) {
563*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("timeout - pipe reset\n");
564*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_pipe_reset(uc->dip, pipe, USB_FLAGS_SLEEP, NULL, 0);
565*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) zyd_cb_lock_wait(&lock, -1);
566*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = ZYD_FAILURE;
567*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else {
568*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = (send_req->bulk_completion_reason == USB_CR_OK) ?
569*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_SUCCESS : ZYD_FAILURE;
570*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
571*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
572*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_free_bulk_req(send_req);
573*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_cb_lock_destroy(&lock);
574*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (res);
575*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
576*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
577*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
578*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Called when the transfer from zyd_usb_intr_pipe_send() terminates
579*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * or an exception occurs on the pipe.
580*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
581*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*ARGSUSED*/
582*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static void
zyd_intr_pipe_cb(usb_pipe_handle_t pipe,struct usb_intr_req * req)583*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_intr_pipe_cb(usb_pipe_handle_t pipe, struct usb_intr_req *req)
584*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
585*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_cb_lock *lock;
586*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China lock = (struct zyd_cb_lock *)req->intr_client_private;
587*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
588*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Just signal that something happened */
589*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_cb_lock_signal(lock);
590*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
591*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
592*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
593*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Send a sequence of bytes to an interrupt pipe.
594*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
595*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * uc pointer to usb module state
596*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * data pointer to a buffer of bytes
597*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * len size of the buffer (bytes)
598*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
599*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static zyd_res
zyd_usb_intr_pipe_send(struct zyd_usb * uc,usb_pipe_handle_t pipe,const void * data,size_t len)600*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_intr_pipe_send(struct zyd_usb *uc,
601*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_pipe_handle_t pipe, const void *data, size_t len)
602*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
603*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_intr_req_t *send_req;
604*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk_t *mblk;
605*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int res;
606*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_cb_lock lock;
607*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
608*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req = usb_alloc_intr_req(uc->dip, len, USB_FLAGS_SLEEP);
609*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (send_req == NULL) {
610*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to allocate interupt request\n");
611*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
612*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
613*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->intr_len = (uint_t)len;
614*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->intr_client_private = (usb_opaque_t)&lock;
615*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->intr_attributes = USB_ATTRS_AUTOCLEARING;
616*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->intr_timeout = 5;
617*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->intr_cb = zyd_intr_pipe_cb;
618*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->intr_exc_cb = zyd_intr_pipe_cb;
619*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
620*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk = send_req->intr_data;
621*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China bcopy(data, mblk->b_wptr, len);
622*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk->b_wptr += len;
623*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
624*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_cb_lock_init(&lock);
625*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
626*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = usb_pipe_intr_xfer(pipe, send_req, 0);
627*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (res != USB_SUCCESS) {
628*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB,
629*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China "failed writing to intr/out pipe (%d)\n", res));
630*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_free_intr_req(send_req);
631*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_cb_lock_destroy(&lock);
632*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
633*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
634*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
635*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_cb_lock_wait(&lock, 1000000) != ZYD_SUCCESS) {
636*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("timeout - pipe reset\n");
637*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_pipe_reset(uc->dip, pipe, USB_FLAGS_SLEEP, NULL, 0);
638*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) zyd_cb_lock_wait(&lock, -1);
639*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = ZYD_FAILURE;
640*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else {
641*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = (send_req->intr_completion_reason == USB_CR_OK) ?
642*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_SUCCESS : ZYD_FAILURE;
643*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
644*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
645*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_free_intr_req(send_req);
646*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_cb_lock_destroy(&lock);
647*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (res);
648*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
649*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
650*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
651*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Send a sequence of bytes to the cmd_out pipe. (in a single USB transfer)
652*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
653*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * uc pointer to usb module state
654*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * data pointer to a buffer of bytes
655*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * len size of the buffer (bytes)
656*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
657*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static zyd_res
zyd_usb_cmd_pipe_send(struct zyd_usb * uc,const void * data,size_t len)658*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_cmd_pipe_send(struct zyd_usb *uc, const void *data, size_t len)
659*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
660*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res res;
661*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint8_t type;
662*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
663*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Determine the type of cmd_out */
664*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China type = uc->ep_cmd_out.ep_descr.bmAttributes & USB_EP_ATTR_MASK;
665*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (type == USB_EP_ATTR_BULK)
666*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = zyd_usb_bulk_pipe_send(uc, uc->pipe_cmd_out, data, len);
667*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China else
668*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = zyd_usb_intr_pipe_send(uc, uc->pipe_cmd_out, data, len);
669*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
670*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (res);
671*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
672*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
673*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
674*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
675*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Format and send a command to the cmd_out pipe.
676*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
677*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * uc pointer to usb module state
678*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * code ZD command code (16-bit)
679*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * data raw buffer containing command data
680*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * len size of the data buffer (bytes)
681*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
682*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res
zyd_usb_cmd_send(struct zyd_usb * uc,uint16_t code,const void * data,size_t len)683*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_cmd_send(struct zyd_usb *uc,
684*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint16_t code, const void *data, size_t len)
685*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
686*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res res;
687*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_cmd cmd;
688*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
689*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China cmd.cmd_code = LE_16(code);
690*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China bcopy(data, cmd.data, len);
691*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
692*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = zyd_usb_cmd_pipe_send(uc, &cmd, sizeof (uint16_t) + len);
693*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (res != ZYD_SUCCESS) {
694*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB, "failed writing command (%d)\n", res));
695*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
696*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
697*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
698*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_SUCCESS);
699*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
700*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
701*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
702*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Issue an ioread request.
703*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
704*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Issues a ZD ioread command (with a vector of addresses passed in raw
705*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * form as in_data) and blocks until the response is received
706*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * and filled into the response buffer.
707*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
708*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * uc pointer to usb module state
709*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * in_data pointer to request data
710*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * in_len request data size (bytes)
711*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * out_data pointer to response buffer
712*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * out_len response buffer size (bytes)
713*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
714*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res
zyd_usb_ioread_req(struct zyd_usb * uc,const void * in_data,size_t in_len,void * out_data,size_t out_len)715*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_ioread_req(struct zyd_usb *uc,
716*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China const void *in_data, size_t in_len, void *out_data, size_t out_len)
717*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
718*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res res;
719*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int cnt;
720*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
721*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Initialise io_read structure */
722*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->io_read.done = B_FALSE;
723*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->io_read.buffer = out_data;
724*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->io_read.buf_len = (int)out_len;
725*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
726*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->io_read.pending = B_TRUE;
727*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
728*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = zyd_usb_cmd_send(uc, ZYD_CMD_IORD, in_data, in_len);
729*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (res != ZYD_SUCCESS) {
730*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB, "IO read request: pipe failure(%d)\n"));
731*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
732*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
733*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
734*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China cnt = 0;
735*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China while (uc->io_read.done != B_TRUE && cnt < 500) {
736*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China delay(drv_usectohz(10 * 1000));
737*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ++cnt;
738*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
739*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
740*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (uc->io_read.done != B_TRUE) {
741*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("I/O read request: timeout\n");
742*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
743*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
744*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
745*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (uc->io_read.exc != B_FALSE) {
746*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB, "I/O read request: exception\n"));
747*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
748*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
749*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
750*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_SUCCESS);
751*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
752*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
753*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
754*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
755*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Called when data arrives from the cmd_in pipe.
756*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
757*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*ARGSUSED*/
758*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static void
zyd_cmd_in_cb(usb_pipe_handle_t pipe,usb_intr_req_t * req)759*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_cmd_in_cb(usb_pipe_handle_t pipe, usb_intr_req_t *req)
760*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
761*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_usb *uc;
762*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_ioread *rdp;
763*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk_t *mblk, *tmp_blk;
764*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China unsigned char *data;
765*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China size_t len;
766*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint16_t code;
767*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
768*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc = (struct zyd_usb *)req->intr_client_private;
769*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(uc != NULL);
770*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China rdp = &uc->io_read;
771*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk = req->intr_data;
772*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
773*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (mblk->b_cont != NULL) {
774*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Fragmented message, concatenate */
775*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China tmp_blk = msgpullup(mblk, -1);
776*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China data = tmp_blk->b_rptr;
777*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China len = MBLKL(tmp_blk);
778*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else {
779*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Non-fragmented message, use directly */
780*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China tmp_blk = NULL;
781*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China data = mblk->b_rptr;
782*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China len = MBLKL(mblk);
783*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
784*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
785*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China code = LE_16(*(uint16_t *)(uintptr_t)data);
786*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (code != ZYD_RESPONSE_IOREAD) {
787*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Other response types not handled yet */
788*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_free_intr_req(req);
789*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return;
790*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
791*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
792*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (rdp->pending != B_TRUE) {
793*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("no ioread pending\n");
794*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_free_intr_req(req);
795*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return;
796*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
797*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China rdp->pending = B_FALSE;
798*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
799*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Now move on to the data part */
800*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China data += sizeof (uint16_t);
801*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China len -= sizeof (uint16_t);
802*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (rdp->buf_len > len) {
803*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("too few bytes received\n");
804*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
805*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
806*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China bcopy(data, rdp->buffer, rdp->buf_len);
807*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
808*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (tmp_blk != NULL)
809*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China freemsg(tmp_blk);
810*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
811*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China rdp->exc = B_FALSE;
812*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China rdp->done = B_TRUE;
813*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_free_intr_req(req);
814*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
815*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
816*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
817*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Called when an exception occurs on the cmd_in pipe.
818*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
819*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*ARGSUSED*/
820*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static void
zyd_cmd_in_exc_cb(usb_pipe_handle_t pipe,usb_intr_req_t * req)821*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_cmd_in_exc_cb(usb_pipe_handle_t pipe, usb_intr_req_t *req)
822*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
823*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_usb *uc;
824*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_ioread *rdp;
825*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
826*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB, "command IN exception\n"));
827*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
828*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc = (struct zyd_usb *)req->intr_client_private;
829*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(uc != NULL);
830*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China rdp = &uc->io_read;
831*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
832*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (rdp->pending == B_TRUE) {
833*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China rdp->exc = B_TRUE;
834*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China rdp->done = B_TRUE;
835*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
836*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_free_intr_req(req);
837*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
838*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
839*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
840*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Start interrupt polling on the cmd_in pipe.
841*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
842*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res
zyd_usb_cmd_in_start_polling(struct zyd_usb * uc)843*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_cmd_in_start_polling(struct zyd_usb *uc)
844*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
845*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_intr_req_t *intr_req;
846*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int res;
847*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
848*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China intr_req = usb_alloc_intr_req(uc->dip, 0, USB_FLAGS_SLEEP);
849*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (intr_req == NULL) {
850*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to allocate interrupt request\n");
851*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
852*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
853*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
854*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China intr_req->intr_attributes = USB_ATTRS_SHORT_XFER_OK;
855*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China intr_req->intr_len = uc->ep_cmd_in.ep_descr.wMaxPacketSize;
856*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China intr_req->intr_cb = zyd_cmd_in_cb;
857*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China intr_req->intr_exc_cb = zyd_cmd_in_exc_cb;
858*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China intr_req->intr_client_private = (usb_opaque_t)uc;
859*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
860*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = usb_pipe_intr_xfer(uc->pipe_cmd_in, intr_req, USB_FLAGS_NOSLEEP);
861*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (res != USB_SUCCESS) {
862*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed starting command IN polling: pipe failure\n");
863*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_free_intr_req(intr_req);
864*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
865*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
866*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
867*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_SUCCESS);
868*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
869*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
870*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
871*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Stop interrupt polling on the cmd_in pipe.
872*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
873*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China void
zyd_usb_cmd_in_stop_polling(struct zyd_usb * uc)874*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_cmd_in_stop_polling(struct zyd_usb *uc)
875*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
876*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB, "stopping command IN polling\n"));
877*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
878*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_pipe_stop_intr_polling(uc->pipe_cmd_in, USB_FLAGS_SLEEP);
879*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
880*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
881*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
882*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Called when data arrives on the data_in pipe.
883*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
884*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*ARGSUSED*/
885*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static void
zyd_data_in_cb(usb_pipe_handle_t pipe,usb_bulk_req_t * req)886*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_data_in_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
887*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
888*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc;
889*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_usb *uc;
890*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk_t *mblk, *tmp_blk;
891*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_rx_desc *desc;
892*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China unsigned char *data;
893*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China size_t len;
894*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
895*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc = (struct zyd_usb *)req->bulk_client_private;
896*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(uc != NULL);
897*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc = ZYD_USB_TO_SOFTC(uc);
898*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(sc != NULL);
899*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk = req->bulk_data;
900*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
901*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Fragmented STREAMS message? */
902*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (mblk->b_cont != NULL) {
903*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Fragmented, concatenate it into a single block */
904*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China tmp_blk = msgpullup(mblk, -1);
905*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (tmp_blk == NULL) {
906*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to concatenate fragments\n");
907*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China goto error;
908*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
909*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China data = tmp_blk->b_rptr;
910*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China len = MBLKL(tmp_blk);
911*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else {
912*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Not fragmented, use directly */
913*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China tmp_blk = NULL;
914*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China data = mblk->b_rptr;
915*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China len = MBLKL(mblk);
916*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
917*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
918*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (len < 2) {
919*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("received usb transfer too short\n");
920*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China goto error;
921*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
922*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
923*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
924*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * If this is a composite packet, the last two bytes contain
925*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * two special signature bytes.
926*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
927*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China desc = (struct zyd_rx_desc *)(data + len) - 1;
928*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* multi-frame transfer */
929*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (LE_16(desc->tag) == ZYD_TAG_MULTIFRAME) {
930*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China const uint8_t *p = data, *end = data + len;
931*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int i;
932*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
933*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_RX, "composite packet\n"));
934*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
935*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China for (i = 0; i < ZYD_MAX_RXFRAMECNT; i++) {
936*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China const uint16_t len16 = LE_16(desc->len[i]);
937*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (len16 == 0 || p + len16 > end)
938*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break;
939*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_receive(ZYD_USB_TO_SOFTC(uc), p, len16);
940*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* next frame is aligned on a 32-bit boundary */
941*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China p += (len16 + 3) & ~3;
942*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
943*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else {
944*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* single-frame transfer */
945*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_receive(ZYD_USB_TO_SOFTC(uc), data, MBLKL(mblk));
946*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
947*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
948*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China error:
949*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (tmp_blk != NULL)
950*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China freemsg(tmp_blk);
951*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
952*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_free_bulk_req(req);
953*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
954*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (!sc->running)
955*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return;
956*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
957*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_usb_data_in_start_request(uc) != ZYD_SUCCESS) {
958*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("error restarting data_in transfer\n");
959*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
960*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
961*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
962*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
963*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Called when an exception occurs on the data_in pipe.
964*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
965*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*ARGSUSED*/
966*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static void
zyd_data_in_exc_cb(usb_pipe_handle_t pipe,usb_bulk_req_t * req)967*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_data_in_exc_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
968*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
969*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_usb *uc;
970*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
971*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB, "data IN exception\n"));
972*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
973*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc = (struct zyd_usb *)req->bulk_client_private;
974*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(uc != NULL);
975*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
976*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_free_bulk_req(req);
977*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
978*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
979*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
980*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Start a receive request on the data_in pipe.
981*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
982*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static zyd_res
zyd_usb_data_in_start_request(struct zyd_usb * uc)983*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_data_in_start_request(struct zyd_usb *uc)
984*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
985*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_bulk_req_t *req;
986*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int res;
987*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
988*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China req = usb_alloc_bulk_req(uc->dip, ZYD_RX_BUF_SIZE, USB_FLAGS_SLEEP);
989*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (req == NULL) {
990*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to allocate bulk IN request\n");
991*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
992*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
993*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
994*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China req->bulk_len = (uint_t)ZYD_RX_BUF_SIZE;
995*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China req->bulk_timeout = 0;
996*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China req->bulk_client_private = (usb_opaque_t)uc;
997*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China req->bulk_attributes =
998*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China USB_ATTRS_SHORT_XFER_OK | USB_ATTRS_AUTOCLEARING;
999*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China req->bulk_cb = zyd_data_in_cb;
1000*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China req->bulk_exc_cb = zyd_data_in_exc_cb;
1001*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1002*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = usb_pipe_bulk_xfer(uc->pipe_data_in, req, USB_FLAGS_NOSLEEP);
1003*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (res != USB_SUCCESS) {
1004*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("error starting receive request on data_in pipe\n");
1005*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_free_bulk_req(req);
1006*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
1007*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1008*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1009*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_SUCCESS);
1010*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1011*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1012*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1013*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
1014*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Start receiving packets on the data_in pipe.
1015*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
1016*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res
zyd_usb_data_in_enable(struct zyd_usb * uc)1017*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_data_in_enable(struct zyd_usb *uc)
1018*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
1019*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China for (int i = 0; i < ZYD_RX_LIST_COUNT; i++) {
1020*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_usb_data_in_start_request(uc) != ZYD_SUCCESS) {
1021*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to start data IN requests\n");
1022*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
1023*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1024*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1025*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_SUCCESS);
1026*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1027*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1028*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
1029*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Stop receiving packets on the data_in pipe.
1030*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
1031*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China void
zyd_usb_data_in_disable(struct zyd_usb * uc)1032*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_data_in_disable(struct zyd_usb *uc)
1033*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
1034*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_pipe_reset(uc->dip, uc->pipe_data_in, USB_FLAGS_SLEEP,
1035*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China NULL, NULL);
1036*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1037*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1038*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
1039*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Send a packet to data_out.
1040*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
1041*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * A packet consists of a zyd_tx_header + the IEEE802.11 frame.
1042*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
1043*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res
zyd_usb_send_packet(struct zyd_usb * uc,mblk_t * mp)1044*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_send_packet(struct zyd_usb *uc, mblk_t *mp)
1045*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
1046*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_bulk_req_t *send_req;
1047*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int res;
1048*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1049*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req = usb_alloc_bulk_req(uc->dip, 0, USB_FLAGS_SLEEP);
1050*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (send_req == NULL) {
1051*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to allocate bulk request\n");
1052*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
1053*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1054*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1055*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_len = msgdsize(mp);
1056*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_data = mp;
1057*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_timeout = 5;
1058*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_attributes = USB_ATTRS_AUTOCLEARING;
1059*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_client_private = (usb_opaque_t)ZYD_USB_TO_SOFTC(uc);
1060*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_cb = zyd_data_out_cb;
1061*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_exc_cb = zyd_data_out_cb;
1062*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_completion_reason = 0;
1063*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China send_req->bulk_cb_flags = 0;
1064*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1065*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = usb_pipe_bulk_xfer(uc->pipe_data_out, send_req, 0);
1066*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (res != USB_SUCCESS) {
1067*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB,
1068*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China "failed writing to bulk/out pipe (%d)\n", res));
1069*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_free_bulk_req(send_req);
1070*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (USB_FAILURE);
1071*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1072*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1073*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (USB_SUCCESS);
1074*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1075*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1076*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
1077*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Initialize USB device communication and USB module state.
1078*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *
1079*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * uc pointer to usb module state
1080*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * dip pointer to device info structure
1081*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
1082*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res
zyd_usb_init(struct zyd_softc * sc)1083*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_init(struct zyd_softc *sc)
1084*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
1085*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_usb *uc = &sc->usb;
1086*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China dev_info_t *dip = sc->dip;
1087*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int ures;
1088*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1089*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->dip = dip;
1090*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1091*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ures = usb_client_attach(uc->dip, USBDRV_VERSION, 0);
1092*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (ures != USB_SUCCESS) {
1093*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("usb_client_attach failed, error code: %d\n", ures);
1094*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
1095*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1096*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1097*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
1098*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * LVL_ALL is needed for later endpoint scanning,
1099*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * and the tree must not be freed before that.
1100*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
1101*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ures = usb_get_dev_data(uc->dip, &uc->cdata, USB_PARSE_LVL_ALL, 0);
1102*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (ures != USB_SUCCESS) {
1103*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("usb_get_dev_data failed, error code: %d\n", ures);
1104*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(uc->cdata == NULL);
1105*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China goto fail;
1106*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1107*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1108*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ures = usb_reset_device(uc->dip, USB_RESET_LVL_DEFAULT);
1109*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (ures != USB_SUCCESS) {
1110*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("usb_reset_device failed, error code: %d\n", ures);
1111*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China goto fail;
1112*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1113*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1114*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->connected = B_TRUE;
1115*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1116*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ures = usb_register_hotplug_cbs(dip, zyd_usb_disconnect,
1117*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_reconnect);
1118*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (ures != USB_SUCCESS) {
1119*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("usb_register_hotplug_cbs failed, error code: %d\n",
1120*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ures);
1121*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China goto fail;
1122*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1123*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1124*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_SUCCESS);
1125*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China fail:
1126*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_client_detach(uc->dip, uc->cdata);
1127*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->cdata = NULL;
1128*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE);
1129*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1130*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1131*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
1132*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Deinitialize USB device communication.
1133*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
1134*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China void
zyd_usb_deinit(struct zyd_softc * sc)1135*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_deinit(struct zyd_softc *sc)
1136*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
1137*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_usb *uc = &sc->usb;
1138*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1139*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_unregister_hotplug_cbs(sc->dip);
1140*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1141*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_client_detach(uc->dip, uc->cdata);
1142*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->cdata = NULL;
1143*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->connected = B_FALSE;
1144*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1145*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1146*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*
1147*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Device connected
1148*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */
1149*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int
zyd_usb_reconnect(dev_info_t * dip)1150*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_reconnect(dev_info_t *dip)
1151*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
1152*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc;
1153*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_usb *uc;
1154*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1155*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc = ddi_get_soft_state(zyd_ssp, ddi_get_instance(dip));
1156*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(sc != NULL);
1157*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc = &sc->usb;
1158*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(!uc->connected);
1159*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1160*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (sc->suspended)
1161*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_RESUME | ZYD_DBG_USB,
1162*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China "reconnect before resume\n"));
1163*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1164*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* check device changes after disconnect */
1165*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (usb_check_same_device(sc->dip, NULL, USB_LOG_L2, -1,
1166*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China USB_CHK_BASIC | USB_CHK_CFG, NULL) != USB_SUCCESS) {
1167*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB, "different device connected\n"));
1168*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE);
1169*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1170*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1171*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) zyd_serial_enter(sc, ZYD_NO_SIG);
1172*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_hw_init(sc) != ZYD_SUCCESS) {
1173*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to reinit hardware\n");
1174*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc);
1175*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE);
1176*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1177*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (sc->running) {
1178*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_hw_start(sc) != ZYD_SUCCESS) {
1179*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to restart hardware\n");
1180*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc);
1181*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China goto fail;
1182*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1183*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1184*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc);
1185*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1186*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->connected = B_TRUE;
1187*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1188*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS);
1189*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China fail:
1190*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China usb_client_detach(uc->dip, uc->cdata);
1191*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->cdata = NULL;
1192*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE);
1193*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1194*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1195*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int
zyd_usb_disconnect(dev_info_t * dip)1196*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_disconnect(dev_info_t *dip)
1197*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
1198*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc;
1199*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_usb *uc;
1200*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1201*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc = ddi_get_soft_state(zyd_ssp, ddi_get_instance(dip));
1202*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(sc != NULL);
1203*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc = &sc->usb;
1204*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1205*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (!uc->connected) {
1206*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB, "different device disconnected\n"));
1207*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE);
1208*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1209*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->connected = B_FALSE;
1210*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1211*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (sc->suspended) {
1212*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB, "disconnect after suspend\n"));
1213*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS);
1214*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1215*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_new_state(&sc->ic, IEEE80211_S_INIT, -1);
1216*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1217*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) zyd_serial_enter(sc, ZYD_NO_SIG);
1218*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_hw_stop(sc);
1219*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_hw_deinit(sc);
1220*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc);
1221*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1222*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS);
1223*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1224*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1225*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int
zyd_suspend(struct zyd_softc * sc)1226*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_suspend(struct zyd_softc *sc)
1227*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
1228*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_usb *uc = &sc->usb;
1229*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1230*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (!uc->connected) {
1231*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB | ZYD_DBG_RESUME,
1232*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China "suspend after disconnect\n"));
1233*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->suspended = B_TRUE;
1234*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS);
1235*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1236*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_RESUME, "suspend\n"));
1237*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1238*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->suspended = B_TRUE;
1239*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_new_state(&sc->ic, IEEE80211_S_INIT, -1);
1240*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1241*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) zyd_serial_enter(sc, ZYD_NO_SIG);
1242*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_hw_stop(sc);
1243*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_hw_deinit(sc);
1244*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc);
1245*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1246*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_RESUME, "suspend complete\n"));
1247*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS);
1248*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1249*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1250*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int
zyd_resume(struct zyd_softc * sc)1251*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_resume(struct zyd_softc *sc)
1252*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {
1253*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_usb *uc = &sc->usb;
1254*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1255*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (!uc->connected) {
1256*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_USB | ZYD_DBG_RESUME,
1257*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China "resume after disconnect\n"));
1258*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->suspended = B_FALSE;
1259*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS);
1260*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1261*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_RESUME, "resume\n"));
1262*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1263*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* check device changes after disconnect */
1264*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (usb_check_same_device(sc->dip, NULL, USB_LOG_L2, -1,
1265*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China USB_CHK_BASIC | USB_CHK_CFG, NULL) != USB_SUCCESS) {
1266*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("different device connected to same port\n");
1267*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->suspended = B_FALSE;
1268*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uc->connected = B_FALSE;
1269*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS);
1270*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1271*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1272*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) zyd_serial_enter(sc, ZYD_NO_SIG);
1273*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_hw_init(sc) != ZYD_SUCCESS) {
1274*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to reinit hardware\n");
1275*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc);
1276*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE);
1277*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1278*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (sc->running) {
1279*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_hw_start(sc) != ZYD_SUCCESS) {
1280*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to restart hardware\n");
1281*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc);
1282*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE);
1283*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1284*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1285*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc);
1286*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1287*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->suspended = B_FALSE;
1288*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China
1289*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_RESUME, "resume complete\n"));
1290*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS);
1291*e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }
1292