Merge branch 'vendor/OPENSSL'
[dragonfly.git] / sys / bus / u4b / usb_pf.c
1 /*-
2  * Copyright (c) 1990, 1991, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from the Stanford/CMU enet packet filter,
6  * (net/enet.c) distributed as part of 4.3BSD, and code contributed
7  * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
8  * Berkeley Laboratory.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34
35 #include <sys/param.h>
36 #include <sys/kernel.h>
37 #include <sys/bus.h>
38 #include <sys/fcntl.h>
39 #include <sys/malloc.h>
40 #include <sys/proc.h>
41 #include <sys/socket.h>
42 #include <sys/sockio.h>
43 #include <net/if.h>
44 #include <net/if_types.h>
45 #include <net/bpf.h>
46 #include <sys/sysctl.h>
47 #include <sys/condvar.h>
48
49 #include <bus/u4b/usb.h>
50 #include <bus/u4b/usbdi.h>
51 #include <bus/u4b/usb_busdma.h>
52
53 #include <bus/u4b/usb_controller.h>
54 #include <bus/u4b/usb_core.h>
55 #include <bus/u4b/usb_process.h>
56 #include <bus/u4b/usb_device.h>
57 #include <bus/u4b/usb_bus.h>
58 #include <bus/u4b/usb_pf.h>
59 #include <bus/u4b/usb_transfer.h>
60 static void usbpf_init(void *);
61 static void usbpf_uninit(void *);
62 static int usbpf_ioctl(struct ifnet *, u_long, caddr_t);
63 static int usbpf_clone_match(struct if_clone *, const char *);
64 static int usbpf_clone_create(struct if_clone *, char *, size_t, caddr_t);
65 static int usbpf_clone_destroy(struct if_clone *, struct ifnet *);
66 static struct usb_bus *usbpf_ifname2ubus(const char *);
67 static uint32_t usbpf_aggregate_xferflags(struct usb_xfer_flags *);
68 static uint32_t usbpf_aggregate_status(struct usb_xfer_flags_int *);
69 static int usbpf_xfer_frame_is_read(struct usb_xfer *, uint32_t);
70 static uint32_t usbpf_xfer_precompute_size(struct usb_xfer *, int);
71
72 static struct if_clone *usbpf_cloner;
73 static const char usbusname[] = "usbus";
74
75 SYSINIT(usbpf_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_init, NULL);
76 SYSUNINIT(usbpf_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_uninit, NULL);
77
78 static void
79 usbpf_uninit(void *arg)
80 {
81         int devlcnt;
82         device_t *devlp;
83         devclass_t dc;
84         struct usb_bus *ubus;
85         int error;
86         int i;
87         
88         if_clone_detach(usbpf_cloner);
89
90         dc = devclass_find(usbusname);
91         if (dc == NULL)
92                 return;
93         error = devclass_get_devices(dc, &devlp, &devlcnt);
94         if (error)
95                 return;
96         for (i = 0; i < devlcnt; i++) {
97                 ubus = device_get_softc(devlp[i]);
98                 if (ubus != NULL && ubus->ifp != NULL)
99                         usbpf_clone_destroy(usbpf_cloner, ubus->ifp);
100         }
101         free(devlp, M_TEMP);
102 }
103
104 static int
105 usbpf_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
106 {
107         
108         /* No configuration allowed. */
109         return (EINVAL);
110 }
111
112 static struct usb_bus *
113 usbpf_ifname2ubus(const char *ifname)
114 {
115         device_t dev;
116         devclass_t dc;
117         int unit;
118         int error;
119
120         if (strncmp(ifname, usbusname, sizeof(usbusname) - 1) != 0)
121                 return (NULL);
122         error = ifc_name2unit(ifname, &unit);
123         if (error || unit < 0)
124                 return (NULL);
125         dc = devclass_find(usbusname);
126         if (dc == NULL)
127                 return (NULL);
128         dev = devclass_get_device(dc, unit);
129         if (dev == NULL)
130                 return (NULL);
131
132         return (device_get_softc(dev));
133 }
134
135 static int
136 usbpf_clone_match(struct if_clone *ifc, const char *name)
137 {
138         struct usb_bus *ubus;
139
140         ubus = usbpf_ifname2ubus(name);
141         if (ubus == NULL)
142                 return (0);
143         if (ubus->ifp != NULL)
144                 return (0);
145
146         return (1);
147 }
148
149 static int
150 usbpf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
151 {
152         int error;
153         int unit;
154         struct ifnet *ifp;
155         struct usb_bus *ubus;
156
157         error = ifc_name2unit(name, &unit);
158         if (error)
159                 return (error);
160         if (unit < 0)
161                 return (EINVAL);
162
163         ubus = usbpf_ifname2ubus(name);
164         if (ubus == NULL)
165                 return (1);
166         if (ubus->ifp != NULL)
167                 return (1);
168
169         error = ifc_alloc_unit(ifc, &unit);
170         if (error) {
171                 device_printf(ubus->parent, "usbpf: Could not allocate "
172                     "instance\n");
173                 return (error);
174         }
175         ifp = ubus->ifp = if_alloc(IFT_USB);
176         if (ifp == NULL) {
177                 ifc_free_unit(ifc, unit);
178                 device_printf(ubus->parent, "usbpf: Could not allocate "
179                     "instance\n");
180                 return (ENOSPC);
181         }
182         strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname));
183         ifp->if_softc = ubus;
184         ifp->if_dname = usbusname;
185         ifp->if_dunit = unit;
186         ifp->if_ioctl = usbpf_ioctl;
187         if_attach(ifp);
188         ifp->if_flags |= IFF_UP;
189         rt_ifmsg(ifp);
190         /*
191          * XXX According to the specification of DLT_USB, it indicates
192          * packets beginning with USB setup header. But not sure all
193          * packets would be.
194          */
195         bpfattach(ifp, DLT_USB, USBPF_HDR_LEN);
196
197         return (0);
198 }
199
200 static int
201 usbpf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
202 {
203         struct usb_bus *ubus;
204         int unit;
205
206         ubus = ifp->if_softc;
207         unit = ifp->if_dunit;
208
209         ubus->ifp = NULL;
210         bpfdetach(ifp);
211         if_detach(ifp);
212         if_free(ifp);
213         ifc_free_unit(ifc, unit);
214         
215         return (0);
216 }
217
218 void
219 usbpf_attach(struct usb_bus *ubus)
220 {
221
222         if (bootverbose)
223                 device_printf(ubus->parent, "usbpf: Attached\n");
224 }
225
226 void
227 usbpf_detach(struct usb_bus *ubus)
228 {
229
230         if (ubus->ifp != NULL)
231                 usbpf_clone_destroy(usbpf_cloner, ubus->ifp);
232         if (bootverbose)
233                 device_printf(ubus->parent, "usbpf: Detached\n");
234 }
235
236 static uint32_t
237 usbpf_aggregate_xferflags(struct usb_xfer_flags *flags)
238 {
239         uint32_t val = 0;
240
241         if (flags->force_short_xfer == 1)
242                 val |= USBPF_FLAG_FORCE_SHORT_XFER;
243         if (flags->short_xfer_ok == 1)
244                 val |= USBPF_FLAG_SHORT_XFER_OK;
245         if (flags->short_frames_ok == 1)
246                 val |= USBPF_FLAG_SHORT_FRAMES_OK;
247         if (flags->pipe_bof == 1)
248                 val |= USBPF_FLAG_PIPE_BOF;
249         if (flags->proxy_buffer == 1)
250                 val |= USBPF_FLAG_PROXY_BUFFER;
251         if (flags->ext_buffer == 1)
252                 val |= USBPF_FLAG_EXT_BUFFER;
253         if (flags->manual_status == 1)
254                 val |= USBPF_FLAG_MANUAL_STATUS;
255         if (flags->no_pipe_ok == 1)
256                 val |= USBPF_FLAG_NO_PIPE_OK;
257         if (flags->stall_pipe == 1)
258                 val |= USBPF_FLAG_STALL_PIPE;
259         return (val);
260 }
261
262 static uint32_t
263 usbpf_aggregate_status(struct usb_xfer_flags_int *flags)
264 {
265         uint32_t val = 0;
266
267         if (flags->open == 1)
268                 val |= USBPF_STATUS_OPEN;
269         if (flags->transferring == 1)
270                 val |= USBPF_STATUS_TRANSFERRING;
271         if (flags->did_dma_delay == 1)
272                 val |= USBPF_STATUS_DID_DMA_DELAY;
273         if (flags->did_close == 1)
274                 val |= USBPF_STATUS_DID_CLOSE;
275         if (flags->draining == 1)
276                 val |= USBPF_STATUS_DRAINING;
277         if (flags->started == 1)
278                 val |= USBPF_STATUS_STARTED;
279         if (flags->bandwidth_reclaimed == 1)
280                 val |= USBPF_STATUS_BW_RECLAIMED;
281         if (flags->control_xfr == 1)
282                 val |= USBPF_STATUS_CONTROL_XFR;
283         if (flags->control_hdr == 1)
284                 val |= USBPF_STATUS_CONTROL_HDR;
285         if (flags->control_act == 1)
286                 val |= USBPF_STATUS_CONTROL_ACT;
287         if (flags->control_stall == 1)
288                 val |= USBPF_STATUS_CONTROL_STALL;
289         if (flags->short_frames_ok == 1)
290                 val |= USBPF_STATUS_SHORT_FRAMES_OK;
291         if (flags->short_xfer_ok == 1)
292                 val |= USBPF_STATUS_SHORT_XFER_OK;
293 #if USB_HAVE_BUSDMA
294         if (flags->bdma_enable == 1)
295                 val |= USBPF_STATUS_BDMA_ENABLE;
296         if (flags->bdma_no_post_sync == 1)
297                 val |= USBPF_STATUS_BDMA_NO_POST_SYNC;
298         if (flags->bdma_setup == 1)
299                 val |= USBPF_STATUS_BDMA_SETUP;
300 #endif
301         if (flags->isochronous_xfr == 1)
302                 val |= USBPF_STATUS_ISOCHRONOUS_XFR;
303         if (flags->curr_dma_set == 1)
304                 val |= USBPF_STATUS_CURR_DMA_SET;
305         if (flags->can_cancel_immed == 1)
306                 val |= USBPF_STATUS_CAN_CANCEL_IMMED;
307         if (flags->doing_callback == 1)
308                 val |= USBPF_STATUS_DOING_CALLBACK;
309
310         return (val);
311 }
312
313 static int
314 usbpf_xfer_frame_is_read(struct usb_xfer *xfer, uint32_t frame)
315 {
316         int isread;
317
318         if ((frame == 0) && (xfer->flags_int.control_xfr != 0) &&
319             (xfer->flags_int.control_hdr != 0)) {
320                 /* special case */
321                 if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) {
322                         /* The device controller writes to memory */
323                         isread = 1;
324                 } else {
325                         /* The host controller reads from memory */
326                         isread = 0;
327                 }
328         } else {
329                 isread = USB_GET_DATA_ISREAD(xfer);
330         }
331         return (isread);
332 }
333
334 static uint32_t
335 usbpf_xfer_precompute_size(struct usb_xfer *xfer, int type)
336 {
337         uint32_t totlen;
338         uint32_t x;
339         uint32_t nframes;
340
341         if (type == USBPF_XFERTAP_SUBMIT)
342                 nframes = xfer->nframes;
343         else
344                 nframes = xfer->aframes;
345
346         totlen = USBPF_HDR_LEN + (USBPF_FRAME_HDR_LEN * nframes);
347
348         /* precompute all trace lengths */
349         for (x = 0; x != nframes; x++) {
350                 if (usbpf_xfer_frame_is_read(xfer, x)) {
351                         if (type != USBPF_XFERTAP_SUBMIT) {
352                                 totlen += USBPF_FRAME_ALIGN(
353                                     xfer->frlengths[x]);
354                         }
355                 } else {
356                         if (type == USBPF_XFERTAP_SUBMIT) {
357                                 totlen += USBPF_FRAME_ALIGN(
358                                     xfer->frlengths[x]);
359                         }
360                 }
361         }
362         return (totlen);
363 }
364
365 void
366 usbpf_xfertap(struct usb_xfer *xfer, int type)
367 {
368         struct usb_bus *bus;
369         struct usbpf_pkthdr *up;
370         struct usbpf_framehdr *uf;
371         usb_frlength_t offset;
372         uint32_t totlen;
373         uint32_t frame;
374         uint32_t temp;
375         uint32_t nframes;
376         uint32_t x;
377         uint8_t *buf;
378         uint8_t *ptr;
379
380         bus = xfer->xroot->bus;
381
382         /* sanity checks */
383         if (bus->ifp == NULL)
384                 return;
385         if (!bpf_peers_present(bus->ifp->if_bpf))
386                 return;
387
388         totlen = usbpf_xfer_precompute_size(xfer, type);
389
390         if (type == USBPF_XFERTAP_SUBMIT)
391                 nframes = xfer->nframes;
392         else
393                 nframes = xfer->aframes;
394
395         /*
396          * XXX TODO XXX
397          *
398          * When BPF supports it we could pass a fragmented array of
399          * buffers avoiding the data copy operation here.
400          */
401         buf = ptr = malloc(totlen, M_TEMP, M_NOWAIT);
402         if (buf == NULL) {
403                 device_printf(bus->parent, "usbpf: Out of memory\n");
404                 return;
405         }
406
407         up = (struct usbpf_pkthdr *)ptr;
408         ptr += USBPF_HDR_LEN;
409
410         /* fill out header */
411         temp = device_get_unit(bus->bdev);
412         up->up_totlen = htole32(totlen);
413         up->up_busunit = htole32(temp);
414         up->up_address = xfer->xroot->udev->device_index;
415         if (xfer->flags_int.usb_mode == USB_MODE_DEVICE)
416                 up->up_mode = USBPF_MODE_DEVICE;
417         else
418                 up->up_mode = USBPF_MODE_HOST;
419         up->up_type = type;
420         up->up_xfertype = xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE;
421         temp = usbpf_aggregate_xferflags(&xfer->flags);
422         up->up_flags = htole32(temp);
423         temp = usbpf_aggregate_status(&xfer->flags_int);
424         up->up_status = htole32(temp);
425         temp = xfer->error;
426         up->up_error = htole32(temp);
427         temp = xfer->interval;
428         up->up_interval = htole32(temp);
429         up->up_frames = htole32(nframes);
430         temp = xfer->max_packet_size;
431         up->up_packet_size = htole32(temp);
432         temp = xfer->max_packet_count;
433         up->up_packet_count = htole32(temp);
434         temp = xfer->endpointno;
435         up->up_endpoint = htole32(temp);
436         up->up_speed = xfer->xroot->udev->speed;
437
438         /* clear reserved area */
439         memset(up->up_reserved, 0, sizeof(up->up_reserved));
440
441         /* init offset and frame */
442         offset = 0;
443         frame = 0;
444
445         /* iterate all the USB frames and copy data, if any */
446         for (x = 0; x != nframes; x++) {
447                 uint32_t length;
448                 int isread;
449
450                 /* get length */
451                 length = xfer->frlengths[x];
452
453                 /* get frame header pointer */
454                 uf = (struct usbpf_framehdr *)ptr;
455                 ptr += USBPF_FRAME_HDR_LEN;
456
457                 /* fill out packet header */
458                 uf->length = htole32(length);
459                 uf->flags = 0;
460
461                 /* get information about data read/write */
462                 isread = usbpf_xfer_frame_is_read(xfer, x);
463
464                 /* check if we need to copy any data */
465                 if (isread) {
466                         if (type == USBPF_XFERTAP_SUBMIT)
467                                 length = 0;
468                         else {
469                                 uf->flags |= htole32(
470                                     USBPF_FRAMEFLAG_DATA_FOLLOWS);
471                         }
472                 } else {
473                         if (type != USBPF_XFERTAP_SUBMIT)
474                                 length = 0;
475                         else {
476                                 uf->flags |= htole32(
477                                     USBPF_FRAMEFLAG_DATA_FOLLOWS);
478                         }
479                 }
480
481                 /* check if data is read direction */
482                 if (isread)
483                         uf->flags |= htole32(USBPF_FRAMEFLAG_READ);
484
485                 /* copy USB data, if any */
486                 if (length != 0) {
487                         /* copy data */
488                         usbd_copy_out(&xfer->frbuffers[frame],
489                             offset, ptr, length);
490
491                         /* align length */
492                         temp = USBPF_FRAME_ALIGN(length);
493
494                         /* zero pad */
495                         if (temp != length)
496                                 memset(ptr + length, 0, temp - length);
497
498                         ptr += temp;
499                 }
500
501                 if (xfer->flags_int.isochronous_xfr) {
502                         offset += usbd_xfer_old_frame_length(xfer, x);
503                 } else {
504                         frame ++;
505                 }
506         }
507
508         bpf_tap(bus->ifp->if_bpf, buf, totlen);
509
510         free(buf, M_TEMP);
511 }