1906943f9SDavid du Colombier typedef struct Hub Hub; 2906943f9SDavid du Colombier typedef struct Port Port; 3906943f9SDavid du Colombier typedef struct DHub DHub; 4*153f606aSDavid du Colombier typedef struct DSSHub DSSHub; 5906943f9SDavid du Colombier typedef struct Devtab Devtab; 6906943f9SDavid du Colombier typedef struct Usbfs Usbfs; 7906943f9SDavid du Colombier 8906943f9SDavid du Colombier enum 9906943f9SDavid du Colombier { 10906943f9SDavid du Colombier Stack = 32*1024, 11906943f9SDavid du Colombier 12906943f9SDavid du Colombier Dhub = 0x29, /* hub descriptor type */ 13906943f9SDavid du Colombier Dhublen = 9, /* hub descriptor length */ 14*153f606aSDavid du Colombier Dsshub = 0x2A, /* superspeed hub descriptor type */ 15*153f606aSDavid du Colombier Dsshublen = 12, /* superspeed hub descriptor length */ 16906943f9SDavid du Colombier 17906943f9SDavid du Colombier /* hub class feature selectors */ 18906943f9SDavid du Colombier Fhublocalpower = 0, 19906943f9SDavid du Colombier Fhubovercurrent = 1, 20906943f9SDavid du Colombier 21906943f9SDavid du Colombier Fportconnection = 0, 22906943f9SDavid du Colombier Fportenable = 1, 23906943f9SDavid du Colombier Fportsuspend = 2, 24906943f9SDavid du Colombier Fportovercurrent = 3, 25906943f9SDavid du Colombier Fportreset = 4, 26906943f9SDavid du Colombier Fportpower = 8, 27906943f9SDavid du Colombier Fportlowspeed = 9, 28906943f9SDavid du Colombier Fcportconnection = 16, 29906943f9SDavid du Colombier Fcportenable = 17, 30906943f9SDavid du Colombier Fcportsuspend = 18, 31906943f9SDavid du Colombier Fcportovercurrent= 19, 32906943f9SDavid du Colombier Fcportreset = 20, 33906943f9SDavid du Colombier Fportindicator = 22, 34906943f9SDavid du Colombier 35906943f9SDavid du Colombier /* Port status and status change bits 36906943f9SDavid du Colombier * Constants at /sys/src/9/pc/usb.h starting with HP- 37906943f9SDavid du Colombier * must have the same values or root hubs won't work. 38906943f9SDavid du Colombier */ 39906943f9SDavid du Colombier PSpresent = 0x0001, 40906943f9SDavid du Colombier PSenable = 0x0002, 41906943f9SDavid du Colombier PSsuspend = 0x0004, 42906943f9SDavid du Colombier PSovercurrent = 0x0008, 43906943f9SDavid du Colombier PSreset = 0x0010, 44906943f9SDavid du Colombier PSpower = 0x0100, 45906943f9SDavid du Colombier PSslow = 0x0200, 46906943f9SDavid du Colombier PShigh = 0x0400, 47906943f9SDavid du Colombier 48906943f9SDavid du Colombier PSstatuschg = 0x10000, /* PSpresent changed */ 49906943f9SDavid du Colombier PSchange = 0x20000, /* PSenable changed */ 50906943f9SDavid du Colombier 51906943f9SDavid du Colombier 52906943f9SDavid du Colombier /* port/device state */ 53906943f9SDavid du Colombier Pdisabled = 0, /* must be 0 */ 54906943f9SDavid du Colombier Pattached, 55906943f9SDavid du Colombier Pconfiged, 56906943f9SDavid du Colombier 57906943f9SDavid du Colombier /* Delays, timeouts (ms) */ 586083aa43SDavid du Colombier Spawndelay = 100, /* how often may we re-spawn a driver */ 59cb8c047aSDavid du Colombier Connectdelay = 500, /* how much to wait after a connect */ 60906943f9SDavid du Colombier Resetdelay = 20, /* how much to wait after a reset */ 61906943f9SDavid du Colombier Enabledelay = 20, /* how much to wait after an enable */ 62906943f9SDavid du Colombier Powerdelay = 100, /* after powering up ports */ 63906943f9SDavid du Colombier Pollms = 250, /* port poll interval */ 64906943f9SDavid du Colombier Chgdelay = 100, /* waiting for port become stable */ 65906943f9SDavid du Colombier Chgtmout = 1000, /* ...but at most this much */ 66906943f9SDavid du Colombier 67906943f9SDavid du Colombier /* 68906943f9SDavid du Colombier * device tab for embedded usb drivers. 69906943f9SDavid du Colombier */ 70906943f9SDavid du Colombier DCL = 0x01000000, /* csp identifies just class */ 71906943f9SDavid du Colombier DSC = 0x02000000, /* csp identifies just subclass */ 72906943f9SDavid du Colombier DPT = 0x04000000, /* csp identifies just proto */ 73906943f9SDavid du Colombier 74906943f9SDavid du Colombier }; 75906943f9SDavid du Colombier 76906943f9SDavid du Colombier struct Hub 77906943f9SDavid du Colombier { 78906943f9SDavid du Colombier uchar pwrmode; 79906943f9SDavid du Colombier uchar compound; 80906943f9SDavid du Colombier uchar pwrms; /* time to wait in ms */ 81906943f9SDavid du Colombier uchar maxcurrent; /* after powering port*/ 82906943f9SDavid du Colombier int leds; /* has port indicators? */ 83906943f9SDavid du Colombier int maxpkt; 84906943f9SDavid du Colombier uchar nport; 85906943f9SDavid du Colombier Port *port; 86906943f9SDavid du Colombier int failed; /* I/O error while enumerating */ 87906943f9SDavid du Colombier int isroot; /* set if root hub */ 88906943f9SDavid du Colombier Dev *dev; /* for this hub */ 89906943f9SDavid du Colombier Hub *next; /* in list of hubs */ 90906943f9SDavid du Colombier }; 91906943f9SDavid du Colombier 92906943f9SDavid du Colombier struct Port 93906943f9SDavid du Colombier { 94906943f9SDavid du Colombier int state; /* state of the device */ 95906943f9SDavid du Colombier int sts; /* old port status */ 96906943f9SDavid du Colombier uchar removable; 97906943f9SDavid du Colombier uchar pwrctl; 98906943f9SDavid du Colombier Dev *dev; /* attached device (if non-nil) */ 99906943f9SDavid du Colombier Hub *hub; /* non-nil if hub attached */ 100ed868a7cSDavid du Colombier int devnb; /* device number */ 101ed868a7cSDavid du Colombier uvlong *devmaskp; /* ptr to dev mask */ 102906943f9SDavid du Colombier }; 103906943f9SDavid du Colombier 104906943f9SDavid du Colombier 105906943f9SDavid du Colombier /* USB HUB descriptor */ 106906943f9SDavid du Colombier struct DHub 107906943f9SDavid du Colombier { 108906943f9SDavid du Colombier uchar bLength; 109906943f9SDavid du Colombier uchar bDescriptorType; 110906943f9SDavid du Colombier uchar bNbrPorts; 111906943f9SDavid du Colombier uchar wHubCharacteristics[2]; 112906943f9SDavid du Colombier uchar bPwrOn2PwrGood; 113906943f9SDavid du Colombier uchar bHubContrCurrent; 114906943f9SDavid du Colombier uchar DeviceRemovable[1]; /* variable length */ 115906943f9SDavid du Colombier }; 116906943f9SDavid du Colombier 117*153f606aSDavid du Colombier /* Superspeed HUB descriptor */ 118*153f606aSDavid du Colombier struct DSSHub 119*153f606aSDavid du Colombier { 120*153f606aSDavid du Colombier uchar bLength; 121*153f606aSDavid du Colombier uchar bDescriptorType; 122*153f606aSDavid du Colombier uchar bNbrPorts; 123*153f606aSDavid du Colombier uchar wHubCharacteristics[2]; 124*153f606aSDavid du Colombier uchar bPwrOn2PwrGood; 125*153f606aSDavid du Colombier uchar bHubContrCurrent; 126*153f606aSDavid du Colombier uchar bHubHdrDecLat; 127*153f606aSDavid du Colombier uchar wHubDelay[2]; 128*153f606aSDavid du Colombier uchar DeviceRemovable[1]; /* variable length */ 129*153f606aSDavid du Colombier }; 130*153f606aSDavid du Colombier 131906943f9SDavid du Colombier struct Devtab 132906943f9SDavid du Colombier { 133906943f9SDavid du Colombier char *name; 134906943f9SDavid du Colombier int (*init)(Dev*, int, char**); /* nil if external */ 135906943f9SDavid du Colombier int csps[4]; 136906943f9SDavid du Colombier int vid; 137906943f9SDavid du Colombier int did; 138906943f9SDavid du Colombier char *args; 139ed868a7cSDavid du Colombier uvlong devmask; 140a650be7dSDavid du Colombier int noauto; 141906943f9SDavid du Colombier }; 142906943f9SDavid du Colombier 143906943f9SDavid du Colombier 144906943f9SDavid du Colombier Hub* newhub(char *fn, Dev *d); 145906943f9SDavid du Colombier int startdev(Port *pp); 146ed868a7cSDavid du Colombier int getdevnb(uvlong *maskp); 147ed868a7cSDavid du Colombier void putdevnb(uvlong *maskp, int nb); 148906943f9SDavid du Colombier void threadmain(int argc, char **argv); 149906943f9SDavid du Colombier 150906943f9SDavid du Colombier extern Usbfs usbdfsops; 151