/* * usb_handle_remote_wakeup: * check if device supports remote wakeup and, if so, enable/disable * remote wake up in the device depending upon the command */ int usb_handle_remote_wakeup(dev_info_t *dip, int cmd) { usb_cfg_descr_t cfg_descr; uchar_t *usb_cfg; /* buf for config descriptor */ size_t cfg_length; int rval; USBA_CHECK_CONTEXT(); /* Obtain the raw configuration descriptor */ usb_cfg = usb_get_raw_cfg_data(dip, &cfg_length); /* get configuration descriptor, must succeed */ rval = usb_parse_cfg_descr(usb_cfg, cfg_length, &cfg_descr, USB_CFG_DESCR_SIZE); ASSERT(rval == USB_CFG_DESCR_SIZE); /* * If the device supports remote wakeup, and PM is enabled, * we enable remote wakeup in the device */ if ((usb_is_pm_enabled(dip) == USB_SUCCESS) && (cfg_descr.bmAttributes & USB_CFG_ATTR_REMOTE_WAKEUP)) { rval = usba_handle_device_remote_wakeup(dip, cmd); } else { rval = USB_FAILURE; } return (rval); }
int usba10_usb_is_pm_enabled(dev_info_t *dip) { return (usb_is_pm_enabled(dip)); }
/* * usb_create_pm_components: * map descriptor into pm properties */ int usb_create_pm_components(dev_info_t *dip, uint_t *pwr_states) { uchar_t *usb_cfg; /* buf for config descriptor */ usb_cfg_descr_t cfg_descr; size_t cfg_length; usba_cfg_pwr_descr_t confpwr_descr; usba_if_pwr_descr_t ifpwr_descr; uint8_t cfg_attrib; int i, lvl, rval; int n_prop = 0; uint8_t *ptr; char *drvname; char str[USBA_POWER_STR_SIZE]; char *pm_comp[USBA_N_PMCOMP]; USBA_CHECK_CONTEXT(); if (usb_is_pm_enabled(dip) != USB_SUCCESS) { return (USB_FAILURE); } /* Obtain the raw configuration descriptor */ usb_cfg = usb_get_raw_cfg_data(dip, &cfg_length); /* get configuration descriptor, must succceed */ rval = usb_parse_cfg_descr(usb_cfg, cfg_length, &cfg_descr, USB_CFG_DESCR_SIZE); ASSERT(rval == USB_CFG_DESCR_SIZE); cfg_attrib = cfg_descr.bmAttributes; *pwr_states = 0; /* * Now start creating the pm-components strings */ drvname = (char *)ddi_driver_name(dip); (void) snprintf(str, USBA_POWER_STR_SIZE, "NAME= %s%d Power", drvname, ddi_get_instance(dip)); pm_comp[n_prop] = kmem_zalloc(strlen(str) + 1, KM_SLEEP); (void) strcpy(pm_comp[n_prop++], str); /* * if the device is bus powered we look at the bBusPowerSavingDx * fields else we look at bSelfPowerSavingDx fields. * OS and USB power states are numerically reversed, * * Here is the mapping :- * OS State USB State * 0 D3 (minimal or no power) * 1 D2 * 2 D1 * 3 D0 (Full power) * * if we own the whole device, we look at the config pwr descr * else at the interface pwr descr. */ if (usb_owns_device(dip)) { /* Parse the configuration power descriptor */ rval = usba_parse_cfg_pwr_descr(usb_cfg, cfg_length, &confpwr_descr, USBA_CFG_PWR_DESCR_SIZE); if (rval != USBA_CFG_PWR_DESCR_SIZE) { USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, "usb_create_pm_components: " "usb_parse_cfg_pwr_descr returns length of %d, " "expecting %d", rval, USBA_CFG_PWR_DESCR_SIZE); return (USB_FAILURE); } if (cfg_attrib & USB_CFG_ATTR_SELFPWR) { ptr = &confpwr_descr.bSelfPowerSavingD3; } else { ptr = &confpwr_descr.bBusPowerSavingD3; } } else { /* Parse the interface power descriptor */ rval = usba_parse_if_pwr_descr(usb_cfg, cfg_length, usba_get_ifno(dip), /* interface index */ 0, /* XXXX alt interface index */ &ifpwr_descr, USBA_IF_PWR_DESCR_SIZE); if (rval != USBA_IF_PWR_DESCR_SIZE) { USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, "usb_create_pm_components: " "usb_parse_if_pwr_descr " "returns length of %d, " "expecting %d", rval, USBA_CFG_PWR_DESCR_SIZE); return (USB_FAILURE); } if (cfg_attrib & USB_CFG_ATTR_SELFPWR) { ptr = &ifpwr_descr.bSelfPowerSavingD3; } else { ptr = &ifpwr_descr.bBusPowerSavingD3; } } /* walk thru levels and create prop level=name strings */ for (lvl = USB_DEV_OS_PWR_0; lvl <= USB_DEV_OS_PWR_3; lvl++) { if (*ptr || (lvl == USB_DEV_OS_PWR_3)) { (void) snprintf(str, USBA_POWER_STR_SIZE, "%d=USB D%d State", lvl, USB_DEV_OS_PWR2USB_PWR(lvl)); pm_comp[n_prop] = kmem_zalloc(strlen(str) + 1, KM_SLEEP); (void) strcpy(pm_comp[n_prop++], str); *pwr_states |= USB_DEV_PWRMASK(lvl); } ptr -= 2; /* skip to the next power state */ } USB_DPRINTF_L3(DPRINT_MASK_USBAI, usbai_log_handle, "usb_create_pm_components: pwr_states: %x", *pwr_states); /* now create the actual components */ rval = ddi_prop_update_string_array(DDI_DEV_T_NONE, dip, "pm-components", pm_comp, n_prop); if (rval == DDI_PROP_SUCCESS) { rval = USB_SUCCESS; } else { rval = USB_FAILURE; } /* display & delete properties */ USB_DPRINTF_L3(DPRINT_MASK_USBAI, usbai_log_handle, "usb_create_pm_components: The properties are:"); for (i = 0; i < n_prop; i++) { USB_DPRINTF_L3(DPRINT_MASK_USBAI, usbai_log_handle, "\t%s", pm_comp[i]); kmem_free(pm_comp[i], strlen(pm_comp[i]) + 1); } return (rval); }