Пример #1
0
/*
 * 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;
	}
Пример #2
0
/*
 * 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);
}
Пример #3
0
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;
}