xref: /plan9/sys/src/cmd/usb/ether/cdc.c (revision 906943f9f6b8411972abb5e3a03ed19f74be7ccc)
1 /*
2  * Standard usb ethernet communications device.
3  */
4 #include <u.h>
5 #include <libc.h>
6 #include <fcall.h>
7 #include <thread.h>
8 #include "usb.h"
9 #include "usbfs.h"
10 #include "ether.h"
11 
12 static int
okclass(Iface * iface)13 okclass(Iface *iface)
14 {
15 	return Class(iface->csp) == Clcomms && Subclass(iface->csp) == Scether;
16 }
17 
18 static int
getmac(Ether * ether)19 getmac(Ether *ether)
20 {
21 	int i;
22 	Usbdev *ud;
23 	uchar *b;
24 	Desc *dd;
25 	char *mac;
26 
27 	ud = ether->dev->usb;
28 
29 	for(i = 0; i < nelem(ud->ddesc); i++)
30 		if((dd = ud->ddesc[i]) != nil && okclass(dd->iface)){
31 			b = (uchar*)&dd->data;
32 			if(b[1] == Dfunction && b[2] == Fnether){
33 				mac = loaddevstr(ether->dev, b[3]);
34 				if(mac != nil && strlen(mac) != 12){
35 					free(mac);
36 					mac = nil;
37 				}
38 				if(mac != nil){
39 					parseaddr(ether->addr, mac);
40 					free(mac);
41 					return 0;
42 				}
43 			}
44 		}
45 	return -1;
46 }
47 
48 int
cdcreset(Ether * ether)49 cdcreset(Ether *ether)
50 {
51 	/*
52 	 * Assume that all communication devices are going to
53 	 * be std. ethernet communication devices. Specific controllers
54 	 * must have been probed first.
55 	 * NB: This ignores unions.
56 	 */
57 	if(ether->dev->usb->class == Clcomms)
58 		return getmac(ether);
59 	return -1;
60 }
61