2 * Mobile action cable mode switcher
4 * Copyright (C) 2008 - 2010 Dan Williams <dcbw@redhat.com>
5 * Copyright (C) 2008 Peter Henn <support@option.com>
7 * Heavily based on the 'ozerocdoff' tool by Peter Henn.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details:
32 #include "ma8280p_us.h"
34 struct usb_dev_handle *handle = NULL;
36 typedef struct usb_device * (*FindFunc) (int vid, int pid);
37 typedef int (*SwitchFunc) (struct usb_dev_handle *dh, struct usb_device *dev);
44 typedef struct SwitchEntry {
48 SwitchFunc switch_func;
51 static SwitchEntry switch_types[] = {
52 { ST_MA8280P, "mobile-action-8280p", NULL, ma8280p_switch },
53 { ST_UNKNOWN, NULL, NULL }
56 static struct usb_device *
57 generic_find (int vid, int pid)
60 struct usb_device *dev;
62 for (bus = usb_get_busses(); bus; bus = bus->next) {
63 for (dev = bus->devices; dev; dev = dev->next) {
64 if (dev->descriptor.idVendor == vid && dev->descriptor.idProduct == pid) {
65 debug ("Found device '%s'", dev->filename);
74 release_usb_device (int param)
76 usb_release_interface (handle, 0);
83 printf ("Usage: mobile-action-modeswitch [-hdq] [-l <file>] -v <vendor-id> -p <product-id> -t <type>\n"
84 " -h, --help show this help message\n"
85 " -v, --vendor <n> target USB vendor ID\n"
86 " -p, --product <n> target USB product ID\n"
87 " -t, --type <type> type of switch to attempt, varies by device:\n"
88 " mobile-action-8280p - For Mobile Action 8xxxP USB cables\n"
89 " -l, --log <file> log output to a file\n"
90 " -q, --quiet don't print anything to stdout\n"
91 " -d, --debug display debugging messages\n\n"
93 " mobile-action-modeswitch -v 0x0df7 -p 0x8000 -t mobile-action-8280p\n");
97 parse_type (const char *s)
99 SwitchEntry *entry = &switch_types[0];
101 while (entry->clopt) {
102 if (!strcmp (entry->clopt, s))
117 int main(int argc, char **argv)
119 static struct option options[] = {
120 { "help", no_argument, NULL, 'h' },
121 { "vendor", required_argument, NULL, 'v' },
122 { "product", required_argument, NULL, 'p' },
123 { "type", required_argument, NULL, 't' },
124 { "log", required_argument, NULL, 'l' },
125 { "debug", no_argument, NULL, 'd' },
126 { "quiet", no_argument, NULL, 'q' },
130 struct usb_device *dev;
131 int vid = 0, pid = 0;
132 const char *logpath = NULL;
134 int ret, quiet = 0, debug = 0;
135 SwitchEntry *sentry = NULL;
140 option = getopt_long(argc, argv, "hv:p:l:t:dq", options, NULL);
146 vid = strtol (optarg, NULL, 0);
149 pid = strtol (optarg, NULL, 0);
152 sentry = parse_type (optarg);
154 error ("unknown switch type '%s'", optarg);
175 if (log_startup (logpath, debug, quiet)) {
176 fprintf (stderr, "Couldn't open/create logfile %s", logpath);
184 error ("missing device switch type.");
192 error ("missing vendor and device IDs.");
198 if (usb_find_busses() < 0) {
199 error ("no USB busses found.");
203 if (usb_find_devices() < 0) {
204 error ("no USB devices found.");
208 if (sentry->find_func)
209 dev = (*sentry->find_func) (vid, pid);
211 dev = generic_find (vid, pid);
213 error ("no device found.");
217 handle = usb_open (dev);
218 if (handle == NULL) {
219 error ("%s: could not access the device.",
224 /* detach running default driver */
225 signal (SIGTERM, release_usb_device);
226 ret = usb_get_driver_np (handle, 0, buffer, sizeof (buffer));
228 debug ("%s: found already attached driver '%s'", dev->filename, buffer);
230 ret = usb_detach_kernel_driver_np (handle, 0);
232 debug ("%s: error: unable to detach current driver.", dev->filename);
238 ret = usb_claim_interface (handle, 0);
240 debug ("%s: couldn't claim device's USB interface: %d.",
246 ret = (*sentry->switch_func) (handle, dev);
248 debug ("%s: failed to switch device to serial mode.", dev->filename);
249 usb_release_interface (handle, 0);
254 usb_release_interface (handle, 0);
256 ret = usb_close (handle);
258 debug ("%s: failed to close the device.", dev->filename);