14static int hubDrvConnect(
int devId);
15static int hubDrvDisconnect(
int devId);
16static int hubDrvProbe(
int devId);
19static void *hubBufferListMemoryBuffer = NULL;
20static int hubAllocatedCount = 0;
45 hubBufferList = hubBufferList->m_next;
46 res->m_desc.bDescriptorType = 0;
47 res->m_statusIoReq.m_busyFlag = 0;
48 res->m_controlIoReq.m_busyFlag = 0;
49 res->m_curAllocatedCount = hubAllocatedCount;
50 hubAllocatedCount += 1;
56 hub->m_next = hubBufferList;
64 for ( res = hub->m_childListStart; res && port > 0; port -= 1, res = res->m_next )
72 if ( dev->m_statusIoReq.m_busyFlag )
74 dbg_printf(
"getHubStatusChange: StatusChangeEP IoReq is busy!\n");
77 attachIoReqToEndpoint(
78 dev->m_statusChangeEp,
80 dev->m_statusChangeInfo,
81 (
int)(dev->m_numChildDevices + 7) >> 3,
82 hubStatusChangeCallback);
85static void hubControlTransfer(
96 if ( hubDev->m_controlIoReq.m_busyFlag )
98 dbg_printf(
"ERROR: hubControlTransfer %p: ioReq busy\n", hubDev);
99 printf(
"hub_control_transfer: busy - %s\n", fromfunc);
103 hubDev->m_controlEp, &hubDev->m_controlIoReq, requestType,
request, value, index, length, destData, callback);
116 dbg_printf(
"HubGetPortStatusCallback res %d\n", req->m_resultCode);
119 dbg_printf(
"port status change: %d: %08X\n", dev->m_portCounter, dev->m_portStatusChange);
120 if ( (dev->m_portStatusChange & BIT(C_PORT_CONNECTION)) != 0 )
122 port = fetchPortElemByNumber(dev->m_controlEp->m_correspDevice, dev->m_portCounter);
125 hubStatusChangeCallback(&dev->m_statusIoReq);
128 if ( port->m_deviceStatus >= (
unsigned int)DEVICE_CONNECTED )
132 feature = C_PORT_CONNECTION;
134 else if ( (dev->m_portStatusChange & BIT(C_PORT_ENABLE)) != 0 )
136 feature = C_PORT_ENABLE;
138 else if ( (dev->m_portStatusChange & BIT(C_PORT_SUSPEND)) != 0 )
140 feature = C_PORT_SUSPEND;
142 else if ( (dev->m_portStatusChange & BIT(C_PORT_OVER_CURRENT)) != 0 )
144 feature = C_PORT_OVER_CURRENT;
146 else if ( (dev->m_portStatusChange & BIT(C_PORT_RESET)) != 0 )
148 feature = C_PORT_RESET;
152 dev->m_portStatusChange &= ~BIT(feature);
155 USB_DIR_OUT | USB_RT_PORT,
156 USB_REQ_CLEAR_FEATURE,
158 dev->m_portCounter & 0xFFFF,
161 hubGetPortStatusCallback,
162 "clear_port_feature");
165 port = fetchPortElemByNumber(dev->m_controlEp->m_correspDevice, dev->m_portCounter);
168 if ( (dev->m_portStatusChange & BIT(PORT_CONNECTION)) != 0 )
170 dbg_printf(
"Hub Port CCS\n");
171 if ( port->m_deviceStatus == DEVICE_NOTCONNECTED )
173 dbg_printf(
"resetting dev\n");
174 port->m_deviceStatus = DEVICE_CONNECTED;
175 addTimerCallback(&port->m_timer, (TimerCallback)hubResetDevice, port, 501);
178 if ( port->m_deviceStatus == DEVICE_RESETPENDING && (dev->m_portStatusChange & BIT(PORT_ENABLE)) != 0 )
180 dbg_printf(
"hub port reset done, opening control EP\n");
181 port->m_deviceStatus = DEVICE_RESETCOMPLETE;
182 port->m_isLowSpeedDevice = (dev->m_portStatusChange & BIT(PORT_LOW_SPEED)) != 0;
183 if ( openDeviceEndpoint(port, NULL, 0) )
184 hubTimedSetFuncAddress(port);
186 dbg_printf(
"Can't open default control ep.\n");
187 dev->m_hubStatusCounter = 0;
192 dbg_printf(
"disconnected; flushing port\n");
196 hubStatusChangeCallback(&dev->m_statusIoReq);
203 dbg_printf(
"port reset err: %d\n", arg->m_resultCode);
206 getHubStatusChange((
UsbdUsbHub_t *)arg->m_userCallbackArg);
213 privDataField = (
UsbdUsbHub_t *)dev->m_parent->m_privDataField;
214 privDataField->m_hubStatusCounter = dev->m_attachedToPortNo;
217 USB_DIR_OUT | USB_RT_PORT,
220 dev->m_attachedToPortNo,
223 hubDeviceResetCallback,
227static void hubCalculateMagicPowerValue(
UsbdUsbHub_t *hubDevice)
231 dev = hubDevice->m_dev;
232 if ( (
int)dev->m_magicPowerValue )
234 if ( (
int)dev->m_magicPowerValue >= 0 && (
int)dev->m_magicPowerValue < 6 && (
int)dev->m_magicPowerValue >= 3 )
236 if ( (hubDevice->m_hubStatus & 1) != 0 )
237 dev->m_magicPowerValue = 4;
239 dev->m_magicPowerValue = 5;
242 else if ( hubDevice->m_isSelfPowered )
244 if ( (
int)hubDevice->m_maxPower <= 0 )
245 dev->m_magicPowerValue = 2;
247 dev->m_magicPowerValue = 3;
251 dev->m_magicPowerValue = (int)hubDevice->m_maxPower > 0;
264 if ( (dev->m_hubStatusChange & BIT(C_HUB_LOCAL_POWER)) != 0 )
266 dev->m_hubStatusChange &= ~BIT(C_HUB_LOCAL_POWER);
269 USB_DIR_OUT | USB_RT_HUB,
270 USB_REQ_CLEAR_FEATURE,
275 hubGetHubStatusCallback,
276 "clear_hub_feature");
277 hubCalculateMagicPowerValue(dev);
279 else if ( (dev->m_hubStatusChange & BIT(C_HUB_OVER_CURRENT)) != 0 )
281 dev->m_hubStatusChange &= ~BIT(C_HUB_OVER_CURRENT);
284 USB_DIR_OUT | USB_RT_HUB,
285 USB_REQ_CLEAR_FEATURE,
290 hubGetHubStatusCallback,
291 "clear_hub_feature");
295 hubStatusChangeCallback(&dev->m_statusIoReq);
307 dbg_printf(
"hubStatusChangeCallback, iores %d\n", req->m_resultCode);
310 if ( (dev->m_statusChangeInfo[0] & 1) != 0 )
312 dev->m_statusChangeInfo[0] &= ~1;
315 USB_DIR_IN | USB_RT_HUB,
321 hubGetHubStatusCallback,
322 "scan_change_bitmap");
325 port = dev->m_hubStatusCounter;
329 if ( (
int)dev->m_numChildDevices <= 0 )
331 getHubStatusChange(dev);
334 while ( (((
int)dev->m_statusChangeInfo[port >> 3] >> (port & 7)) & 1) == 0 )
337 if ( (
int)dev->m_numChildDevices < port )
339 getHubStatusChange(dev);
344 else if ( (((
int)dev->m_statusChangeInfo[port >> 3] >> (port & 7)) & 1) == 0 )
346 getHubStatusChange(dev);
349 dev->m_statusChangeInfo[port >> 3] &= ~BIT(port & 7);
350 dev->m_portCounter = port;
353 USB_DIR_IN | USB_RT_PORT,
358 &dev->m_portStatusChange,
359 hubGetPortStatusCallback,
360 "scan_change_bitmap");
369 if ( (
int)dev->m_portCounter > 0 && req->m_resultCode !=
USB_RC_OK )
373 dev->m_portCounter += 1;
374 if ( ((
int)dev->m_numChildDevices < (
int)dev->m_portCounter) || usbConfig.m_maxPortsPerHub < (
int)dev->m_portCounter )
375 getHubStatusChange(dev);
379 USB_DIR_OUT | USB_RT_PORT,
399 hubCalculateMagicPowerValue(dev);
401 dev->m_hubStatusCounter = 0;
402 dev->m_portCounter = 0;
403 dev->m_numChildDevices = dev->m_desc.bNbrPorts;
404 for ( i = 0; (int)i < (
int)dev->m_numChildDevices && (int)i < usbConfig.m_maxPortsPerHub; i += 1 )
406 if ( !attachChildDevice(dev->m_controlEp->m_correspDevice, i + 1) )
408 dev->m_numChildDevices = i;
412 if ( (
int)dev->m_numChildDevices > 0 )
413 hubSetPortPower(req);
422 dev, USB_DIR_IN | USB_RT_HUB, USB_REQ_GET_STATUS, 0, 0, 4u, &dev->m_hubStatus, hubSetupPorts,
"get_hub_status");
441 if ( dev->m_desc.bDescriptorType == USB_DT_HUB )
446 USB_DIR_IN | USB_RT_HUB,
447 USB_REQ_GET_DESCRIPTOR,
453 "set_configuration_done");
456static int hubDrvConnect(
int devId)
465 dev = fetchDeviceById(devId);
469 if ( !confDesc || confDesc->bNumInterfaces != 1 )
476 if ( intfDesc->bNumEndpoints != 1 )
485 if ( (endpDesc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN )
487 if ( (endpDesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT )
489 hubDesc = (
UsbHubDescriptor *)doGetDeviceStaticDescriptor(devId, endpDesc, USB_DT_HUB);
490 hubDevice = allocHubBuffer();
493 dev->m_privDataField = hubDevice;
494 hubDevice->m_dev = dev;
495 hubDevice->m_controlEp = dev->m_endpointListStart;
496 hubDevice->m_statusChangeEp = doOpenEndpoint(dev, endpDesc, 0);
497 if ( !hubDevice->m_statusChangeEp )
499 freeHubBuffer(hubDevice);
502 hubDevice->m_statusIoReq.m_userCallbackArg = hubDevice;
503 hubDevice->m_controlIoReq.m_userCallbackArg = hubDevice;
504 hubDevice->m_maxPower = confDesc->maxPower;
505 hubDevice->m_isSelfPowered = (confDesc->bmAttributes >> 6) & 1;
506 hubCalculateMagicPowerValue(hubDevice);
516 USB_DIR_OUT | USB_RECIP_DEVICE,
517 USB_REQ_SET_CONFIGURATION,
518 confDesc->bConfigurationValue,
527static int hubDrvDisconnect(
int devId)
531 dev = fetchDeviceById(devId);
538static int hubDrvProbe(
int devId)
542 devDesc = (
const UsbDeviceDescriptor *)doGetDeviceStaticDescriptor(devId, NULL, USB_DT_DEVICE);
543 return devDesc && devDesc->bDeviceClass == USB_CLASS_HUB && devDesc->bNumConfigurations == 1;
546int initHubDriver(
void)
553 needMem = usbConfig.m_maxHubDevices *
sizeof(
UsbdUsbHub_t);
554 hubBufferList = (
UsbdUsbHub_t *)AllocSysMemoryWrap(needMem);
555 if ( !hubBufferList )
557 dbg_printf(
"ERROR: unable to alloc hub buffer\n");
561 hubBufferListMemoryBuffer = hub;
562 bzero(hubBufferList, needMem);
563 usbConfig.m_allocatedSize_unused += needMem;
564 for ( i = 0; i < usbConfig.m_maxHubDevices; i += 1 )
566 hub[i].m_next = (i < usbConfig.m_maxHubDevices - 1) ? &hub[i + 1] : NULL;
573 doRegisterDriver(&usbHubDriver, OldGP);
577void deinitHubDriver(
void)
579 doUnregisterDriver(&usbHubDriver);
580 FreeSysMemoryWrap(hubBufferListMemoryBuffer);