Example #1
0
void
usba10_usb_free_descr_tree(
	dev_info_t			*dip,
	usb_client_dev_data_t		*dev_data)
{
	usb_free_descr_tree(dip, dev_data);
}
Example #2
0
/*
 * configuration clean up
 */
static void
uftdi_cleanup(uftdi_state_t *uf, int level)
{
	ASSERT(level > 0 && level <= UFTDI_CLEANUP_LEVEL_MAX);

	switch (level) {
	default:
	case 6:
		uftdi_close_pipes(uf);
		/*FALLTHROUGH*/
	case 5:
		usb_unregister_event_cbs(uf->uf_dip, uf->uf_usb_events);
		/*FALLTHROUGH*/
	case 4:
		uftdi_destroy_pm_components(uf);
		/*FALLTHROUGH*/
	case 3:
		mutex_destroy(&uf->uf_lock);
		cv_destroy(&uf->uf_tx_cv);

		usb_free_log_hdl(uf->uf_lh);
		uf->uf_lh = NULL;

		usb_free_descr_tree(uf->uf_dip, uf->uf_dev_data);
		uf->uf_def_ph = NULL;
		/*FALLTHROUGH*/
	case 2:
		usb_client_detach(uf->uf_dip, uf->uf_dev_data);
		/*FALLTHROUGH*/
	case 1:
		kmem_free(uf, sizeof (*uf));
		break;
	}
}
Example #3
0
/*
 * wusb_df_attach:
 *	Attach or resume.
 *
 *	For attach, initialize state and device, including:
 *		state variables, locks, device node
 *		device registration with system
 *		power management, hotplugging
 *	For resume, restore device and state
 */
static int
wusb_df_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	int			instance = ddi_get_instance(dip);
	char			*devinst;
	int			devinstlen;
	wusb_df_state_t		*wusb_dfp = NULL;
	usb_ep_data_t		*ep_datap;
	int			status;

	switch (cmd) {
	case DDI_ATTACH:
		break;

	case DDI_RESUME:
		wusb_df_cpr_resume(dip);

		/*
		 * Always return success to work around enumeration failures.
		 * This works around an issue where devices which are present
		 * before a suspend and absent upon resume could cause a system
		 * panic on resume.
		 */
		return (DDI_SUCCESS);
	default:
		return (DDI_FAILURE);
	}

	if (ddi_soft_state_zalloc(wusb_df_statep, instance) == DDI_SUCCESS) {
		wusb_dfp = ddi_get_soft_state(wusb_df_statep, instance);
	}
	if (wusb_dfp == NULL)  {

		return (DDI_FAILURE);
	}

	wusb_dfp->wusb_df_dip = dip;

	devinst = kmem_zalloc(USB_MAXSTRINGLEN, KM_SLEEP);
	devinstlen = snprintf(devinst, USB_MAXSTRINGLEN, "%s%d: ",
	    ddi_driver_name(dip), instance);

	wusb_dfp->wusb_df_devinst = kmem_zalloc(devinstlen + 1, KM_SLEEP);
	(void) strncpy(wusb_dfp->wusb_df_devinst, devinst, devinstlen);
	kmem_free(devinst, USB_MAXSTRINGLEN);

	wusb_dfp->wusb_df_log_hdl = usb_alloc_log_hdl(dip, "wusb_df",
	    &wusb_df_errlevel, &wusb_df_errmask, &wusb_df_instance_debug, 0);

	USB_DPRINTF_L4(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl,
	    "Attach: enter for attach");

	if ((status = usb_client_attach(dip, USBDRV_VERSION, 0)) !=
	    USB_SUCCESS) {
		USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl,
		    "attach: usb_client_attach failed, error code:%d", status);
		goto fail;
	}

	if ((status = usb_get_dev_data(dip, &wusb_dfp->wusb_df_reg,
	    USB_PARSE_LVL_ALL, 0)) != USB_SUCCESS) {
		USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl,
		    "attach: usb_get_dev_data failed, error code:%d", status);
		goto fail;
	}


	/*
	 * Get the descriptor for an intr pipe at alt 0 of current interface.
	 * This will be used later to open the pipe.
	 */
	if ((ep_datap = usb_lookup_ep_data(dip, wusb_dfp->wusb_df_reg,
	    wusb_dfp->wusb_df_reg->dev_curr_if, 0, 0,
	    USB_EP_ATTR_INTR, USB_EP_DIR_IN)) == NULL) {
		USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl,
		    "attach: Error getting intr endpoint descriptor");
		goto fail;
	}
	wusb_dfp->wusb_df_intr_ep_descr = ep_datap->ep_descr;

	usb_free_descr_tree(dip, wusb_dfp->wusb_df_reg);

	mutex_init(&wusb_dfp->wusb_df_mutex, NULL, MUTEX_DRIVER,
	    wusb_dfp->wusb_df_reg->dev_iblock_cookie);

	cv_init(&wusb_dfp->wusb_df_serial_cv, NULL, CV_DRIVER, NULL);
	wusb_dfp->wusb_df_serial_inuse = B_FALSE;

	wusb_dfp->wusb_df_locks_initialized = B_TRUE;

	/* create minor node */
	if (ddi_create_minor_node(dip, name, S_IFCHR, instance,
	    "wusb_df", 0) != DDI_SUCCESS) {
		USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl,
		    "attach: Error creating minor node");
		goto fail;
	}

	/* Put online before PM init as can get power managed afterward. */
	wusb_dfp->wusb_df_dev_state = USB_DEV_ONLINE;

	/* initialize power management */
	wusb_df_init_power_mgmt(wusb_dfp);

	if (usb_register_hotplug_cbs(dip, wusb_df_disconnect_callback,
	    wusb_df_reconnect_callback) != USB_SUCCESS) {

		goto fail;
	}

	/* Report device */
	ddi_report_dev(dip);

	(void) wusb_df_firmware_download(wusb_dfp);

	if (usb_reset_device(dip, USB_RESET_LVL_REATTACH) != USB_SUCCESS) {
		USB_DPRINTF_L2(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl,
		    "reset device failed");

		return (USB_FAILURE);
	}

	return (DDI_SUCCESS);

fail:
	if (wusb_dfp) {
		(void) wusb_df_cleanup(dip, wusb_dfp);
	}

	return (DDI_FAILURE);
}