source: trunk/src/ifd/usb.c @ 1137

Revision 1137, 5.8 KB checked in by alonbl, 3 years ago (diff)

Allow driver to specify events to poll

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * USB device handling
3 *
4 * Copyright (C) 2003, Olaf Kirch <okir@suse.de>
5 */
6
7#include "internal.h"
8#include <sys/poll.h>
9#include <stdlib.h>
10#include <string.h>
11#include <fcntl.h>
12
13/*
14 * Send/receive USB control block
15 */
16int ifd_usb_control(ifd_device_t * dev, unsigned int requesttype,
17                    unsigned int request, unsigned int value,
18                    unsigned int idx, void *buffer, size_t len, long timeout)
19{
20        int n;
21
22        if (dev->type != IFD_DEVICE_TYPE_USB)
23                return -1;
24        if (timeout < 0)
25                timeout = 10000;
26
27        if ((ct_config.debug >= 3) && !(requesttype & 0x80)) {
28                ifd_debug(4,
29                          "usb req type=x%02x req=x%02x val=x%04x ind=x%04x len=%u",
30                          requesttype, request, value, idx, len);
31                if (len)
32                        ifd_debug(4, "send %s", ct_hexdump(buffer, len));
33        }
34
35        n = ifd_sysdep_usb_control(dev, requesttype, request, value, idx,
36                                   buffer, len, timeout);
37
38        if ((ct_config.debug >= 3) && (requesttype & 0x80)) {
39                ifd_debug(4,
40                          "usb req type=x%02x req=x%02x val=x%04x ind=x%04x len=%d",
41                          requesttype, request, value, idx, n);
42                if (n > 0)
43                        ifd_debug(4, "recv %s", ct_hexdump(buffer, n));
44        }
45
46        return n;
47}
48
49/*
50 * USB frame capture
51 */
52int ifd_usb_begin_capture(ifd_device_t * dev, int type, int endpoint,
53                          size_t maxpacket, ifd_usb_capture_t ** capret)
54{
55        if (dev->type != IFD_DEVICE_TYPE_USB)
56                return -1;
57
58        if (ct_config.debug >= 5)
59                ifd_debug(5, "usb capture type=%d ep=x%x maxpacket=%u",
60                          type, endpoint, maxpacket);
61        return ifd_sysdep_usb_begin_capture(dev, type, endpoint, maxpacket,
62                                            capret);
63}
64
65int ifd_usb_capture_event(ifd_device_t * dev, ifd_usb_capture_t * cap, void *buffer,
66                    size_t len)
67{
68        int rc;
69
70        if (dev->type != IFD_DEVICE_TYPE_USB)
71                return -1;
72
73        ifd_debug(5, "called.");
74        rc = ifd_sysdep_usb_capture_event(dev, cap, buffer, len);
75        if (ct_config.debug >= 3) {
76                if (rc < 0)
77                        ifd_debug(1, "usb event capture: %s", ct_strerror(rc));
78                if (rc > 0)
79                        ifd_debug(5, "usb event capture: recv %s",
80                                  ct_hexdump(buffer, rc));
81                if (rc == 0)
82                        ifd_debug(5, "usb event capture: rc=%d (timeout?)", rc);
83        }
84        return rc;
85}
86
87int ifd_usb_capture(ifd_device_t * dev, ifd_usb_capture_t * cap, void *buffer,
88                    size_t len, long timeout)
89{
90        int rc;
91
92        if (dev->type != IFD_DEVICE_TYPE_USB)
93                return -1;
94
95        ifd_debug(5, "called, timeout=%ld ms.", timeout);
96        rc = ifd_sysdep_usb_capture(dev, cap, buffer, len, timeout);
97        if (ct_config.debug >= 3) {
98                if (rc < 0)
99                        ifd_debug(1, "usb capture: %s", ct_strerror(rc));
100                if (rc > 0)
101                        ifd_debug(5, "usb capture: recv %s",
102                                  ct_hexdump(buffer, rc));
103                if (rc == 0)
104                        ifd_debug(5, "usb capture: rc=%d (timeout?)", rc);
105        }
106        return rc;
107}
108
109int ifd_usb_end_capture(ifd_device_t * dev, ifd_usb_capture_t * cap)
110{
111        ifd_debug(5, "called.");
112
113        if (dev->type != IFD_DEVICE_TYPE_USB)
114                return -1;
115        return ifd_sysdep_usb_end_capture(dev, cap);
116}
117
118/*
119 * Set usb params (for now, endpoint for transceive)
120 */
121static int usb_set_params(ifd_device_t * dev,
122                          const ifd_device_params_t * params)
123{
124
125        ifd_debug(1, "called. config x%02x ifc x%02x eps x%02x/x%02x",
126                  params->usb.configuration, params->usb.interface,
127                  params->usb.ep_o, params->usb.ep_i);
128        if (params->usb.interface != -1 && params->usb.interface > 255)
129                return IFD_ERROR_INVALID_ARG;
130        if (params->usb.ep_o != -1 && (params->usb.ep_o & ~0x7F))
131                return IFD_ERROR_INVALID_ARG;
132        if ((params->usb.ep_i != -1 && (params->usb.ep_i & ~0xFF))
133            || !(params->usb.ep_i & 0x80))
134                return IFD_ERROR_INVALID_ARG;
135
136        if (dev->settings.usb.interface != -1)
137                ifd_sysdep_usb_release_interface(dev,
138                                                 dev->settings.usb.interface);
139
140        if (params->usb.configuration != -1
141            && ifd_sysdep_usb_set_configuration(dev, params->usb.configuration))
142                return -1;
143
144        if (params->usb.interface != -1) {
145                if (ifd_sysdep_usb_claim_interface(dev, params->usb.interface))
146                        return -1;
147                if (params->usb.altsetting != -1
148                    && ifd_sysdep_usb_set_interface(dev,
149                                                    params->usb.interface,
150                                                    params->usb.altsetting))
151                        return -1;
152        }
153
154        dev->settings = *params;
155        return 0;
156}
157
158static int usb_send(ifd_device_t * dev, const unsigned char *send,
159                    size_t sendlen)
160{
161        if (dev->settings.usb.ep_o == -1)
162                return IFD_ERROR_NOT_SUPPORTED;
163        if (ct_config.debug >= 3) {
164                ifd_debug(4, "usb send to=x%02x", dev->settings.usb.ep_o);
165                if (sendlen)
166                        ifd_debug(4, "send %s", ct_hexdump(send, sendlen));
167        }
168
169        return ifd_sysdep_usb_bulk(dev,
170                                   dev->settings.usb.ep_o,
171                                   (unsigned char *)send, sendlen, 10000);
172}
173
174static int usb_recv(ifd_device_t * dev, unsigned char *recv, size_t recvlen,
175                    long timeout)
176{
177        int rc;
178
179        if (dev->settings.usb.ep_i == -1)
180                return IFD_ERROR_NOT_SUPPORTED;
181
182        rc = ifd_sysdep_usb_bulk(dev, dev->settings.usb.ep_i,
183                                 recv, recvlen, timeout);
184        if (rc >= 0 && ct_config.debug >= 4) {
185                ifd_debug(4, "usb recv from=x%02x", dev->settings.usb.ep_i);
186                if (rc > 0)
187                        ifd_debug(4, "recv %s", ct_hexdump(recv, rc));
188        }
189
190        return rc;
191}
192
193static int usb_reset(ifd_device_t * dev)
194{
195        int rc;
196
197        rc = ifd_sysdep_usb_reset(dev);
198
199        return rc;
200}
201
202static int usb_get_eventfd(ifd_device_t * dev, short *events)
203{
204        int rc;
205
206        rc = ifd_sysdep_usb_get_eventfd(dev, events);
207
208        return rc;
209}
210
211static struct ifd_device_ops ifd_usb_ops;
212
213/*
214 * Open USB device
215 */
216ifd_device_t *ifd_open_usb(const char *device)
217{
218        ifd_device_t *dev;
219        int fd;
220
221        if ((fd = ifd_sysdep_usb_open(device)) < 0) {
222                ct_error("Unable to open USB device %s: %m", device);
223                return NULL;
224        }
225
226        ifd_usb_ops.poll_presence = ifd_sysdep_usb_poll_presence;
227        ifd_usb_ops.set_params = usb_set_params;
228        ifd_usb_ops.send = usb_send;
229        ifd_usb_ops.recv = usb_recv;
230        ifd_usb_ops.reset = usb_reset;
231        ifd_usb_ops.get_eventfd = usb_get_eventfd;
232
233        dev = ifd_device_new(device, &ifd_usb_ops, sizeof(*dev));
234        dev->type = IFD_DEVICE_TYPE_USB;
235        dev->timeout = 10000;
236        dev->fd = fd;
237        dev->settings.usb.configuration = -1;
238        dev->settings.usb.interface = -1;
239        dev->settings.usb.altsetting = -1;
240        dev->settings.usb.ep_o = -1;
241        dev->settings.usb.ep_i = -1;
242
243        return dev;
244}
Note: See TracBrowser for help on using the repository browser.