1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 Dave Chapman
12 * USB code based on ifp-line - http://ifp-driver.sourceforge.net
14 * ifp-line is (C) Pavel Kriz, Jun Yamishiro and Joe Roback and
15 * licensed under the GPL (v2)
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24 * KIND, either express or implied.
26 ****************************************************************************/
39 /* USB IDs for Manufacturing Mode */
40 #define E200R_VENDORID 0x0781
41 #define E200R_PRODUCTID 0x0720
43 #define E200R_BULK_TO 1
45 #define MAX_TRANSFER 64 /* Number of bytes to send in one write */
48 #define MAX(a,b) (((a)>(b))?(a):(b))
51 static void put_int32le(uint32_t x
, char* p
)
54 p
[1] = (x
>> 8) & 0xff;
55 p
[2] = (x
>> 16) & 0xff;
56 p
[3] = (x
>> 24) & 0xff;
59 int upload_app(usb_dev_handle
* dh
)
64 char* p
= (char*)bootimg
;
65 int bytesleft
= LEN_bootimg
;
67 /* Write the data length */
69 put_int32le(LEN_bootimg
, buf
);
71 err
= usb_bulk_write(dh
, E200R_BULK_TO
, buf
, 4, TOUT
);
75 fprintf(stderr
,"[ERR] Error writing data length\n");
76 fprintf(stderr
,"[ERR] Bulk write error (%d, %s)\n", err
, strerror(-err
));
80 /* Now send the data, MAX_TRANSFER bytes at a time. */
84 tosend
= MAX(MAX_TRANSFER
, bytesleft
);
86 err
= usb_bulk_write(dh
, E200R_BULK_TO
, p
, tosend
, TOUT
);
90 fprintf(stderr
,"[ERR] Error writing data\n");
91 fprintf(stderr
,"[ERR] Bulk write error (%d, %s)\n", err
, strerror(-err
));
103 /* The main function */
105 void do_patching(void)
107 struct usb_bus
*busses
;
109 struct usb_device
*tmp_dev
;
110 struct usb_device
*dev
= NULL
;
114 fprintf(stderr
,"[INFO] Searching for E200R\n");
118 if(usb_find_busses() < 0) {
119 fprintf(stderr
, "[ERR] Could not find any USB busses.\n");
123 if (usb_find_devices() < 0) {
124 fprintf(stderr
, "[ERR] USB devices not found(nor hubs!).\n");
128 /* C calling convention, it's not nice to use global stuff */
129 busses
= usb_get_busses();
131 for (bus
= busses
; bus
; bus
= bus
->next
) {
132 for (tmp_dev
= bus
->devices
; tmp_dev
; tmp_dev
= tmp_dev
->next
) {
133 if (tmp_dev
->descriptor
.idVendor
== E200R_VENDORID
&&
134 tmp_dev
->descriptor
.idProduct
== E200R_PRODUCTID
) {
144 fprintf(stderr
, "[ERR] E200R device not found.\n");
145 fprintf(stderr
, "[ERR] Ensure your E200R is in manufacturing mode and run e200rpatcher again.\n");
150 if ( (dh
= usb_open(dev
)) == NULL
) {
151 fprintf(stderr
,"[ERR] Unable to open E200R device.\n");
155 err
= usb_set_configuration(dh
, 1);
158 fprintf(stderr
, "[ERR] usb_set_configuration failed (%d)\n", err
);
163 /* "must be called" written in the libusb documentation */
164 err
= usb_claim_interface(dh
, dev
->config
->interface
->altsetting
->bInterfaceNumber
);
166 fprintf(stderr
, "[ERR] Unable to claim interface (%d)\n", err
);
171 fprintf(stderr
,"[INFO] Found E200R, uploading patching application.\n");
173 /* Now we can transfer the application to the device. */
175 if (upload_app(dh
) < 0)
177 fprintf(stderr
,"[ERR] Upload of application failed.\n");
181 fprintf(stderr
,"[INFO] Patching application uploaded successfully!\n");
184 /* release claimed interface */
185 usb_release_interface(dh
, dev
->config
->interface
->altsetting
->bInterfaceNumber
);
189 void print_usage(void)
191 fprintf(stderr
,"Usage: e200rpatcher [options]\n");
192 fprintf(stderr
,"Options:\n");
193 fprintf(stderr
," -s, --silent\t\tDont display instructions\n");
196 int main(int argc
, char* argv
[])
203 if ((argc
> 1) && ((strcmp(argv
[1],"-h")==0) || (strcmp(argv
[1],"--help")==0))) {
209 if (!strcmp(argv
[i
], "--silent") || !strcmp(argv
[i
], "-s"))
213 printf("e200rpatcher v" VERSION
" - (C) 2007 Jonathan Gordon & Dave Chapman\n");
214 printf("This is free software; see the source for copying conditions. There is NO\n");
215 printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
219 printf("Attach your E200R in \"manufacturing mode\" as follows:\n");
220 printf(" 1) Power-off your E200R\n");
221 printf(" 2) Turn ON the lock/hold switch\n");
222 printf(" 3) Press and hold the SELECT button and whilst it is held down,\n");
223 printf(" attach your E200R to your computer via USB\n");
224 printf(" 4) After attaching to USB, keep the SELECT button held for 10 seconds.\n");
226 printf("NOTE: If your E200R starts in the normal Sansa firmware, you have\n");
227 printf(" failed to enter manufacturing mode and should try again at step 1).\n\n");
229 printf("[INFO] Press Enter to continue:");
230 fgets(input
, 4, stdin
);
236 printf("[INFO] Press ENTER to exit: ");
237 fgets(input
, 4, stdin
);