+/* Routine io_user_client_method */
+kern_return_t is_io_connect_method_var_output
+(
+ io_connect_t connection,
+ uint32_t selector,
+ io_scalar_inband64_t scalar_input,
+ mach_msg_type_number_t scalar_inputCnt,
+ io_struct_inband_t inband_input,
+ mach_msg_type_number_t inband_inputCnt,
+ mach_vm_address_t ool_input,
+ mach_vm_size_t ool_input_size,
+ io_struct_inband_t inband_output,
+ mach_msg_type_number_t *inband_outputCnt,
+ io_scalar_inband64_t scalar_output,
+ mach_msg_type_number_t *scalar_outputCnt,
+ io_buf_ptr_t *var_output,
+ mach_msg_type_number_t *var_outputCnt
+)
+{
+ CHECK( IOUserClient, connection, client );
+
+ IOExternalMethodArguments args;
+ IOReturn ret;
+ IOMemoryDescriptor * inputMD = 0;
+ OSObject * structureVariableOutputData = 0;
+
+ bzero(&args.__reserved[0], sizeof(args.__reserved));
+ args.version = kIOExternalMethodArgumentsCurrentVersion;
+
+ args.selector = selector;
+
+ args.asyncWakePort = MACH_PORT_NULL;
+ args.asyncReference = 0;
+ args.asyncReferenceCount = 0;
+ args.structureVariableOutputData = &structureVariableOutputData;
+
+ args.scalarInput = scalar_input;
+ args.scalarInputCount = scalar_inputCnt;
+ args.structureInput = inband_input;
+ args.structureInputSize = inband_inputCnt;
+
+ if (ool_input)
+ inputMD = IOMemoryDescriptor::withAddressRange(ool_input, ool_input_size,
+ kIODirectionOut, current_task());
+
+ args.structureInputDescriptor = inputMD;
+
+ args.scalarOutput = scalar_output;
+ args.scalarOutputCount = *scalar_outputCnt;
+ bzero(&scalar_output[0], *scalar_outputCnt * sizeof(scalar_output[0]));
+ args.structureOutput = inband_output;
+ args.structureOutputSize = *inband_outputCnt;
+ args.structureOutputDescriptor = NULL;
+ args.structureOutputDescriptorSize = 0;
+
+ IOStatisticsClientCall();
+ ret = client->externalMethod( selector, &args );
+
+ *scalar_outputCnt = args.scalarOutputCount;
+ *inband_outputCnt = args.structureOutputSize;
+
+ if (var_outputCnt && var_output && (kIOReturnSuccess == ret))
+ {
+ OSSerialize * serialize;
+ OSData * data;
+ vm_size_t len;
+
+ if ((serialize = OSDynamicCast(OSSerialize, structureVariableOutputData)))
+ {
+ len = serialize->getLength();
+ *var_outputCnt = len;
+ ret = copyoutkdata(serialize->text(), len, var_output);
+ }
+ else if ((data = OSDynamicCast(OSData, structureVariableOutputData)))
+ {
+ len = data->getLength();
+ *var_outputCnt = len;
+ ret = copyoutkdata(data->getBytesNoCopy(), len, var_output);
+ }
+ else
+ {
+ ret = kIOReturnUnderrun;
+ }
+ }
+
+ if (inputMD)
+ inputMD->release();
+ if (structureVariableOutputData)
+ structureVariableOutputData->release();
+
+ return (ret);
+}
+
+/* Routine io_user_client_method */
+kern_return_t is_io_connect_method
+(
+ io_connect_t connection,
+ uint32_t selector,
+ io_scalar_inband64_t scalar_input,
+ mach_msg_type_number_t scalar_inputCnt,
+ io_struct_inband_t inband_input,
+ mach_msg_type_number_t inband_inputCnt,
+ mach_vm_address_t ool_input,
+ mach_vm_size_t ool_input_size,
+ io_struct_inband_t inband_output,
+ mach_msg_type_number_t *inband_outputCnt,
+ io_scalar_inband64_t scalar_output,
+ mach_msg_type_number_t *scalar_outputCnt,
+ mach_vm_address_t ool_output,
+ mach_vm_size_t *ool_output_size
+)
+{
+ CHECK( IOUserClient, connection, client );
+
+ IOExternalMethodArguments args;
+ IOReturn ret;
+ IOMemoryDescriptor * inputMD = 0;
+ IOMemoryDescriptor * outputMD = 0;
+
+ bzero(&args.__reserved[0], sizeof(args.__reserved));
+ args.version = kIOExternalMethodArgumentsCurrentVersion;
+
+ args.selector = selector;
+
+ args.asyncWakePort = MACH_PORT_NULL;
+ args.asyncReference = 0;
+ args.asyncReferenceCount = 0;
+ args.structureVariableOutputData = 0;
+
+ args.scalarInput = scalar_input;
+ args.scalarInputCount = scalar_inputCnt;
+ args.structureInput = inband_input;
+ args.structureInputSize = inband_inputCnt;
+
+ if (ool_input)
+ inputMD = IOMemoryDescriptor::withAddressRange(ool_input, ool_input_size,
+ kIODirectionOut, current_task());
+
+ args.structureInputDescriptor = inputMD;
+
+ args.scalarOutput = scalar_output;
+ args.scalarOutputCount = *scalar_outputCnt;
+ bzero(&scalar_output[0], *scalar_outputCnt * sizeof(scalar_output[0]));
+ args.structureOutput = inband_output;
+ args.structureOutputSize = *inband_outputCnt;
+
+ if (ool_output && ool_output_size)
+ {
+ outputMD = IOMemoryDescriptor::withAddressRange(ool_output, *ool_output_size,
+ kIODirectionIn, current_task());
+ }
+
+ args.structureOutputDescriptor = outputMD;
+ args.structureOutputDescriptorSize = ool_output_size ? *ool_output_size : 0;
+
+ IOStatisticsClientCall();
+ ret = client->externalMethod( selector, &args );
+
+ *scalar_outputCnt = args.scalarOutputCount;
+ *inband_outputCnt = args.structureOutputSize;
+ *ool_output_size = args.structureOutputDescriptorSize;
+
+ if (inputMD)
+ inputMD->release();
+ if (outputMD)
+ outputMD->release();
+
+ return (ret);
+}
+
+/* Routine io_async_user_client_method */
+kern_return_t is_io_connect_async_method
+(
+ io_connect_t connection,
+ mach_port_t wake_port,
+ io_async_ref64_t reference,
+ mach_msg_type_number_t referenceCnt,
+ uint32_t selector,
+ io_scalar_inband64_t scalar_input,
+ mach_msg_type_number_t scalar_inputCnt,
+ io_struct_inband_t inband_input,
+ mach_msg_type_number_t inband_inputCnt,
+ mach_vm_address_t ool_input,
+ mach_vm_size_t ool_input_size,
+ io_struct_inband_t inband_output,
+ mach_msg_type_number_t *inband_outputCnt,
+ io_scalar_inband64_t scalar_output,
+ mach_msg_type_number_t *scalar_outputCnt,
+ mach_vm_address_t ool_output,
+ mach_vm_size_t * ool_output_size
+)
+{
+ CHECK( IOUserClient, connection, client );
+
+ IOExternalMethodArguments args;
+ IOReturn ret;
+ IOMemoryDescriptor * inputMD = 0;
+ IOMemoryDescriptor * outputMD = 0;
+
+ bzero(&args.__reserved[0], sizeof(args.__reserved));
+ args.version = kIOExternalMethodArgumentsCurrentVersion;
+
+ reference[0] = (io_user_reference_t) wake_port;
+ if (vm_map_is_64bit(get_task_map(current_task())))
+ reference[0] |= kIOUCAsync64Flag;
+
+ args.selector = selector;
+
+ args.asyncWakePort = wake_port;
+ args.asyncReference = reference;
+ args.asyncReferenceCount = referenceCnt;
+
+ args.scalarInput = scalar_input;
+ args.scalarInputCount = scalar_inputCnt;
+ args.structureInput = inband_input;
+ args.structureInputSize = inband_inputCnt;
+
+ if (ool_input)
+ inputMD = IOMemoryDescriptor::withAddressRange(ool_input, ool_input_size,
+ kIODirectionOut, current_task());
+
+ args.structureInputDescriptor = inputMD;
+
+ args.scalarOutput = scalar_output;
+ args.scalarOutputCount = *scalar_outputCnt;
+ bzero(&scalar_output[0], *scalar_outputCnt * sizeof(scalar_output[0]));
+ args.structureOutput = inband_output;
+ args.structureOutputSize = *inband_outputCnt;
+
+ if (ool_output)
+ {
+ outputMD = IOMemoryDescriptor::withAddressRange(ool_output, *ool_output_size,
+ kIODirectionIn, current_task());
+ }
+
+ args.structureOutputDescriptor = outputMD;
+ args.structureOutputDescriptorSize = *ool_output_size;
+
+ IOStatisticsClientCall();
+ ret = client->externalMethod( selector, &args );
+
+ *inband_outputCnt = args.structureOutputSize;
+ *ool_output_size = args.structureOutputDescriptorSize;
+
+ if (inputMD)
+ inputMD->release();
+ if (outputMD)
+ outputMD->release();
+
+ return (ret);
+}