status_t get_device_parent(usb_device _device, usb_device *parentHub, uint8 *portIndex) { if (!parentHub || !portIndex) return B_BAD_VALUE; Object *object = gUSBStack->GetObject(_device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_DEV_INVALID_PIPE; Object *parent = object->Parent(); if (!parent || (parent->Type() & USB_OBJECT_HUB) == 0) return B_ENTRY_NOT_FOUND; Hub *hub = (Hub *)parent; for (uint8 i = 0; i < 8; i++) { if (hub->ChildAt(i) == object) { *portIndex = i; *parentHub = hub->USBID(); return B_OK; } } return B_ERROR; }
bool Object::Equal( Object& a, Object& b ) { if( a.Type() != b.Type() ) return false; DataType* pA = a.Get(); DataType* pB = b.Get(); return DataType::Equal( pA, pB ); }
const usb_device_descriptor * get_device_descriptor(usb_device device) { TRACE_MODULE("get_device_descriptor(%" B_PRId32 ")\n", device); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return NULL; return ((Device *)object)->DeviceDescriptor(); }
status_t cancel_queued_transfers(usb_pipe pipe) { TRACE_MODULE("cancel_queued_transfers(%" B_PRId32 ")\n", pipe); Object *object = gUSBStack->GetObject(pipe); if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) return B_DEV_INVALID_PIPE; return ((Pipe *)object)->CancelQueuedTransfers(false); }
status_t set_alt_interface(usb_device device, const usb_interface_info *interface) { TRACE_MODULE("set_alt_interface(%" B_PRId32 ", %p)\n", device, interface); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_DEV_INVALID_PIPE; return ((Device *)object)->SetAltInterface(interface); }
status_t disable_port(usb_device _hub, uint8 portIndex) { Object *object = gUSBStack->GetObject(_hub); if (!object || (object->Type() & USB_OBJECT_HUB) == 0) return B_DEV_INVALID_PIPE; Hub *hub = (Hub *)object; return hub->DisablePort(portIndex); }
const usb_configuration_info * get_configuration(usb_device device) { TRACE_MODULE("get_configuration(%" B_PRId32 ")\n", device); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return NULL; return ((Device *)object)->Configuration(); }
status_t set_configuration(usb_device device, const usb_configuration_info *configuration) { TRACE_MODULE("set_configuration(%" B_PRId32 ", %p)\n", device, configuration); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_DEV_INVALID_PIPE; return ((Device *)object)->SetConfiguration(configuration); }
status_t queue_interrupt(usb_pipe pipe, void *data, size_t dataLength, usb_callback_func callback, void *callbackCookie) { TRACE_MODULE("queue_interrupt(%" B_PRId32 ", %p, %ld, %p, %p)\n", pipe, data, dataLength, callback, callbackCookie); Object *object = gUSBStack->GetObject(pipe); if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) return B_DEV_INVALID_PIPE; return ((InterruptPipe *)object)->QueueInterrupt(data, dataLength, callback, callbackCookie); }
status_t queue_bulk(usb_pipe pipe, void *data, size_t dataLength, usb_callback_func callback, void *callbackCookie) { TRACE_MODULE("queue_bulk(%" B_PRId32 ", %p, %" B_PRIuSIZE ", %p, %p)\n", pipe, data, dataLength, callback, callbackCookie); Object *object = gUSBStack->GetObject(pipe); if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) return B_DEV_INVALID_PIPE; return ((BulkPipe *)object)->QueueBulk(data, dataLength, callback, callbackCookie); }
status_t queue_bulk_v_physical(usb_pipe pipe, iovec *vector, size_t vectorCount, usb_callback_func callback, void *callbackCookie) { TRACE_MODULE("queue_bulk_v_physical(%" B_PRId32 ", %p, %" B_PRIuSIZE ", %p, %p)\n", pipe, vector, vectorCount, callback, callbackCookie); Object *object = gUSBStack->GetObject(pipe); if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) return B_DEV_INVALID_PIPE; return ((BulkPipe *)object)->QueueBulkV(vector, vectorCount, callback, callbackCookie, true); }
status_t set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets, uint16 maxBufferDurationMS, uint16 sampleSize) { TRACE_MODULE("set_pipe_policy(%" B_PRId32 ", %d, %d, %d)\n", pipe, maxQueuedPackets, maxBufferDurationMS, sampleSize); Object *object = gUSBStack->GetObject(pipe); if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) return B_DEV_INVALID_PIPE; return ((IsochronousPipe *)object)->SetPipePolicy(maxQueuedPackets, maxBufferDurationMS, sampleSize); }
status_t get_descriptor(usb_device device, uint8 type, uint8 index, uint16 languageID, void *data, size_t dataLength, size_t *actualLength) { TRACE_MODULE("get_descriptor(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, %p, " "%" B_PRIuSIZE ", %p)\n", device, type, index, languageID, data, dataLength, actualLength); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_DEV_INVALID_PIPE; return ((Device *)object)->GetDescriptor(type, index, languageID, data, dataLength, actualLength); }
status_t send_request(usb_device device, uint8 requestType, uint8 request, uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength) { TRACE_MODULE("send_request(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, 0x%04x, " "%d, %p, %p)\n", device, requestType, request, value, index, length, data, actualLength); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_DEV_INVALID_PIPE; return ((Device *)object)->DefaultPipe()->SendRequest(requestType, request, value, index, length, data, length, actualLength); }
status_t queue_request(usb_device device, uint8 requestType, uint8 request, uint16 value, uint16 index, uint16 length, void *data, usb_callback_func callback, void *callbackCookie) { TRACE_MODULE("queue_request(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, 0x%04x," " %u, %p, %p, %p)\n", device, requestType, request, value, index, length, data, callback, callbackCookie); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_DEV_INVALID_PIPE; return ((Device *)object)->DefaultPipe()->QueueRequest(requestType, request, value, index, length, data, length, callback, callbackCookie); }
int Table::operator == (Object &tblobj) { char *a; if (strcmp (a=tblobj.Type (), Type ())) // Type check return 0; Table *tblptr = (Table *) &tblobj; if (tblptr->Nelem () == nelem) // Count check { Object *b; for (int i = 0; i < nelem; i++) if (*(b=tblptr->Get (i)) != *(Get(i))) // Elementwise check return 0; } else return 0; return 1; }
status_t queue_isochronous(usb_pipe pipe, void *data, size_t dataLength, usb_iso_packet_descriptor *packetDesc, uint32 packetCount, uint32 *startingFrameNumber, uint32 flags, usb_callback_func callback, void *callbackCookie) { TRACE_MODULE("queue_isochronous(%" B_PRId32 ", %p, %" B_PRIuSIZE ", %p, " "%" B_PRId32 ", %p, 0x%08" B_PRIx32 ", %p, %p)\n", pipe, data, dataLength, packetDesc, packetCount, startingFrameNumber, flags, callback, callbackCookie); Object *object = gUSBStack->GetObject(pipe); if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) return B_DEV_INVALID_PIPE; return ((IsochronousPipe *)object)->QueueIsochronous(data, dataLength, packetDesc, packetCount, startingFrameNumber, flags, callback, callbackCookie); }
status_t usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize) { TRACE_MODULE("usb_ioctl(%" B_PRIu32 ", %p, %" B_PRIuSIZE ")\n", opcode, buffer, bufferSize); switch (opcode) { case 'DNAM': { Object *object = gUSBStack->GetObject(*(usb_id *)buffer); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_BAD_VALUE; uint32 index = 0; return ((Device *)object)->BuildDeviceName((char *)buffer, &index, bufferSize, NULL); } } return B_DEV_INVALID_IOCTL; }
static int debug_get_pipe_for_id(int argc, char **argv) { if (gUSBStack == NULL) return 1; if (!is_debug_variable_defined("_usbPipeID")) return 2; uint64 id = get_debug_variable("_usbPipeID", 0); Object *object = gUSBStack->GetObjectNoLock((usb_id)id); if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) return 3; // check if we support debug transfers for this pipe (only on UHCI for now) if (object->GetBusManager()->TypeName()[0] != 'u') return 4; set_debug_variable("_usbPipe", (uint64)object); return 0; }
status_t get_nth_child(usb_device _hub, uint8 index, usb_device *childDevice) { if (!childDevice) return B_BAD_VALUE; Object *object = gUSBStack->GetObject(_hub); if (!object || (object->Type() & USB_OBJECT_HUB) == 0) return B_DEV_INVALID_PIPE; Hub *hub = (Hub *)object; for (uint8 i = 0; i < 8; i++) { if (hub->ChildAt(i) == NULL) continue; if (index-- > 0) continue; *childDevice = hub->ChildAt(i)->USBID(); return B_OK; } return B_ENTRY_NOT_FOUND; }
int operator == (Object &o) { char *a; if (strcmp (a=o.Type (),Type ())) return 0; return j == ((B&)o).j; }
int operator == (Object &o) { char *a; if (strcmp (a=o.Type (),Type ())) return 0; return i == ((A&)o).i; }
Hub::Hub(Object *parent, int8 hubAddress, uint8 hubPort, usb_device_descriptor &desc, int8 deviceAddress, usb_speed speed, bool isRootHub) : Device(parent, hubAddress, hubPort, desc, deviceAddress, speed, isRootHub), fInterruptPipe(NULL) { TRACE("creating hub\n"); memset(&fHubDescriptor, 0, sizeof(fHubDescriptor)); for (int32 i = 0; i < USB_MAX_PORT_COUNT; i++) fChildren[i] = NULL; if (!fInitOK) { TRACE_ERROR("device failed to initialize\n"); return; } // Set to false again for the hub init. fInitOK = false; if (fDeviceDescriptor.device_class != 9) { TRACE_ERROR("wrong class! bailing out\n"); return; } TRACE("getting hub descriptor...\n"); size_t actualLength; status_t status = GetDescriptor(USB_DESCRIPTOR_HUB, 0, 0, (void *)&fHubDescriptor, sizeof(usb_hub_descriptor), &actualLength); // we need at least 8 bytes if (status < B_OK || actualLength < 8) { TRACE_ERROR("error getting hub descriptor\n"); return; } TRACE("hub descriptor (%ld bytes):\n", actualLength); TRACE("\tlength:..............%d\n", fHubDescriptor.length); TRACE("\tdescriptor_type:.....0x%02x\n", fHubDescriptor.descriptor_type); TRACE("\tnum_ports:...........%d\n", fHubDescriptor.num_ports); TRACE("\tcharacteristics:.....0x%04x\n", fHubDescriptor.characteristics); TRACE("\tpower_on_to_power_g:.%d\n", fHubDescriptor.power_on_to_power_good); TRACE("\tdevice_removeable:...0x%02x\n", fHubDescriptor.device_removeable); TRACE("\tpower_control_mask:..0x%02x\n", fHubDescriptor.power_control_mask); if (fHubDescriptor.num_ports > USB_MAX_PORT_COUNT) { TRACE_ALWAYS("hub supports more ports than we do (%d vs. %d)\n", fHubDescriptor.num_ports, USB_MAX_PORT_COUNT); fHubDescriptor.num_ports = USB_MAX_PORT_COUNT; } usb_interface_list *list = Configuration()->interface; Object *object = GetStack()->GetObject(list->active->endpoint[0].handle); if (object && (object->Type() & USB_OBJECT_INTERRUPT_PIPE) != 0) { fInterruptPipe = (InterruptPipe *)object; fInterruptPipe->QueueInterrupt(fInterruptStatus, sizeof(fInterruptStatus), InterruptCallback, this); } else { TRACE_ALWAYS("no interrupt pipe found\n"); } // Wait some time before powering up the ports if (!isRootHub) snooze(USB_DELAY_HUB_POWER_UP); // Enable port power on all ports for (int32 i = 0; i < fHubDescriptor.num_ports; i++) { status = DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_SET_FEATURE, PORT_POWER, i + 1, 0, NULL, 0, NULL); if (status < B_OK) TRACE_ERROR("power up failed on port %" B_PRId32 "\n", i); } // Wait for power to stabilize snooze(fHubDescriptor.power_on_to_power_good * 2000); fInitOK = true; TRACE("initialised ok\n"); }