コード例 #1
0
ファイル: usbser_keyspan.c プロジェクト: andreiw/polaris
/*ARGSUSED*/
static int
keyspan_pre_attach(dev_info_t *dip, ddi_attach_cmd_t cmd, void *statep)
{

	int			instance = ddi_get_instance(dip);
	keyspan_pre_state_t	*kbp = NULL;
	usb_client_dev_data_t	*dev_data = NULL;
	int			rval = DDI_FAILURE;

	switch (cmd) {
	case DDI_ATTACH:

		break;
	case DDI_RESUME:

		return (DDI_SUCCESS);
	default:

		return (DDI_FAILURE);
	}

	/* attach driver to USBA */
	if (usb_client_attach(dip, USBDRV_VERSION, 0) == USB_SUCCESS) {
		(void) usb_get_dev_data(dip, &dev_data, USB_PARSE_LVL_IF, 0);
	}
	if (dev_data == NULL) {

		goto fail;
	}

	/*
	 * If 19HS, needn't download firmware, but need check the current cfg.
	 * If 49WLC, need check the current cfg before download fw. And after
	 * download, the product id will change to KEYSPAN_USA49WLC_PID.
	 */
	if (dev_data->dev_descr->idProduct == KEYSPAN_USA19HS_PID ||
	    dev_data->dev_descr->idProduct == KEYSPAN_USA49WLC_PID) {
		if (keyspan_set_cfg(dip) == USB_SUCCESS) {
			/* Go to keyspan_attach() by return DDI_ECONTEXT. */
			rval =	DDI_ECONTEXT;
		}

		goto fail;
	}

	/*
	 * By checking KEYSPAN_FW_FLAG,  we can check whether the firmware
	 * has been downloaded.
	 * If firmware is already there, then do normal attach.
	 */
	if (!keyspan_need_fw(dev_data)) {
		/* Go to keyspan_attach() by return DDI_ECONTEXT. */
		rval =	DDI_ECONTEXT;

		goto fail;
	}

	/* Go on to download firmware. */

	if (ddi_soft_state_zalloc(statep, instance) == DDI_SUCCESS) {
		kbp = ddi_get_soft_state(statep, instance);
	}
	if (kbp) {
		kbp->kb_dip = dip;
		kbp->kb_instance = instance;
		kbp->kb_dev_data = dev_data;
		kbp->kb_def_pipe.pipe_handle = kbp->kb_dev_data->dev_default_ph;
		kbp->kb_lh = usb_alloc_log_hdl(kbp->kb_dip, "keyspan[*].",
		    &keyspan_pre_errlevel, &keyspan_pre_errmask,
		    &keyspan_pre_instance_debug, 0);

		kbp->kb_def_pipe.pipe_lh = kbp->kb_lh;

		if (keyspan_download_firmware(kbp) == USB_SUCCESS) {
			USB_DPRINTF_L4(DPRINT_ATTACH, kbp->kb_lh,
			    "keyspan_pre_attach: completed.");

			/* keyspan download firmware done. */

			return (DDI_SUCCESS);
		}
	}
fail:
	if (kbp) {
		usb_free_log_hdl(kbp->kb_lh);
		ddi_soft_state_free(statep, instance);
	}
	usb_client_detach(dip, dev_data);

	return (rval);
}
コード例 #2
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);
}
コード例 #3
0
ファイル: uftdi_dsd.c プロジェクト: madhavsuresh/illumos-gate
/*
 * ds_attach
 */
static int
uftdi_attach(ds_attach_info_t *aip)
{
	uftdi_state_t *uf;
	usb_dev_descr_t *dd;
	int recognized;

	uf = kmem_zalloc(sizeof (*uf), KM_SLEEP);
	uf->uf_dip = aip->ai_dip;
	uf->uf_usb_events = aip->ai_usb_events;
	*aip->ai_hdl = (ds_hdl_t)uf;

	/* only one port */
	*aip->ai_port_cnt = 1;

	if (usb_client_attach(uf->uf_dip, USBDRV_VERSION, 0) != USB_SUCCESS) {
		uftdi_cleanup(uf, 1);
		return (USB_FAILURE);
	}

	if (usb_get_dev_data(uf->uf_dip,
	    &uf->uf_dev_data, USB_PARSE_LVL_IF, 0) != USB_SUCCESS) {
		uftdi_cleanup(uf, 2);
		return (USB_FAILURE);
	}

	uf->uf_hwport = FTDI_PIT_SIOA + uf->uf_dev_data->dev_curr_if;

	mutex_init(&uf->uf_lock, NULL, MUTEX_DRIVER,
	    uf->uf_dev_data->dev_iblock_cookie);

	cv_init(&uf->uf_tx_cv, NULL, CV_DRIVER, NULL);

	uf->uf_lh = usb_alloc_log_hdl(uf->uf_dip, "uftdi",
	    &uftdi_errlevel, &uftdi_errmask, &uftdi_instance_debug, 0);

	/*
	 * This device and its clones has numerous physical instantiations.
	 */
	recognized = B_TRUE;
	dd = uf->uf_dev_data->dev_descr;
	switch (dd->idVendor) {
	case USB_VENDOR_FTDI:
		switch (dd->idProduct) {
		case USB_PRODUCT_FTDI_SERIAL_8U232AM:
		case USB_PRODUCT_FTDI_SEMC_DSS20:
		case USB_PRODUCT_FTDI_CFA_631:
		case USB_PRODUCT_FTDI_CFA_632:
		case USB_PRODUCT_FTDI_CFA_633:
		case USB_PRODUCT_FTDI_CFA_634:
		case USB_PRODUCT_FTDI_CFA_635:
		case USB_PRODUCT_FTDI_USBSERIAL:
		case USB_PRODUCT_FTDI_MX2_3:
		case USB_PRODUCT_FTDI_MX4_5:
		case USB_PRODUCT_FTDI_LK202:
		case USB_PRODUCT_FTDI_LK204:
		case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13M:
		case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13S:
		case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13U:
		case USB_PRODUCT_FTDI_EISCOU:
		case USB_PRODUCT_FTDI_UOPTBR:
		case USB_PRODUCT_FTDI_EMCU2D:
		case USB_PRODUCT_FTDI_PCMSFU:
		case USB_PRODUCT_FTDI_EMCU2H:
			break;
		default:
			recognized = B_FALSE;
			break;
		}
		break;
	case USB_VENDOR_SIIG2:
		switch (dd->idProduct) {
		case USB_PRODUCT_SIIG2_US2308:
			break;
		default:
			recognized = B_FALSE;
			break;
		}
		break;
	case USB_VENDOR_INTREPIDCS:
		switch (dd->idProduct) {
		case USB_PRODUCT_INTREPIDCS_VALUECAN:
		case USB_PRODUCT_INTREPIDCS_NEOVI:
			break;
		default:
			recognized = B_FALSE;
			break;
		}
		break;
	case USB_VENDOR_BBELECTRONICS:
		switch (dd->idProduct) {
		case USB_PRODUCT_BBELECTRONICS_USOTL4:
			break;
		default:
			recognized = B_FALSE;
			break;
		}
		break;
	case USB_VENDOR_MELCO:
		switch (dd->idProduct) {
		case USB_PRODUCT_MELCO_PCOPRS1:
			break;
		default:
			recognized = B_FALSE;
			break;
		}
		break;
	case USB_VENDOR_MARVELL:
		switch (dd->idProduct) {
		case USB_PRODUCT_MARVELL_SHEEVAPLUG_JTAG:
			break;
		default:
			recognized = B_FALSE;
			break;
		}
		break;
	default:
		recognized = B_FALSE;
		break;
	}

	/*
	 * Set 'uftdi_attach_unrecognized' to non-zero to
	 * experiment with newer devices ..
	 */
	if (!recognized && !uftdi_attach_unrecognized) {
		uftdi_cleanup(uf, 3);
		return (USB_FAILURE);
	}

	USB_DPRINTF_L3(DPRINT_ATTACH, uf->uf_lh,
	    "uftdi: matched vendor 0x%x product 0x%x port %d",
	    dd->idVendor, dd->idProduct, uf->uf_hwport);

	uf->uf_def_ph = uf->uf_dev_data->dev_default_ph;

	mutex_enter(&uf->uf_lock);
	uf->uf_dev_state = USB_DEV_ONLINE;
	uf->uf_port_state = UFTDI_PORT_CLOSED;
	mutex_exit(&uf->uf_lock);

	if (uftdi_create_pm_components(uf) != USB_SUCCESS) {
		uftdi_cleanup(uf, 3);
		return (USB_FAILURE);
	}

	if (usb_register_event_cbs(uf->uf_dip,
	    uf->uf_usb_events, 0) != USB_SUCCESS) {
		uftdi_cleanup(uf, 4);
		return (USB_FAILURE);
	}

	if (usb_pipe_get_max_bulk_transfer_size(uf->uf_dip,
	    &uf->uf_xfer_sz) != USB_SUCCESS) {
		uftdi_cleanup(uf, 5);
		return (USB_FAILURE);
	}

	/*
	 * TODO: modern ftdi devices have deeper (and asymmetric)
	 * fifos than this minimal 64 bytes .. but how to tell
	 * -safely- ?
	 */

#define	FTDI_MAX_XFERSIZE	64

	if (uf->uf_xfer_sz > FTDI_MAX_XFERSIZE)
		uf->uf_xfer_sz = FTDI_MAX_XFERSIZE;

	if (uftdi_dev_attach(uf) != USB_SUCCESS) {
		uftdi_cleanup(uf, 5);
		return (USB_FAILURE);
	}

	return (USB_SUCCESS);
}