diff options
Diffstat (limited to 'utils/hwstub/lib/hwstub.c')
-rw-r--r-- | utils/hwstub/lib/hwstub.c | 121 |
1 files changed, 30 insertions, 91 deletions
diff --git a/utils/hwstub/lib/hwstub.c b/utils/hwstub/lib/hwstub.c index 41842fb181..67a797ddfe 100644 --- a/utils/hwstub/lib/hwstub.c +++ b/utils/hwstub/lib/hwstub.c | |||
@@ -19,69 +19,55 @@ | |||
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #include "hwstub.h" | 21 | #include "hwstub.h" |
22 | #include <string.h> | ||
23 | #include <stdlib.h> | ||
22 | 24 | ||
23 | #ifndef MIN | 25 | #ifndef MIN |
24 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) | 26 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) |
25 | #endif | 27 | #endif |
26 | 28 | ||
27 | /* requires then ->handle field only */ | 29 | struct hwstub_device_t |
28 | int hwstub_probe(struct hwstub_device_t *dev) | ||
29 | { | 30 | { |
31 | libusb_device_handle *handle; | ||
32 | int intf; | ||
33 | int bulk_in; | ||
34 | int bulk_out; | ||
35 | int int_in; | ||
36 | }; | ||
37 | |||
38 | struct hwstub_device_t *hwstub_open(libusb_device_handle *handle) | ||
39 | { | ||
40 | struct hwstub_device_t *dev = malloc(sizeof(struct hwstub_device_t)); | ||
41 | memset(dev, 0, sizeof(struct hwstub_device_t)); | ||
42 | dev->handle = handle; | ||
30 | libusb_device *mydev = libusb_get_device(dev->handle); | 43 | libusb_device *mydev = libusb_get_device(dev->handle); |
31 | 44 | ||
32 | int config_id; | 45 | int config_id; |
33 | libusb_get_configuration(dev->handle, &config_id); | 46 | libusb_get_configuration(dev->handle, &config_id); |
34 | struct libusb_config_descriptor *config; | 47 | struct libusb_device_descriptor dev_desc; |
35 | libusb_get_active_config_descriptor(mydev, &config); | 48 | libusb_get_device_descriptor(mydev, &dev_desc); |
36 | 49 | if(dev_desc.bDeviceClass != HWSTUB_CLASS || | |
37 | const struct libusb_endpoint_descriptor *endp = NULL; | 50 | dev_desc.bDeviceSubClass != HWSTUB_SUBCLASS || |
38 | int intf; | 51 | dev_desc.bDeviceProtocol != HWSTUB_PROTOCOL) |
39 | for(intf = 0; intf < config->bNumInterfaces; intf++) | 52 | goto Lerr; |
40 | { | 53 | return dev; |
41 | if(config->interface[intf].num_altsetting != 1) | ||
42 | continue; | ||
43 | const struct libusb_interface_descriptor *interface = | ||
44 | &config->interface[intf].altsetting[0]; | ||
45 | if(interface->bNumEndpoints != 3 || | ||
46 | interface->bInterfaceClass != HWSTUB_CLASS || | ||
47 | interface->bInterfaceSubClass != HWSTUB_SUBCLASS || | ||
48 | interface->bInterfaceProtocol != HWSTUB_PROTOCOL) | ||
49 | continue; | ||
50 | dev->intf = intf; | ||
51 | dev->bulk_in = dev->bulk_out = dev->int_in = -1; | ||
52 | for(int ep = 0; ep < interface->bNumEndpoints; ep++) | ||
53 | { | ||
54 | endp = &interface->endpoint[ep]; | ||
55 | if((endp->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_INTERRUPT && | ||
56 | (endp->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) | ||
57 | dev->int_in = endp->bEndpointAddress; | ||
58 | if((endp->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK && | ||
59 | (endp->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) | ||
60 | dev->bulk_in = endp->bEndpointAddress; | ||
61 | if((endp->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK && | ||
62 | (endp->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) | ||
63 | dev->bulk_out = endp->bEndpointAddress; | ||
64 | } | ||
65 | if(dev->bulk_in == -1 || dev->bulk_out == -1 || dev->int_in == -1) | ||
66 | continue; | ||
67 | break; | ||
68 | } | ||
69 | if(intf == config->bNumInterfaces) | ||
70 | return 1; | ||
71 | 54 | ||
72 | return libusb_claim_interface(dev->handle, intf); | 55 | Lerr: |
56 | free(dev); | ||
57 | return NULL; | ||
73 | } | 58 | } |
74 | 59 | ||
75 | int hwstub_release(struct hwstub_device_t *dev) | 60 | int hwstub_release(struct hwstub_device_t *dev) |
76 | { | 61 | { |
77 | return libusb_release_interface(dev->handle, dev->intf); | 62 | free(dev); |
63 | return 0; | ||
78 | } | 64 | } |
79 | 65 | ||
80 | int hwstub_get_info(struct hwstub_device_t *dev, uint16_t idx, void *info, size_t sz) | 66 | int hwstub_get_desc(struct hwstub_device_t *dev, uint16_t desc, void *info, size_t sz) |
81 | { | 67 | { |
82 | return libusb_control_transfer(dev->handle, | 68 | return libusb_control_transfer(dev->handle, |
83 | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, | 69 | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, |
84 | HWSTUB_GET_INFO, 0, idx, info, sz, 1000); | 70 | LIBUSB_REQUEST_GET_DESCRIPTOR, desc << 8, 0, info, sz, 1000); |
85 | } | 71 | } |
86 | 72 | ||
87 | int hwstub_get_log(struct hwstub_device_t *dev, void *buf, size_t sz) | 73 | int hwstub_get_log(struct hwstub_device_t *dev, void *buf, size_t sz) |
@@ -126,50 +112,3 @@ int hwstub_jump(struct hwstub_device_t *dev, uint32_t addr) | |||
126 | LIBUSB_ENDPOINT_OUT, HWSTUB_JUMP, addr & 0xffff, addr >> 16, NULL, 0, | 112 | LIBUSB_ENDPOINT_OUT, HWSTUB_JUMP, addr & 0xffff, addr >> 16, NULL, 0, |
127 | 1000); | 113 | 1000); |
128 | } | 114 | } |
129 | |||
130 | const char *hwstub_get_product_string(struct usb_resp_info_stmp_t *stmp) | ||
131 | { | ||
132 | switch(stmp->chipid) | ||
133 | { | ||
134 | case 0x3700: return "STMP 3700"; | ||
135 | case 0x37b0: return "STMP 3770"; | ||
136 | case 0x3780: return "STMP 3780 / i.MX233"; | ||
137 | default: return "unknown"; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | const char *hwstub_get_rev_string(struct usb_resp_info_stmp_t *stmp) | ||
142 | { | ||
143 | switch(stmp->chipid) | ||
144 | { | ||
145 | case 0x37b0: | ||
146 | case 0x3780: | ||
147 | switch(stmp->rev) | ||
148 | { | ||
149 | case 0: return "TA1"; | ||
150 | case 1: return "TA2"; | ||
151 | case 2: return "TA3"; | ||
152 | case 3: return "TA4"; | ||
153 | default: return "unknown"; | ||
154 | } | ||
155 | break; | ||
156 | default: | ||
157 | return "unknown"; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | int hwstub_atexit(struct hwstub_device_t *dev, int method) | ||
162 | { | ||
163 | return libusb_control_transfer(dev->handle, | ||
164 | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | | ||
165 | LIBUSB_ENDPOINT_OUT, HWSTUB_ATEXIT, 0, method, NULL, 0, | ||
166 | 1000); | ||
167 | } | ||
168 | |||
169 | int hwstub_exit(struct hwstub_device_t *dev) | ||
170 | { | ||
171 | return libusb_control_transfer(dev->handle, | ||
172 | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | | ||
173 | LIBUSB_ENDPOINT_OUT, HWSTUB_EXIT, 0, 0, NULL, 0, | ||
174 | 1000); | ||
175 | } | ||