int ddi_soft_state_init(void **state_p, size_t size, size_t n_items) { struct i_ddi_soft_state *ss; if (state_p == NULL || *state_p != NULL || size == 0) return (EINVAL); ss = kmem_zalloc(sizeof (*ss), KM_SLEEP); mutex_init(&ss->lock, NULL, MUTEX_DRIVER, NULL); ss->size = size; if (n_items < MIN_N_ITEMS) ss->n_items = MIN_N_ITEMS; else { int bitlog; if ((bitlog = ddi_fls(n_items)) == ddi_ffs(n_items)) bitlog--; ss->n_items = 1 << bitlog; } ASSERT(ss->n_items >= n_items); ss->array = kmem_zalloc(ss->n_items * sizeof (void *), KM_SLEEP); *state_p = ss; return (0); }
int sda_slot_power_on(sda_slot_t *slot) { int rv; uint32_t ocr; sda_slot_enter(slot); /* * Get the voltage supplied by the host. Note that we expect * hosts will include a range of 2.7-3.7 in their supported * voltage ranges. The spec does not allow for hosts that * cannot supply a voltage in this range, yet. */ if ((rv = sda_getprop(slot, SDA_PROP_OCR, &ocr)) != 0) { sda_slot_err(slot, "Failed to get host OCR (%d)", rv); goto done; } if ((ocr & OCR_HI_MASK) == 0) { sda_slot_err(slot, "Host does not support standard voltages."); rv = ENOTSUP; goto done; } /* * We prefer 3.3V, 3.0V, and failing that, just use the * maximum that the host supports. 3.3V is preferable, * because it is the typical common voltage that just about * everything supports. Otherwise we just pick the highest * supported voltage. This facilitates initial power up. */ if (ocr & OCR_32_33V) { slot->s_cur_ocr = OCR_32_33V; } else if (ocr & OCR_29_30V) { slot->s_cur_ocr = OCR_29_30V; } else { slot->s_cur_ocr = (1U << (ddi_fls(ocr) - 1)); } /* * Turn on the power. */ if ((rv = sda_setprop(slot, SDA_PROP_OCR, slot->s_cur_ocr)) != 0) { sda_slot_err(slot, "Failed to set OCR %x (%d)", slot->s_cur_ocr, rv); goto done; } sda_slot_exit(slot); /* * Wait 250 msec (per spec) for power ramp to complete. */ delay(drv_usectohz(250000)); return (0); done: sda_slot_exit(slot); return (rv); }
/* check to see if value is power of 2 or not. */ static int isnot_pow2(uint64_t value) { uint32_t low; uint32_t hi; low = value & 0xffffffff; hi = value >> 32; /* * ddi_ffs and ddi_fls gets long values, so in 32bit environment * won't work correctly for 64bit values */ if ((ddi_ffs(low) == ddi_fls(low)) && (ddi_ffs(hi) == ddi_fls(hi))) return (0); return (1); }