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

Revision 1137, 4.9 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 * Generic IFD device layer
3 *
4 * Copyright (C) 2003 Olaf Kirch <okir@suse.de>
5 */
6
7#include "internal.h"
8#include <stdlib.h>
9#include <string.h>
10
11/*
12 * Open a device given the name
13 */
14ifd_device_t *ifd_device_open(const char *name)
15{
16        if (name == NULL) {
17                ct_error("Null device");
18                return NULL;
19        }
20
21        if (!strncmp(name, "serial:", 7))
22                return ifd_open_serial(name + 7);
23        if (!strncmp(name, "usb:", 4))
24                return ifd_open_usb(name + 4);
25        if (!strncmp(name, "remote:", 7))
26                return ifd_open_remote(name + 7);
27        if (!strncmp(name, "pcmcia:", 7))
28                return ifd_open_pcmcia(name + 7);
29        if (!strncmp(name, "pcmcia_block:", 13))
30                return ifd_open_pcmcia_block(name + 13);
31
32        ct_error("Unknown device type \"%s\"", name);
33        return NULL;
34}
35
36/*
37 * Create a new device struct
38 * This is an internal function called by the different device
39 * type handlers (serial, usb, etc)
40 */
41ifd_device_t *ifd_device_new(const char *name, struct ifd_device_ops * ops,
42                             size_t size)
43{
44        ifd_device_t *dev;
45
46        dev = (ifd_device_t *) calloc(1, size);
47        if (!dev) {
48                ct_error("out of memory");
49                return NULL;
50        }
51        dev->name = strdup(name);
52        dev->ops = ops;
53
54        return dev;
55}
56
57/*
58 * Destroy a device handle
59 */
60void ifd_device_free(ifd_device_t * dev)
61{
62        if (dev->name)
63                free(dev->name);
64        memset(dev, 0, sizeof(*dev));
65        free(dev);
66}
67
68/*
69 * Miscellaneous device operations. These functions
70 * just do a consistency check on the handle, and route
71 * the call to the appropriate member function
72 */
73int ifd_device_type(ifd_device_t * dev)
74{
75        return dev->type;
76}
77
78int ifd_device_reset(ifd_device_t * dev)
79{
80        if (!dev || !dev->ops || !dev->ops->reset)
81                return IFD_ERROR_NOT_SUPPORTED;
82        return dev->ops->reset(dev);
83}
84
85void ifd_device_set_hotplug(ifd_device_t * dev, int hotplug)
86{
87        if (hotplug)
88                dev->hotplug = 1;
89}
90
91int ifd_device_set_parameters(ifd_device_t * dev,
92                              const ifd_device_params_t * parms)
93{
94        if (!dev || !dev->ops || !dev->ops->set_params)
95                return IFD_ERROR_NOT_SUPPORTED;
96        return dev->ops->set_params(dev, parms);
97}
98
99int ifd_device_get_parameters(ifd_device_t * dev, ifd_device_params_t * parms)
100{
101        if (!dev || !dev->ops || !dev->ops->get_params)
102                return IFD_ERROR_NOT_SUPPORTED;
103        return dev->ops->get_params(dev, parms);
104}
105
106void ifd_device_flush(ifd_device_t * dev)
107{
108        if (!dev || !dev->ops || !dev->ops->flush)
109                return;
110        dev->ops->flush(dev);
111}
112
113void ifd_device_send_break(ifd_device_t * dev, unsigned int usec)
114{
115        if (!dev || !dev->ops || !dev->ops->send_break)
116                return;
117        dev->ops->send_break(dev, usec);
118}
119
120int ifd_device_send(ifd_device_t * dev, const unsigned char *data, size_t len)
121{
122        if (!dev || !dev->ops || !dev->ops->send)
123                return IFD_ERROR_NOT_SUPPORTED;
124        return dev->ops->send(dev, data, len);
125}
126
127int ifd_device_control(ifd_device_t * dev, void *cmsg, size_t len)
128{
129        if (!dev || !dev->ops || !dev->ops->control)
130                return IFD_ERROR_NOT_SUPPORTED;
131        return dev->ops->control(dev, cmsg, len);
132}
133
134int ifd_device_recv(ifd_device_t * dev, unsigned char *data, size_t len,
135                    long timeout)
136{
137        if (timeout < 0)
138                timeout = dev->timeout;
139
140        if (!dev || !dev->ops || !dev->ops->recv)
141                return IFD_ERROR_NOT_SUPPORTED;
142        return dev->ops->recv(dev, data, len, timeout);
143}
144
145int ifd_device_transceive(ifd_device_t * dev, const void *sbuf, size_t slen,
146                          void *rbuf, size_t rlen, long timeout)
147{
148        int rc;
149
150        if (timeout < 0)
151                timeout = dev->timeout;
152
153        if (!dev || !dev->ops)
154                return -1;
155        if (dev->ops->transceive)
156                return dev->ops->transceive(dev,
157                                            sbuf, slen, rbuf, rlen, timeout);
158
159        /* Fall back to send/recv */
160        ifd_device_flush(dev);
161        if ((rc = ifd_device_send(dev, (const unsigned char *)sbuf, slen)) < 0)
162                return rc;
163        return ifd_device_recv(dev, (unsigned char *)rbuf, rlen, timeout);
164}
165
166int ifd_device_poll_presence(ifd_device_t * dev, struct pollfd *pfd)
167{
168        if (!dev || !dev->ops || !dev->ops->poll_presence)
169                return 1;
170        return dev->ops->poll_presence(dev, pfd);
171}
172
173int ifd_device_get_eventfd(ifd_device_t * dev, short *events)
174{
175        if (!dev || !dev->ops)
176                return -1;
177        if (!dev->ops->get_eventfd)
178                return -1;
179        return dev->ops->get_eventfd(dev, events);
180}
181
182void ifd_device_close(ifd_device_t * dev)
183{
184        if (!dev)
185                return;
186        if (dev->ops && dev->ops->close)
187                dev->ops->close(dev);
188        ifd_device_free(dev);
189}
190
191/*
192 * Device ID handling
193 */
194int ifd_device_id_parse(const char *str, ifd_devid_t * id)
195{
196        unsigned int n;
197
198        id->type = IFD_DEVICE_TYPE_OTHER;
199
200        n = strcspn(str, ":");
201        if (str[n] == ':') {
202                if (!strncmp(str, "usb", n))
203                        id->type = IFD_DEVICE_TYPE_USB;
204                else if (!strncmp(str, "pcmcia", n))
205                        id->type = IFD_DEVICE_TYPE_PCMCIA;
206                else
207                        return -1;
208                str += n + 1;
209        }
210
211        for (n = 0; *str && n < IFD_MAX_DEVID_PARTS; n++) {
212                id->val[n] = strtoul(str, (char **)&str, 16);
213                if (*str == '/')
214                        str++;
215        }
216
217        if (*str || n == 0)
218                return -1;
219        id->num = n;
220        return 0;
221}
222
223int ifd_device_id_match(const ifd_devid_t * match, const ifd_devid_t * id)
224{
225        if (id->type != match->type
226            || id->num < match->num
227            || memcmp(id->val, match->val, match->num * sizeof(id->val[0])))
228                return 0;
229        return 1;
230}
Note: See TracBrowser for help on using the repository browser.