Exemple #1
0
static int32
bus_std_ops(int32 op, ...)
{
	switch (op) {
		case B_MODULE_INIT: {
			TRACE_MODULE("init\n");
			if (gUSBStack)
				return B_OK;

#ifdef HAIKU_TARGET_PLATFORM_BEOS
			// This code is to handle plain R5 (non-BONE) where the same module
			// gets loaded multiple times (once for each exported module
			// interface, the USB v2 and v3 API in our case). We don't want to
			// ever create multiple stacks however, so we "share" the same stack
			// for both modules by storing it's address in a shared area.
			void *address = NULL;
			area_id shared = find_area("shared usb stack");
			if (shared >= B_OK && clone_area("usb stack clone", &address,
				B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA, shared) >= B_OK) {
				gUSBStack = *((Stack **)address);
				TRACE_MODULE("found shared stack at %p\n", gUSBStack);
				return B_OK;
			}
#endif

#ifdef TRACE_USB
			set_dprintf_enabled(true);
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
			load_driver_symbols("usb");
#endif
#endif
			Stack *stack = new(std::nothrow) Stack();
			TRACE_MODULE("usb_module: stack created %p\n", stack);
			if (!stack)
				return B_NO_MEMORY;

			if (stack->InitCheck() != B_OK) {
				delete stack;
				return ENODEV;
			}

			gUSBStack = stack;

#ifdef HAIKU_TARGET_PLATFORM_HAIKU
			add_debugger_command("get_usb_pipe_for_id",
				&debug_get_pipe_for_id,
				"Gets the config for a USB pipe");
#elif HAIKU_TARGET_PLATFORM_BEOS
			// Plain R5 workaround, see comment above.
			shared = create_area("shared usb stack", &address,
				B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_NO_LOCK,
				B_KERNEL_WRITE_AREA);
			if (shared >= B_OK)
				*((Stack **)address) = gUSBStack;
#endif
			break;
		}

		case B_MODULE_UNINIT:
			TRACE_MODULE("uninit\n");
			delete gUSBStack;
			gUSBStack = NULL;

#ifdef HAIKU_TARGET_PLATFORM_HAIKU
			remove_debugger_command("get_usb_pipe_for_id",
				&debug_get_pipe_for_id);
#endif
			break;

		default:
			return EINVAL;
	}

	return B_OK;
}