static NTSTATUS XenUsb_CompleteXenbusInit(PXENUSB_DEVICE_DATA xudd) { PUCHAR ptr; USHORT type; PCHAR setting, value, value2; ULONG i; ptr = xudd->config_page; while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END) { switch(type) { case XEN_INIT_TYPE_RING: /* frontend ring */ FUNCTION_MSG("XEN_INIT_TYPE_RING - %s = %p\n", setting, value); if (strcmp(setting, "urb-ring-ref") == 0) { xudd->urb_sring = (usbif_urb_sring_t *)value; FRONT_RING_INIT(&xudd->urb_ring, xudd->urb_sring, PAGE_SIZE); } if (strcmp(setting, "conn-ring-ref") == 0) { xudd->conn_sring = (usbif_conn_sring_t *)value; FRONT_RING_INIT(&xudd->conn_ring, xudd->conn_sring, PAGE_SIZE); } break; case XEN_INIT_TYPE_EVENT_CHANNEL_DPC: /* frontend event channel */ FUNCTION_MSG("XEN_INIT_TYPE_EVENT_CHANNEL_DPC - %s = %d\n", setting, PtrToUlong(value) & 0x3FFFFFFF); if (strcmp(setting, "event-channel") == 0) { xudd->event_channel = PtrToUlong(value); } break; case XEN_INIT_TYPE_READ_STRING_BACK: case XEN_INIT_TYPE_READ_STRING_FRONT: FUNCTION_MSG("XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value); break; default: FUNCTION_MSG("XEN_INIT_TYPE_%d\n", type); break; } } if (xudd->urb_sring == NULL || xudd->conn_sring == NULL || xudd->event_channel == 0) { FUNCTION_MSG("Missing settings\n"); FUNCTION_EXIT(); return STATUS_BAD_INITIAL_PC; } stack_new(&xudd->req_id_ss, REQ_ID_COUNT); for (i = 0; i < REQ_ID_COUNT; i++) { put_id_on_freelist(xudd->req_id_ss, (uint16_t)i); } return STATUS_SUCCESS; }
static NTSTATUS XenUsb_StartXenbusInit(PXENUSB_DEVICE_DATA xudd) { PUCHAR ptr; USHORT type; PCHAR setting, value, value2; xudd->urb_sring = NULL; xudd->event_channel = 0; ptr = xudd->config_page; while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END) { switch(type) { case XEN_INIT_TYPE_READ_STRING_BACK: FUNCTION_MSG("XEN_INIT_TYPE_READ_STRING_BACK - %s = %s\n", setting, value); break; case XEN_INIT_TYPE_READ_STRING_FRONT: FUNCTION_MSG("XEN_INIT_TYPE_READ_STRING_FRONT - %s = %s\n", setting, value); break; case XEN_INIT_TYPE_VECTORS: FUNCTION_MSG("XEN_INIT_TYPE_VECTORS\n"); if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) || ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC) { FUNCTION_MSG("vectors mismatch (magic = %08x, length = %d)\n", ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length); FUNCTION_EXIT(); return STATUS_BAD_INITIAL_PC; } else memcpy(&xudd->vectors, value, sizeof(XENPCI_VECTORS)); break; case XEN_INIT_TYPE_STATE_PTR: FUNCTION_MSG("XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)); xudd->device_state = (PXENPCI_DEVICE_STATE)value; break; default: FUNCTION_MSG("XEN_INIT_TYPE_%d\n", type); break; } } return STATUS_SUCCESS; }
// Called at <= DISPATCH_LEVEL static NDIS_STATUS XenNet_Init( OUT PNDIS_STATUS OpenErrorStatus, OUT PUINT SelectedMediumIndex, IN PNDIS_MEDIUM MediumArray, IN UINT MediumArraySize, IN NDIS_HANDLE MiniportAdapterHandle, IN NDIS_HANDLE WrapperConfigurationContext ) { NDIS_STATUS status; BOOLEAN medium_found = FALSE; struct xennet_info *xi = NULL; UINT nrl_length; PNDIS_RESOURCE_LIST nrl; PCM_PARTIAL_RESOURCE_DESCRIPTOR prd; KIRQL irq_level = 0; ULONG irq_vector = 0; ULONG irq_mode = 0; NDIS_HANDLE config_handle; NDIS_STRING config_param_name; PNDIS_CONFIGURATION_PARAMETER config_param; ULONG i; PUCHAR ptr; UCHAR type; PCHAR setting, value; ULONG length; //CHAR buf[128]; PVOID network_address; UINT network_address_length; BOOLEAN qemu_hide_filter = FALSE; ULONG qemu_hide_flags_value = 0; UNREFERENCED_PARAMETER(OpenErrorStatus); FUNCTION_ENTER(); KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql())); /* deal with medium stuff */ for (i = 0; i < MediumArraySize; i++) { if (MediumArray[i] == NdisMedium802_3) { medium_found = TRUE; break; } } if (!medium_found) { KdPrint(("NIC_MEDIA_TYPE not in MediumArray\n")); return NDIS_STATUS_UNSUPPORTED_MEDIA; } *SelectedMediumIndex = i; /* Alloc memory for adapter private info */ status = NdisAllocateMemoryWithTag((PVOID)&xi, sizeof(*xi), XENNET_POOL_TAG); if (!NT_SUCCESS(status)) { KdPrint(("NdisAllocateMemoryWithTag failed with 0x%x\n", status)); status = NDIS_STATUS_RESOURCES; goto err; } RtlZeroMemory(xi, sizeof(*xi)); xi->adapter_handle = MiniportAdapterHandle; xi->rx_target = RX_DFL_MIN_TARGET; xi->rx_min_target = RX_DFL_MIN_TARGET; xi->rx_max_target = RX_MAX_TARGET; xi->inactive = TRUE; NdisMSetAttributesEx(xi->adapter_handle, (NDIS_HANDLE) xi, 0, 0 /* the last zero is to give the next | something to | with */ #ifdef NDIS51_MINIPORT |NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS #endif |NDIS_ATTRIBUTE_DESERIALIZE |NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK, NdisInterfaceInternal); /* PnpBus option doesn't exist... */ xi->multicast_list_size = 0; xi->current_lookahead = MIN_LOOKAHEAD_LENGTH; nrl_length = 0; NdisMQueryAdapterResources(&status, WrapperConfigurationContext, NULL, (PUINT)&nrl_length); KdPrint((__DRIVER_NAME " nrl_length = %d\n", nrl_length)); status = NdisAllocateMemoryWithTag((PVOID)&nrl, nrl_length, XENNET_POOL_TAG); if (status != NDIS_STATUS_SUCCESS) { KdPrint((__DRIVER_NAME " Could not get allocate memory for Adapter Resources 0x%x\n", status)); return NDIS_STATUS_RESOURCES; } NdisMQueryAdapterResources(&status, WrapperConfigurationContext, nrl, (PUINT)&nrl_length); if (status != NDIS_STATUS_SUCCESS) { KdPrint((__DRIVER_NAME " Could not get Adapter Resources 0x%x\n", status)); return NDIS_STATUS_RESOURCES; } xi->event_channel = 0; xi->config_csum = 1; xi->config_csum_rx_check = 1; xi->config_sg = 1; xi->config_gso = 61440; xi->config_page = NULL; xi->config_rx_interrupt_moderation = 0; for (i = 0; i < nrl->Count; i++) { prd = &nrl->PartialDescriptors[i]; switch(prd->Type) { case CmResourceTypeInterrupt: irq_vector = prd->u.Interrupt.Vector; irq_level = (KIRQL)prd->u.Interrupt.Level; irq_mode = (prd->Flags & CM_RESOURCE_INTERRUPT_LATCHED)?NdisInterruptLatched:NdisInterruptLevelSensitive; KdPrint((__DRIVER_NAME " irq_vector = %03x, irq_level = %03x, irq_mode = %s\n", irq_vector, irq_level, (irq_mode == NdisInterruptLatched)?"NdisInterruptLatched":"NdisInterruptLevelSensitive")); break; case CmResourceTypeMemory: if (xi->config_page) { KdPrint(("More than one memory range\n")); return NDIS_STATUS_RESOURCES; } else { status = NdisMMapIoSpace(&xi->config_page, MiniportAdapterHandle, prd->u.Memory.Start, prd->u.Memory.Length); if (!NT_SUCCESS(status)) { KdPrint(("NdisMMapIoSpace failed with 0x%x\n", status)); NdisFreeMemory(nrl, nrl_length, 0); return NDIS_STATUS_RESOURCES; } } break; } } NdisFreeMemory(nrl, nrl_length, 0); if (!xi->config_page) { KdPrint(("No config page given\n")); return NDIS_STATUS_RESOURCES; } KeInitializeDpc(&xi->suspend_dpc, XenNet_SuspendResume, xi); KeInitializeSpinLock(&xi->resume_lock); KeInitializeDpc(&xi->rxtx_dpc, XenNet_RxTxDpc, xi); KeSetTargetProcessorDpc(&xi->rxtx_dpc, 0); KeSetImportanceDpc(&xi->rxtx_dpc, HighImportance); NdisMGetDeviceProperty(MiniportAdapterHandle, &xi->pdo, &xi->fdo, &xi->lower_do, NULL, NULL); xi->packet_filter = 0; status = IoGetDeviceProperty(xi->pdo, DevicePropertyDeviceDescription, NAME_SIZE, xi->dev_desc, &length); if (!NT_SUCCESS(status)) { KdPrint(("IoGetDeviceProperty failed with 0x%x\n", status)); status = NDIS_STATUS_FAILURE; goto err; } ptr = xi->config_page; while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value)) != XEN_INIT_TYPE_END) { switch(type) { case XEN_INIT_TYPE_VECTORS: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n")); if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) || ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC) { KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n", ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length)); FUNCTION_EXIT(); return NDIS_STATUS_FAILURE; } else memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS)); break; case XEN_INIT_TYPE_STATE_PTR: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value))); xi->device_state = (PXENPCI_DEVICE_STATE)value; break; case XEN_INIT_TYPE_QEMU_HIDE_FLAGS: qemu_hide_flags_value = PtrToUlong(value); break; case XEN_INIT_TYPE_QEMU_HIDE_FILTER: qemu_hide_filter = TRUE; break; default: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type)); break; } } if ((qemu_hide_flags_value & QEMU_UNPLUG_ALL_IDE_DISKS) || qemu_hide_filter) xi->inactive = FALSE; xi->power_state = NdisDeviceStateD0; xi->power_workitem = IoAllocateWorkItem(xi->fdo); // now build config page NdisOpenConfiguration(&status, &config_handle, WrapperConfigurationContext); if (!NT_SUCCESS(status)) { KdPrint(("Could not open config in registry (%08x)\n", status)); status = NDIS_STATUS_RESOURCES; goto err; } NdisInitUnicodeString(&config_param_name, L"ScatterGather"); NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); if (!NT_SUCCESS(status)) { KdPrint(("Could not read ScatterGather value (%08x)\n", status)); xi->config_sg = 1; } else { KdPrint(("ScatterGather = %d\n", config_param->ParameterData.IntegerData)); xi->config_sg = config_param->ParameterData.IntegerData; } NdisInitUnicodeString(&config_param_name, L"LargeSendOffload"); NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); if (!NT_SUCCESS(status)) { KdPrint(("Could not read LargeSendOffload value (%08x)\n", status)); xi->config_gso = 0; } else { KdPrint(("LargeSendOffload = %d\n", config_param->ParameterData.IntegerData)); xi->config_gso = config_param->ParameterData.IntegerData; if (xi->config_gso > 61440) { xi->config_gso = 61440; KdPrint(("(clipped to %d)\n", xi->config_gso)); } } NdisInitUnicodeString(&config_param_name, L"ChecksumOffload"); NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); if (!NT_SUCCESS(status)) { KdPrint(("Could not read ChecksumOffload value (%08x)\n", status)); xi->config_csum = 1; } else { KdPrint(("ChecksumOffload = %d\n", config_param->ParameterData.IntegerData)); xi->config_csum = !!config_param->ParameterData.IntegerData; } NdisInitUnicodeString(&config_param_name, L"ChecksumOffloadRxCheck"); NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); if (!NT_SUCCESS(status)) { KdPrint(("Could not read ChecksumOffloadRxCheck value (%08x)\n", status)); xi->config_csum_rx_check = 1; } else { KdPrint(("ChecksumOffloadRxCheck = %d\n", config_param->ParameterData.IntegerData)); xi->config_csum_rx_check = !!config_param->ParameterData.IntegerData; } NdisInitUnicodeString(&config_param_name, L"ChecksumOffloadDontFix"); NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); if (!NT_SUCCESS(status)) { KdPrint(("Could not read ChecksumOffloadDontFix value (%08x)\n", status)); xi->config_csum_rx_dont_fix = 0; } else { KdPrint(("ChecksumOffloadDontFix = %d\n", config_param->ParameterData.IntegerData)); xi->config_csum_rx_dont_fix = !!config_param->ParameterData.IntegerData; } NdisInitUnicodeString(&config_param_name, L"MTU"); NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); if (!NT_SUCCESS(status)) { KdPrint(("Could not read MTU value (%08x)\n", status)); xi->config_mtu = 1500; } else { KdPrint(("MTU = %d\n", config_param->ParameterData.IntegerData)); xi->config_mtu = config_param->ParameterData.IntegerData; } NdisInitUnicodeString(&config_param_name, L"RxInterruptModeration"); NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); if (!NT_SUCCESS(status)) { KdPrint(("Could not read RxInterruptModeration value (%08x)\n", status)); xi->config_rx_interrupt_moderation = 1500; } else { KdPrint(("RxInterruptModeration = %d\n", config_param->ParameterData.IntegerData)); xi->config_rx_interrupt_moderation = config_param->ParameterData.IntegerData; } NdisReadNetworkAddress(&status, &network_address, &network_address_length, config_handle); if (!NT_SUCCESS(status) || network_address_length != ETH_ALEN || ((((PUCHAR)network_address)[0] & 0x03) != 0x02)) { KdPrint(("Could not read NetworkAddress value (%08x) or value is invalid\n", status)); memset(xi->curr_mac_addr, 0, ETH_ALEN); } else { memcpy(xi->curr_mac_addr, network_address, ETH_ALEN); KdPrint((" Set MAC address from registry to %02X:%02X:%02X:%02X:%02X:%02X\n", xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2], xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5])); } xi->config_max_pkt_size = max(xi->config_mtu + XN_HDR_SIZE, xi->config_gso + XN_HDR_SIZE); NdisCloseConfiguration(config_handle); status = XenNet_D0Entry(xi); if (!NT_SUCCESS(status)) { KdPrint(("Failed to go to D0 (%08x)\n", status)); goto err; } return NDIS_STATUS_SUCCESS; err: NdisFreeMemory(xi, 0, 0); *OpenErrorStatus = status; FUNCTION_EXIT_STATUS(status); return status; }
static ULONG XenScsi_HwScsiFindAdapter(PVOID DeviceExtension, PVOID Reserved1, PVOID Reserved2, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PUCHAR Reserved3) { ULONG i; PXENSCSI_DEVICE_DATA xsdd = DeviceExtension; PACCESS_RANGE access_range; PUCHAR ptr; USHORT type; PCHAR setting, value, value2; vscsiif_sring_t *sring; CHAR path[128]; UNREFERENCED_PARAMETER(Reserved1); UNREFERENCED_PARAMETER(Reserved2); UNREFERENCED_PARAMETER(ArgumentString); UNREFERENCED_PARAMETER(Reserved3); FUNCTION_ENTER(); KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql())); xsdd->scsiport_paused = TRUE; /* wait for initial scan */ KdPrint((__DRIVER_NAME " BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel)); KdPrint((__DRIVER_NAME " BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector)); if (!ConfigInfo->BusInterruptVector) { KdPrint((__DRIVER_NAME " No Interrupt assigned\n")); return SP_RETURN_BAD_CONFIG; } if (ConfigInfo->NumberOfAccessRanges != 1) { KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges)); return SP_RETURN_BAD_CONFIG; } ptr = NULL; access_range = &((*(ConfigInfo->AccessRanges))[0]); KdPrint((__DRIVER_NAME " RangeStart = %08x, RangeLength = %08x\n", access_range->RangeStart.LowPart, access_range->RangeLength)); ptr = ScsiPortGetDeviceBase( DeviceExtension, ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, access_range->RangeStart, access_range->RangeLength, !access_range->RangeInMemory); if (!ptr) { KdPrint((__DRIVER_NAME " Unable to map range\n")); KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n")); return SP_RETURN_BAD_CONFIG; } sring = NULL; xsdd->event_channel = 0; while((type = GET_XEN_INIT_RSP(&ptr, &setting, &value, &value2)) != XEN_INIT_TYPE_END) { switch(type) { case XEN_INIT_TYPE_RING: /* frontend ring */ KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, value)); if (strcmp(setting, "ring-ref") == 0) { sring = (vscsiif_sring_t *)value; FRONT_RING_INIT(&xsdd->ring, sring, PAGE_SIZE); } break; //case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */ case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel */ KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value))); if (strcmp(setting, "event-channel") == 0) { xsdd->event_channel = PtrToUlong(value); } break; case XEN_INIT_TYPE_READ_STRING_BACK: case XEN_INIT_TYPE_READ_STRING_FRONT: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value)); break; case XEN_INIT_TYPE_VECTORS: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n")); if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) || ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC) { KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n", ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length)); KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n")); return SP_RETURN_BAD_CONFIG; } else memcpy(&xsdd->vectors, value, sizeof(XENPCI_VECTORS)); break; case XEN_INIT_TYPE_GRANT_ENTRIES: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(value))); xsdd->grant_entries = (USHORT)PtrToUlong(value); memcpy(&xsdd->grant_free_list, value2, sizeof(grant_ref_t) * xsdd->grant_entries); xsdd->grant_free = xsdd->grant_entries; break; default: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type)); break; } } if (sring == NULL || xsdd->event_channel == 0) { KdPrint((__DRIVER_NAME " Missing settings\n")); KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n")); return SP_RETURN_BAD_CONFIG; } ConfigInfo->ScatterGather = TRUE; ConfigInfo->NumberOfPhysicalBreaks = VSCSIIF_SG_TABLESIZE - 1; ConfigInfo->MaximumTransferLength = VSCSIIF_SG_TABLESIZE * PAGE_SIZE; ConfigInfo->CachesData = FALSE; ConfigInfo->NumberOfBuses = 4; //SCSI_MAXIMUM_BUSES; //8 ConfigInfo->MaximumNumberOfTargets = 16; ConfigInfo->MaximumNumberOfLogicalUnits = SCSI_MAXIMUM_LOGICAL_UNITS; // 8 ConfigInfo->BufferAccessScsiPortControlled = TRUE; if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) { ConfigInfo->Master = TRUE; ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED; KdPrint((__DRIVER_NAME " Dma64BitAddresses supported\n")); } else { ConfigInfo->Master = FALSE; KdPrint((__DRIVER_NAME " Dma64BitAddresses not supported\n")); } ConfigInfo->InitiatorBusId[0] = 7; ConfigInfo->InitiatorBusId[1] = 7; ConfigInfo->InitiatorBusId[2] = 7; ConfigInfo->InitiatorBusId[3] = 7; xsdd->shadow_free = 0; memset(xsdd->shadows, 0, sizeof(vscsiif_shadow_t) * SHADOW_ENTRIES); for (i = 0; i < SHADOW_ENTRIES; i++) { xsdd->shadows[i].req.rqid = (USHORT)i; put_shadow_on_freelist(xsdd, &xsdd->shadows[i]); } if (!dump_mode) { InitializeListHead(&xsdd->dev_list_head); /* should do something if we haven't enumerated in a certain time */ RtlStringCbCopyA(path, ARRAY_SIZE(path), xsdd->vectors.backend_path); RtlStringCbCatA(path, ARRAY_SIZE(path), "/vscsi-devs"); xsdd->vectors.XenBus_AddWatch(xsdd->vectors.context, XBT_NIL, path, XenScsi_DevWatch, xsdd); } FUNCTION_EXIT(); return SP_RETURN_FOUND; }
static NDIS_STATUS XenNet_ConnectBackend(struct xennet_info *xi) { PUCHAR ptr; UCHAR type; PCHAR setting, value, value2; UINT i; ULONG backend_sg = 0; ULONG backend_gso = 0; FUNCTION_ENTER(); ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL); ptr = xi->config_page; while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END) { switch(type) { case XEN_INIT_TYPE_RING: /* frontend ring */ KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, value)); if (strcmp(setting, "tx-ring-ref") == 0) { FRONT_RING_INIT(&xi->tx, (netif_tx_sring_t *)value, PAGE_SIZE); } else if (strcmp(setting, "rx-ring-ref") == 0) { FRONT_RING_INIT(&xi->rx, (netif_rx_sring_t *)value, PAGE_SIZE); } break; case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */ KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value))); if (strcmp(setting, "event-channel") == 0) { xi->event_channel = PtrToUlong(value); } break; case XEN_INIT_TYPE_READ_STRING_FRONT: break; case XEN_INIT_TYPE_READ_STRING_BACK: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value)); if (strcmp(setting, "mac") == 0) { char *s, *e; s = value; for (i = 0; i < ETH_ALEN; i++) { xi->perm_mac_addr[i] = (uint8_t)simple_strtoul(s, &e, 16); if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) { KdPrint((__DRIVER_NAME "Error parsing MAC address\n")); } s = e + 1; } if ((xi->curr_mac_addr[0] & 0x03) != 0x02) { /* only copy if curr_mac_addr is not a LUA */ memcpy(xi->curr_mac_addr, xi->perm_mac_addr, ETH_ALEN); } } else if (strcmp(setting, "feature-sg") == 0) { if (atoi(value)) { backend_sg = 1; } } else if (strcmp(setting, "feature-gso-tcpv4") == 0) { if (atoi(value)) { backend_gso = 1; } } break; case XEN_INIT_TYPE_VECTORS: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n")); if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) || ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC) { KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n", ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length)); FUNCTION_EXIT(); return NDIS_STATUS_ADAPTER_NOT_FOUND; } else memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS)); break; case XEN_INIT_TYPE_STATE_PTR: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value))); xi->device_state = (PXENPCI_DEVICE_STATE)value; break; default: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type)); break; } } if (xi->config_sg && !backend_sg) { KdPrint((__DRIVER_NAME " SG not supported by backend - disabling\n")); xi->config_sg = 0; } if (xi->config_gso && !backend_gso) { KdPrint((__DRIVER_NAME " GSO not supported by backend - disabling\n")); xi->config_gso = 0; } FUNCTION_EXIT(); return NDIS_STATUS_SUCCESS; }