FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/ezload.c
1 /* $NetBSD: ezload.c,v 1.8 2003/10/29 03:54:17 mycroft Exp $ */
2
3 /*
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson <lennart@augustsson.net>.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: ezload.c,v 1.8 2003/10/29 03:54:17 mycroft Exp $");
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/device.h>
46 #include <sys/conf.h>
47
48 #include <dev/usb/usb.h>
49 #include <dev/usb/usbdi.h>
50 #include <dev/usb/usbdi_util.h>
51
52 #include <dev/usb/ezload.h>
53
54 /*
55 * Vendor specific request code for Anchor Upload/Download
56 */
57
58 /* This one is implemented in the core */
59 #define ANCHOR_LOAD_INTERNAL 0xA0
60
61 /* This is the highest internal RAM address for the AN2131Q */
62 #define ANCHOR_MAX_INTERNAL_ADDRESS 0x1B3F
63
64 /*
65 * EZ-USB Control and Status Register. Bit 0 controls 8051 reset
66 */
67 #define ANCHOR_CPUCS_REG 0x7F92
68 #define ANCHOR_RESET 0x01
69
70 /*
71 * Although USB does not limit you here, the Anchor docs
72 * quote 64 as a limit, and Mato@activewireinc.com suggested
73 * to use 16.
74 */
75 #define ANCHOR_CHUNK 16
76
77 /*
78 * This is a firmware loader for ezusb (Anchor) devices. When the firmware
79 * has been downloaded the device will simulate a disconnect and when it
80 * is next recognized by the USB software it will appear as another
81 * device.
82 */
83
84 #ifdef USB_DEBUG
85 #define DPRINTF(x) if (ezloaddebug) printf x
86 #define DPRINTFN(n,x) if (ezloaddebug>(n)) printf x
87 int ezloaddebug = 0;
88 #else
89 #define DPRINTF(x)
90 #define DPRINTFN(n,x)
91 #endif
92
93 usbd_status
94 ezload_reset(usbd_device_handle dev, int reset)
95 {
96 usb_device_request_t req;
97 uByte rst;
98
99 DPRINTF(("ezload_reset: reset=%d\n", reset));
100
101 rst = reset ? ANCHOR_RESET : 0;
102 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
103 req.bRequest = ANCHOR_LOAD_INTERNAL;
104 USETW(req.wValue, ANCHOR_CPUCS_REG);
105 USETW(req.wIndex, 0);
106 USETW(req.wLength, 1);
107 return (usbd_do_request(dev, &req, &rst));
108 }
109
110 usbd_status
111 ezload_download(usbd_device_handle dev, const struct ezdata *rec)
112 {
113 usb_device_request_t req;
114 const struct ezdata *ptr;
115 u_int len, offs;
116 int err;
117
118 DPRINTF(("ezload_down record=%p\n", rec));
119
120 for (ptr = rec; ptr->length != 0; ptr++) {
121
122 #if 0
123 if (ptr->address + ptr->length > ANCHOR_MAX_INTERNAL_ADDRESS)
124 return (USBD_INVAL);
125 #endif
126
127 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
128 req.bRequest = ANCHOR_LOAD_INTERNAL;
129 USETW(req.wIndex, 0);
130 for (offs = 0; offs < ptr->length; offs += ANCHOR_CHUNK) {
131 len = ptr->length - offs;
132 if (len > ANCHOR_CHUNK)
133 len = ANCHOR_CHUNK;
134 USETW(req.wValue, ptr->address + offs);
135 USETW(req.wLength, len);
136 DPRINTFN(2,("ezload_download: addr=0x%x len=%d\n",
137 ptr->address + offs, len));
138 err = usbd_do_request(dev, &req, ptr->data + offs);
139 if (err)
140 return (err);
141 }
142 }
143
144 return (0);
145 }
146
147 usbd_status
148 ezload_downloads_and_reset(usbd_device_handle dev, const struct ezdata **recs)
149 {
150 usbd_status err;
151
152 /*(void)ezload_reset(dev, 1);*/
153 err = ezload_reset(dev, 1);
154 if (err)
155 return (err);
156 usbd_delay_ms(dev, 250);
157 while (*recs != NULL) {
158 err = ezload_download(dev, *recs++);
159 if (err)
160 return (err);
161 }
162 if (err)
163 return (err);
164 usbd_delay_ms(dev, 250);
165 /*(void)ezload_reset(dev, 0);*/
166 err = ezload_reset(dev, 0);
167 usbd_delay_ms(dev, 250);
168 return (err);
169 }
Cache object: 02546da1d10fd6c95bdcbbbb58ea1521
|