1906943f9SDavid du Colombier /* 2906943f9SDavid du Colombier * Standard usb ethernet communications device. 3906943f9SDavid du Colombier */ 4906943f9SDavid du Colombier #include <u.h> 5906943f9SDavid du Colombier #include <libc.h> 6906943f9SDavid du Colombier #include <fcall.h> 7906943f9SDavid du Colombier #include <thread.h> 8906943f9SDavid du Colombier #include "usb.h" 9906943f9SDavid du Colombier #include "usbfs.h" 10906943f9SDavid du Colombier #include "ether.h" 11906943f9SDavid du Colombier 12906943f9SDavid du Colombier static int okclass(Iface * iface)13906943f9SDavid du Colombierokclass(Iface *iface) 14906943f9SDavid du Colombier { 15906943f9SDavid du Colombier return Class(iface->csp) == Clcomms && Subclass(iface->csp) == Scether; 16906943f9SDavid du Colombier } 17906943f9SDavid du Colombier 18906943f9SDavid du Colombier static int getmac(Ether * ether)19906943f9SDavid du Colombiergetmac(Ether *ether) 20906943f9SDavid du Colombier { 21906943f9SDavid du Colombier int i; 22906943f9SDavid du Colombier Usbdev *ud; 23906943f9SDavid du Colombier uchar *b; 24906943f9SDavid du Colombier Desc *dd; 25906943f9SDavid du Colombier char *mac; 26906943f9SDavid du Colombier 27906943f9SDavid du Colombier ud = ether->dev->usb; 28906943f9SDavid du Colombier 29906943f9SDavid du Colombier for(i = 0; i < nelem(ud->ddesc); i++) 30906943f9SDavid du Colombier if((dd = ud->ddesc[i]) != nil && okclass(dd->iface)){ 31906943f9SDavid du Colombier b = (uchar*)&dd->data; 32906943f9SDavid du Colombier if(b[1] == Dfunction && b[2] == Fnether){ 33906943f9SDavid du Colombier mac = loaddevstr(ether->dev, b[3]); 34906943f9SDavid du Colombier if(mac != nil && strlen(mac) != 12){ 35906943f9SDavid du Colombier free(mac); 36906943f9SDavid du Colombier mac = nil; 37906943f9SDavid du Colombier } 38906943f9SDavid du Colombier if(mac != nil){ 39906943f9SDavid du Colombier parseaddr(ether->addr, mac); 40906943f9SDavid du Colombier free(mac); 41906943f9SDavid du Colombier return 0; 42906943f9SDavid du Colombier } 43906943f9SDavid du Colombier } 44906943f9SDavid du Colombier } 45906943f9SDavid du Colombier return -1; 46906943f9SDavid du Colombier } 47906943f9SDavid du Colombier 48906943f9SDavid du Colombier int cdcreset(Ether * ether)49906943f9SDavid du Colombiercdcreset(Ether *ether) 50906943f9SDavid du Colombier { 51*d4df0e25SDavid du Colombier Usbdev *ud; 52*d4df0e25SDavid du Colombier Ep *ep; 53*d4df0e25SDavid du Colombier int i; 54*d4df0e25SDavid du Colombier 55906943f9SDavid du Colombier /* 56906943f9SDavid du Colombier * Assume that all communication devices are going to 57906943f9SDavid du Colombier * be std. ethernet communication devices. Specific controllers 58906943f9SDavid du Colombier * must have been probed first. 59906943f9SDavid du Colombier */ 60*d4df0e25SDavid du Colombier ud = ether->dev->usb; 61*d4df0e25SDavid du Colombier if(ud->class == Clcomms) 62906943f9SDavid du Colombier return getmac(ether); 63*d4df0e25SDavid du Colombier if(getmac(ether) == 0){ 64*d4df0e25SDavid du Colombier for(i = 0; i < Nep; i++){ 65*d4df0e25SDavid du Colombier ep = ud->ep[i]; 66*d4df0e25SDavid du Colombier if(ep == nil) 67*d4df0e25SDavid du Colombier continue; 68*d4df0e25SDavid du Colombier if(ep->iface == nil || !okclass(ep->iface)) 69*d4df0e25SDavid du Colombier continue; 70*d4df0e25SDavid du Colombier if(ep->conf->cval != 1) 71*d4df0e25SDavid du Colombier usbcmd(ether->dev, Rh2d|Rstd|Rdev, Rsetconf, ep->conf->cval, 0, nil, 0); 72*d4df0e25SDavid du Colombier return 0; 73*d4df0e25SDavid du Colombier } 74*d4df0e25SDavid du Colombier } 75906943f9SDavid du Colombier return -1; 76906943f9SDavid du Colombier } 77