/* * We never set the switch_exe bit since that would interfere * with the commands send by the MMC core. */ static void do_switch(struct cvm_mmc_host *host, u64 emm_switch) { int retries = 100; u64 rsp_sts; int bus_id; /* * Modes setting only taken from slot 0. Work around that hardware * issue by first switching to slot 0. */ bus_id = get_bus_id(emm_switch); clear_bus_id(&emm_switch); writeq(emm_switch, host->base + MIO_EMM_SWITCH(host)); set_bus_id(&emm_switch, bus_id); writeq(emm_switch, host->base + MIO_EMM_SWITCH(host)); /* wait for the switch to finish */ do { rsp_sts = readq(host->base + MIO_EMM_RSP_STS(host)); if (!(rsp_sts & MIO_EMM_RSP_STS_SWITCH_VAL)) break; udelay(10); } while (--retries); check_switch_errors(host); }
/** * set_hp_adapter_status * * @param operation 1=> config 0=> unconfig * @param slot_name * @returns 0 on success, !0 otherwise */ int set_hp_adapter_status(uint operation, char *slot_name) { int rc = 0; FILE *file; char *bus_id; char path[DR_PATH_MAX]; bus_id = get_bus_id(slot_name); if (bus_id) sprintf(path, PHP_SYSFS_POWER_PATH, bus_id); else sprintf(path, PHP_SYSFS_POWER_PATH, slot_name); say(DEBUG, "setting hp adapter status to %s for %s\n", ((operation+1 - 1) ? "CONFIG adapter" : "UNCONFIG adapter"), slot_name); file = fopen(path, "w"); if (file == NULL) { say(ERROR, "failed to open %s: %s\n", path, strerror(errno)); return -ENODEV; } rc = fwrite((operation+1 - 1) ? "1" : "0", 1, 1, file); if (rc != 1) rc = -EACCES; else rc = 0; fclose(file); return rc; }
/* check one register value */ bool AP_HAL::Device::check_next_register(void) { if (_checked.n_set == 0) { return true; } if (++_checked.counter < _checked.frequency) { return true; } _checked.counter = 0; struct checkreg ® = _checked.regs[_checked.next]; uint8_t v; if (!read_registers(reg.regnum, &v, 1) || v != reg.value) { // a register has changed value unexpectedly. Try changing it back // and re-check it next time #if 0 printf("Device 0x%x fixing 0x%02x 0x%02x -> 0x%02x\n", (unsigned)get_bus_id(), (unsigned)reg.regnum, (unsigned)v, (unsigned)reg.value); #endif write_register(reg.regnum, reg.value); return false; } _checked.next = (_checked.next+1) % _checked.n_set; return true; }
/* Try to clean up failed DMA. */ static void cleanup_dma(struct cvm_mmc_host *host, u64 rsp_sts) { u64 emm_dma; emm_dma = readq(host->base + MIO_EMM_DMA(host)); emm_dma |= FIELD_PREP(MIO_EMM_DMA_VAL, 1) | FIELD_PREP(MIO_EMM_DMA_DAT_NULL, 1); set_bus_id(&emm_dma, get_bus_id(rsp_sts)); writeq(emm_dma, host->base + MIO_EMM_DMA(host)); }
/* set value of one checked register */ void AP_HAL::Device::set_checked_register(uint8_t reg, uint8_t val) { if (_checked.regs == nullptr) { return; } struct checkreg *regs = _checked.regs; for (uint8_t i=0; i<_checked.n_set; i++) { if (regs[i].regnum == reg) { regs[i].value = val; return; } } if (_checked.n_set == _checked.n_allocated) { printf("Not enough checked registers for reg 0x%02x on device 0x%x\n", (unsigned)reg, (unsigned)get_bus_id()); return; } regs[_checked.n_set].regnum = reg; regs[_checked.n_set].value = val; _checked.n_set++; }
/** * get_hp_adapter_status * @brief check adapter status * * @param drc_name * @returns 0 if slot is empty * @returns 1 if adapter is configured * @returns 2 if adapter is not configured * @returns <0 on error */ int get_hp_adapter_status(char *drc_name) { int value, rc = 0; char path[DR_PATH_MAX], *bus_id; bus_id = get_bus_id(drc_name); if (bus_id) sprintf(path, PHP_SYSFS_ADAPTER_PATH, bus_id); else sprintf(path, PHP_SYSFS_ADAPTER_PATH, drc_name); rc = get_int_attribute(path, NULL, &value, sizeof(value)); if (rc) return -1; say(DEBUG, "hp adapter status for %s is %d\n", drc_name, value); rc = value; if (rc != CONFIG && rc != NOT_CONFIG && rc != EMPTY) rc = -1; return rc; }