/* * Convert the logical range into a physcial range and add it to our * avl tree. */ void vdev_initialize_range_add(void *arg, uint64_t start, uint64_t size) { vdev_t *vd = arg; range_seg_t logical_rs, physical_rs; logical_rs.rs_start = start; logical_rs.rs_end = start + size; ASSERT(vd->vdev_ops->vdev_op_leaf); vdev_xlate(vd, &logical_rs, &physical_rs); IMPLY(vd->vdev_top == vd, logical_rs.rs_start == physical_rs.rs_start); IMPLY(vd->vdev_top == vd, logical_rs.rs_end == physical_rs.rs_end); /* Only add segments that we have not visited yet */ if (physical_rs.rs_end <= vd->vdev_initialize_last_offset) return; /* Pick up where we left off mid-range. */ if (vd->vdev_initialize_last_offset > physical_rs.rs_start) { zfs_dbgmsg("range write: vd %s changed (%llu, %llu) to " "(%llu, %llu)", vd->vdev_path, (u_longlong_t)physical_rs.rs_start, (u_longlong_t)physical_rs.rs_end, (u_longlong_t)vd->vdev_initialize_last_offset, (u_longlong_t)physical_rs.rs_end); ASSERT3U(physical_rs.rs_end, >, vd->vdev_initialize_last_offset); physical_rs.rs_start = vd->vdev_initialize_last_offset; }
/* * DL_INFO_REQ */ static void proto_info_req(dld_str_t *dsp, mblk_t *mp) { dl_info_ack_wrapper_t *dlwp; dl_info_ack_t *dlp; dl_qos_cl_sel1_t *selp; dl_qos_cl_range1_t *rangep; uint8_t *addr; uint8_t *brdcst_addr; uint_t addr_length; uint_t sap_length; mac_info_t minfo; mac_info_t *minfop; queue_t *q = dsp->ds_wq; /* * Swap the request message for one large enough to contain the * wrapper structure defined above. */ if ((mp = mexchange(q, mp, sizeof (dl_info_ack_wrapper_t), M_PCPROTO, 0)) == NULL) return; bzero(mp->b_rptr, sizeof (dl_info_ack_wrapper_t)); dlwp = (dl_info_ack_wrapper_t *)mp->b_rptr; dlp = &(dlwp->dl_info); ASSERT(dlp == (dl_info_ack_t *)mp->b_rptr); dlp->dl_primitive = DL_INFO_ACK; /* * Set up the sub-structure pointers. */ addr = dlwp->dl_addr; brdcst_addr = dlwp->dl_brdcst_addr; rangep = &(dlwp->dl_qos_range1); selp = &(dlwp->dl_qos_sel1); /* * This driver supports only version 2 connectionless DLPI provider * nodes. */ dlp->dl_service_mode = DL_CLDLS; dlp->dl_version = DL_VERSION_2; /* * Set the style of the provider */ dlp->dl_provider_style = dsp->ds_style; ASSERT(dlp->dl_provider_style == DL_STYLE1 || dlp->dl_provider_style == DL_STYLE2); /* * Set the current DLPI state. */ dlp->dl_current_state = dsp->ds_dlstate; /* * Gratuitously set the media type. This is to deal with modules * that assume the media type is known prior to DL_ATTACH_REQ * being completed. */ dlp->dl_mac_type = DL_ETHER; /* * If the stream is not at least attached we try to retrieve the * mac_info using mac_info_get() */ if (dsp->ds_dlstate == DL_UNATTACHED || dsp->ds_dlstate == DL_ATTACH_PENDING || dsp->ds_dlstate == DL_DETACH_PENDING) { if (!mac_info_get(ddi_major_to_name(dsp->ds_major), &minfo)) { /* * Cannot find mac_info. giving up. */ goto done; } minfop = &minfo; } else { minfop = (mac_info_t *)dsp->ds_mip; /* We can only get the sdu if we're attached. */ mac_sdu_get(dsp->ds_mh, &dlp->dl_min_sdu, &dlp->dl_max_sdu); } /* * Set the media type (properly this time). */ if (dsp->ds_native) dlp->dl_mac_type = minfop->mi_nativemedia; else dlp->dl_mac_type = minfop->mi_media; /* * Set the DLSAP length. We only support 16 bit values and they * appear after the MAC address portion of DLSAP addresses. */ sap_length = sizeof (uint16_t); dlp->dl_sap_length = NEG(sap_length); addr_length = minfop->mi_addr_length; /* * Copy in the media broadcast address. */ if (minfop->mi_brdcst_addr != NULL) { dlp->dl_brdcst_addr_offset = (uintptr_t)brdcst_addr - (uintptr_t)dlp; bcopy(minfop->mi_brdcst_addr, brdcst_addr, addr_length); dlp->dl_brdcst_addr_length = addr_length; } /* Only VLAN links and links that have a normal tag mode support QOS. */ if ((dsp->ds_mch != NULL && mac_client_vid(dsp->ds_mch) != VLAN_ID_NONE) || (dsp->ds_dlp != NULL && dsp->ds_dlp->dl_tagmode == LINK_TAGMODE_NORMAL)) { dlp->dl_qos_range_offset = (uintptr_t)rangep - (uintptr_t)dlp; dlp->dl_qos_range_length = sizeof (dl_qos_cl_range1_t); rangep->dl_qos_type = DL_QOS_CL_RANGE1; rangep->dl_trans_delay.dl_target_value = DL_UNKNOWN; rangep->dl_trans_delay.dl_accept_value = DL_UNKNOWN; rangep->dl_protection.dl_min = DL_UNKNOWN; rangep->dl_protection.dl_max = DL_UNKNOWN; rangep->dl_residual_error = DL_UNKNOWN; /* * Specify the supported range of priorities. */ rangep->dl_priority.dl_min = 0; rangep->dl_priority.dl_max = (1 << VLAN_PRI_SIZE) - 1; dlp->dl_qos_offset = (uintptr_t)selp - (uintptr_t)dlp; dlp->dl_qos_length = sizeof (dl_qos_cl_sel1_t); selp->dl_qos_type = DL_QOS_CL_SEL1; selp->dl_trans_delay = DL_UNKNOWN; selp->dl_protection = DL_UNKNOWN; selp->dl_residual_error = DL_UNKNOWN; /* * Specify the current priority (which can be changed by * the DL_UDQOS_REQ primitive). */ selp->dl_priority = dsp->ds_pri; } dlp->dl_addr_length = addr_length + sizeof (uint16_t); if (dsp->ds_dlstate == DL_IDLE) { /* * The stream is bound. Therefore we can formulate a valid * DLSAP address. */ dlp->dl_addr_offset = (uintptr_t)addr - (uintptr_t)dlp; if (addr_length > 0) mac_unicast_primary_get(dsp->ds_mh, addr); *(uint16_t *)(addr + addr_length) = dsp->ds_sap; } done: IMPLY(dlp->dl_qos_offset != 0, dlp->dl_qos_length != 0); IMPLY(dlp->dl_qos_range_offset != 0, dlp->dl_qos_range_length != 0); IMPLY(dlp->dl_addr_offset != 0, dlp->dl_addr_length != 0); IMPLY(dlp->dl_brdcst_addr_offset != 0, dlp->dl_brdcst_addr_length != 0); qreply(q, mp); }
NTSTATUS #pragma prefast(suppress:28152) // Does not clear DO_DEVICE_INITIALIZING AddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject ) { HANDLE ParametersKey; PANSI_STRING ActiveDeviceInstance; BOOLEAN Active; PWCHAR DeviceID; PWCHAR InstanceID; UNICODE_STRING Unicode; ULONG Length; NTSTATUS status; ASSERT3P(DriverObject, ==, __DriverGetDriverObject()); ParametersKey = __DriverGetParametersKey(); ActiveDeviceInstance = NULL; if (ParametersKey != NULL) { status = RegistryQuerySzValue(ParametersKey, "ActiveDeviceInstance", &ActiveDeviceInstance); ASSERT(IMPLY(!NT_SUCCESS(status), ActiveDeviceInstance == NULL)); } else { ActiveDeviceInstance = NULL; } Active = FALSE; DeviceID = NULL; InstanceID = NULL; RtlZeroMemory(&Unicode, sizeof (UNICODE_STRING)); if (ActiveDeviceInstance == NULL) goto done; status = __DriverQueryId(DeviceObject, BusQueryDeviceID, &DeviceID); if (!NT_SUCCESS(status)) goto fail1; status = __DriverQueryId(DeviceObject, BusQueryInstanceID, &InstanceID); if (!NT_SUCCESS(status)) goto fail2; status = RtlAnsiStringToUnicodeString(&Unicode, ActiveDeviceInstance, TRUE); if (!NT_SUCCESS(status)) goto fail3; Length = (ULONG)wcslen(DeviceID); if (_wcsnicmp(Unicode.Buffer, DeviceID, Length) != 0) goto done; Length = (ULONG)wcslen(InstanceID); if (_wcsnicmp(Unicode.Buffer + (Unicode.Length / sizeof (WCHAR)) - Length, InstanceID, Length) != 0) goto done; Active = TRUE; RegistryFreeSzValue(ActiveDeviceInstance); done: if (Unicode.Buffer != NULL) RtlFreeUnicodeString(&Unicode); if (InstanceID != NULL) ExFreePool(InstanceID); if (DeviceID != NULL) ExFreePool(DeviceID); status = FdoCreate(DeviceObject, Active); if (!NT_SUCCESS(status)) goto fail3; return STATUS_SUCCESS; fail3: if (InstanceID != NULL) ExFreePool(InstanceID); fail2: if (DeviceID != NULL) ExFreePool(DeviceID); fail1: RegistryFreeSzValue(ActiveDeviceInstance); Error("fail1 (%08x)\n", status); return status; }