/* Test that we can bind/unbind and the lists update correctly */ static int dm_test_ordering(struct unit_test_state *uts) { struct dm_test_state *dms = uts->priv; struct udevice *dev, *dev_penultimate, *dev_last, *test_dev; int pingret; ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual, &dev)); ut_assert(dev); /* Bind two new devices (numbers 4 and 5) */ ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual, &dev_penultimate)); ut_assert(dev_penultimate); ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual, &dev_last)); ut_assert(dev_last); /* Now remove device 3 */ ut_assertok(device_remove(dev)); ut_assertok(device_unbind(dev)); /* The device numbering should have shifted down one */ ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev)); ut_assert(dev_penultimate == test_dev); ut_assertok(uclass_find_device(UCLASS_TEST, 4, &test_dev)); ut_assert(dev_last == test_dev); /* Add back the original device 3, now in position 5 */ ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual, &dev)); ut_assert(dev); /* Try ping */ ut_assertok(test_ping(dev, 100, &pingret)); ut_assert(pingret == 102); /* Remove 3 and 4 */ ut_assertok(device_remove(dev_penultimate)); ut_assertok(device_unbind(dev_penultimate)); ut_assertok(device_remove(dev_last)); ut_assertok(device_unbind(dev_last)); /* Our device should now be in position 3 */ ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev)); ut_assert(dev == test_dev); /* Now remove device 3 */ ut_assertok(device_remove(dev)); ut_assertok(device_unbind(dev)); return 0; }
int dm_uninit(void) { device_remove(dm_root()); device_unbind(dm_root()); return 0; }
/* Test that the bus ops are called when a child is probed/removed */ static int dm_test_bus_parent_ops(struct dm_test_state *dms) { struct dm_test_parent_data *parent_data; struct udevice *bus, *dev; struct uclass *uc; test_state = dms; ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc)); uclass_foreach_dev(dev, uc) { /* Ignore these if they are not on this bus */ if (dev->parent != bus) continue; ut_asserteq_ptr(NULL, dev_get_parentdata(dev)); ut_assertok(device_probe(dev)); parent_data = dev_get_parentdata(dev); ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag); } uclass_foreach_dev(dev, uc) { /* Ignore these if they are not on this bus */ if (dev->parent != bus) continue; parent_data = dev_get_parentdata(dev); ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag); ut_assertok(device_remove(dev)); ut_asserteq_ptr(NULL, dev_get_parentdata(dev)); ut_asserteq_ptr(dms->removed, dev); } test_state = NULL; return 0; }
static int sata_imx_probe(struct udevice *dev) { int i, err; /* Make sure this gpio has logical 0 value */ gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0); udelay(100); cm_fx6_sata_power(1); for (i = 0; i < CM_FX6_SATA_INIT_RETRIES; i++) { err = setup_sata(); if (err) { printf("SATA setup failed: %d\n", err); return err; } udelay(100); err = dwc_ahsata_probe(dev); if (!err) break; /* There is no device on the SATA port */ if (sata_dm_port_status(0, 0) == 0) break; /* There's a device, but link not established. Retry */ device_remove(dev, DM_REMOVE_NORMAL); } return 0; }
static void usb_midi_sink_unbind(void* ctx) { usb_midi_sink_t* sink = ctx; sink->dead = true; update_signals(sink); sync_completion_signal(&sink->free_write_completion); device_remove(sink->mxdev); }
int sata_remove(int devnum) { #ifdef CONFIG_AHCI struct udevice *dev; int rc; rc = uclass_find_device(UCLASS_AHCI, devnum, &dev); if (!rc && !dev) rc = uclass_find_first_device(UCLASS_AHCI, &dev); if (rc || !dev) { printf("Cannot find SATA device %d (err=%d)\n", devnum, rc); return CMD_RET_FAILURE; } rc = device_remove(dev, DM_REMOVE_NORMAL); if (rc) { printf("Cannot remove SATA device '%s' (err=%d)\n", dev->name, rc); return CMD_RET_FAILURE; } return 0; #else return sata_stop(); #endif }
/* * 关闭 socket */ static int socket_close(void *ctx, file_t *file) { privinfo_t *priv = ctx; reg_t reg; if (priv == NULL) { seterrno(EINVAL); return -1; } reg = interrupt_disable(); atomic_dec(dev_ref(file)); device_remove(file->ctx); file->ctx = NULL; lwip_close(priv->sock_fd); kfree(priv); interrupt_resume(reg); return 0; }
/* Test that the bus can store data about each child */ static int test_bus_parent_data(struct unit_test_state *uts) { struct dm_test_parent_data *parent_data; struct udevice *bus, *dev; struct uclass *uc; int value; ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); /* Check that parent data is allocated */ ut_assertok(device_find_child_by_seq(bus, 0, true, &dev)); ut_asserteq_ptr(NULL, dev_get_parent_priv(dev)); ut_assertok(device_get_child_by_seq(bus, 0, &dev)); parent_data = dev_get_parent_priv(dev); ut_assert(NULL != parent_data); /* Check that it starts at 0 and goes away when device is removed */ parent_data->sum += 5; ut_asserteq(5, parent_data->sum); device_remove(dev); ut_asserteq_ptr(NULL, dev_get_parent_priv(dev)); /* Check that we can do this twice */ ut_assertok(device_get_child_by_seq(bus, 0, &dev)); parent_data = dev_get_parent_priv(dev); ut_assert(NULL != parent_data); parent_data->sum += 5; ut_asserteq(5, parent_data->sum); /* Add parent data to all children */ ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc)); value = 5; uclass_foreach_dev(dev, uc) { /* Ignore these if they are not on this bus */ if (dev->parent != bus) { ut_asserteq_ptr(NULL, dev_get_parent_priv(dev)); continue; } ut_assertok(device_probe(dev)); parent_data = dev_get_parent_priv(dev); parent_data->sum = value; value += 5; } /* Check it is still there */ value = 5; uclass_foreach_dev(dev, uc) { /* Ignore these if they are not on this bus */ if (dev->parent != bus) continue; parent_data = dev_get_parent_priv(dev); ut_asserteq(value, parent_data->sum); value += 5; } return 0; }
void IntelHDAStreamBase::Deactivate() { { fbl::AutoLock obj_lock(&obj_lock_); DEBUG_LOG("Deactivating stream\n"); // Let go of any unsolicited stream tags we may be holding. if (unsol_tag_count_) { ZX_DEBUG_ASSERT(parent_codec_ != nullptr); parent_codec_->ReleaseAllUnsolTags(*this); unsol_tag_count_ = 0; } // Clear out our parent_codec_ pointer. This will mark us as being // inactive and prevent any new connections from being made. parent_codec_.reset(); // We should already have been removed from our codec's active stream list // at this point. ZX_DEBUG_ASSERT(!this->InContainer()); } default_domain_->Deactivate(); { fbl::AutoLock obj_lock(&obj_lock_); ZX_DEBUG_ASSERT(stream_channel_ == nullptr); // Allow our implementation to send the commands needed to tear down the // widgets which make up this stream. OnDeactivateLocked(); // If we have been given a DMA stream by the IHDA controller, attempt to // return it now. if ((dma_stream_id_ != IHDA_INVALID_STREAM_ID) && (codec_channel_ != nullptr)) { ihda_proto::ReleaseStreamReq req; req.hdr.transaction_id = id(); req.hdr.cmd = IHDA_CODEC_RELEASE_STREAM_NOACK, req.stream_id = dma_stream_id_; codec_channel_->Write(&req, sizeof(req)); dma_stream_id_ = IHDA_INVALID_STREAM_ID; dma_stream_tag_ = IHDA_INVALID_STREAM_TAG; } // Let go of our reference to the codec device channel. codec_channel_ = nullptr; // If we had published a device node, remove it now. if (parent_device_ != nullptr) { device_remove(stream_device_); parent_device_ = nullptr; } } DEBUG_LOG("Deactivate complete\n"); }
int device_remove_all(void) { int i; int res = 0; for (i=dev_ptr-1; i>=0; i--) res |= device_remove(devices[i]); return res; }
int mmc_unbind(struct udevice *dev) { struct udevice *bdev; device_find_first_child(dev, &bdev); if (bdev) { device_remove(bdev); device_unbind(bdev); } return 0; }
/* Test that we can bind, probe, remove, unbind a driver */ static int dm_test_lifecycle(struct unit_test_state *uts) { struct dm_test_state *dms = uts->priv; int op_count[DM_TEST_OP_COUNT]; struct udevice *dev, *test_dev; int pingret; int ret; memcpy(op_count, dm_testdrv_op_count, sizeof(op_count)); ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual, &dev)); ut_assert(dev); ut_assert(dm_testdrv_op_count[DM_TEST_OP_BIND] == op_count[DM_TEST_OP_BIND] + 1); ut_assert(!dev->priv); /* Probe the device - it should fail allocating private data */ dms->force_fail_alloc = 1; ret = device_probe(dev); ut_assert(ret == -ENOMEM); ut_assert(dm_testdrv_op_count[DM_TEST_OP_PROBE] == op_count[DM_TEST_OP_PROBE] + 1); ut_assert(!dev->priv); /* Try again without the alloc failure */ dms->force_fail_alloc = 0; ut_assertok(device_probe(dev)); ut_assert(dm_testdrv_op_count[DM_TEST_OP_PROBE] == op_count[DM_TEST_OP_PROBE] + 2); ut_assert(dev->priv); /* This should be device 3 in the uclass */ ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev)); ut_assert(dev == test_dev); /* Try ping */ ut_assertok(test_ping(dev, 100, &pingret)); ut_assert(pingret == 102); /* Now remove device 3 */ ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]); ut_assertok(device_remove(dev)); ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]); ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_UNBIND]); ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]); ut_assertok(device_unbind(dev)); ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]); ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]); return 0; }
int usb_stop(void) { struct udevice *bus; struct uclass *uc; int err = 0, ret; /* De-activate any devices that have been activated */ ret = uclass_get(UCLASS_USB, &uc); if (ret) return ret; uclass_foreach_dev(bus, uc) { ret = device_remove(bus); if (ret && !err) err = ret; }
/** * This test case is trying to test the following scenario: * - All ethernet devices are not probed * - "ethaddr" for all ethernet devices are not set * - "ethact" is set to a valid ethernet device name * * With Sandbox default test configuration, all ethernet devices are * probed after power-up, so we have to manually create such scenario: * - Remove all ethernet devices * - Remove all "ethaddr" environment variables * - Set "ethact" to the first ethernet device * * Do a ping test to see if anything goes wrong. */ static int dm_test_eth_act(struct unit_test_state *uts) { struct udevice *dev[DM_TEST_ETH_NUM]; const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000", "sbe5", "eth@10004000"}; const char *addrname[DM_TEST_ETH_NUM] = {"ethaddr", "eth5addr", "eth3addr", "eth1addr"}; char ethaddr[DM_TEST_ETH_NUM][18]; int i; memset(ethaddr, '\0', sizeof(ethaddr)); net_ping_ip = string_to_ip("1.1.2.2"); /* Prepare the test scenario */ for (i = 0; i < DM_TEST_ETH_NUM; i++) { ut_assertok(uclass_find_device_by_name(UCLASS_ETH, ethname[i], &dev[i])); ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL)); /* Invalidate MAC address */ strncpy(ethaddr[i], env_get(addrname[i]), 17); /* Must disable access protection for ethaddr before clearing */ env_set(".flags", addrname[i]); env_set(addrname[i], NULL); } /* Set ethact to "eth@10002000" */ env_set("ethact", ethname[0]); /* Segment fault might happen if something is wrong */ ut_asserteq(-ENODEV, net_loop(PING)); for (i = 0; i < DM_TEST_ETH_NUM; i++) { /* Restore the env */ env_set(".flags", addrname[i]); env_set(addrname[i], ethaddr[i]); /* Probe the device again */ ut_assertok(device_probe(dev[i])); } env_set(".flags", NULL); env_set("ethact", NULL); return 0; }
/* Remove all drivers and check that things work */ static int dm_test_remove(struct unit_test_state *uts) { struct udevice *dev; int i; for (i = 0; i < 3; i++) { ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev)); ut_assert(dev); ut_assertf(dev->flags & DM_FLAG_ACTIVATED, "Driver %d/%s not activated", i, dev->name); ut_assertok(device_remove(dev)); ut_assertf(!(dev->flags & DM_FLAG_ACTIVATED), "Driver %d/%s should have deactivated", i, dev->name); ut_assert(!dev->priv); } return 0; }
int blk_unbind_all(int if_type) { struct uclass *uc; struct udevice *dev, *next; int ret; ret = uclass_get(UCLASS_BLK, &uc); if (ret) return ret; uclass_foreach_dev_safe(dev, next, uc) { struct blk_desc *desc = dev_get_uclass_platdata(dev); if (desc->if_type == if_type) { ret = device_remove(dev); if (ret) return ret; ret = device_unbind(dev); if (ret) return ret; } } return 0; }
void spi_free_slave(struct spi_slave *slave) { device_remove(slave->dev); slave->dev = NULL; }
int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, const char *drv_name, const char *dev_name, struct udevice **busp, struct spi_slave **devp) { struct udevice *bus, *dev; struct dm_spi_slave_platdata *plat; bool created = false; int ret; ret = uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus); if (ret) { printf("Invalid bus %d (err=%d)\n", busnum, ret); return ret; } ret = spi_find_chip_select(bus, cs, &dev); /* * If there is no such device, create one automatically. This means * that we don't need a device tree node or platform data for the * SPI flash chip - we will bind to the correct driver. */ if (ret == -ENODEV && drv_name) { debug("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n", __func__, dev_name, busnum, cs, drv_name); ret = device_bind_driver(bus, drv_name, dev_name, &dev); if (ret) return ret; plat = dev_get_parent_platdata(dev); plat->cs = cs; plat->max_hz = speed; plat->mode = mode; created = true; } else if (ret) { printf("Invalid chip select %d:%d (err=%d)\n", busnum, cs, ret); return ret; } if (!device_active(dev)) { struct spi_slave *slave; ret = device_probe(dev); if (ret) goto err; slave = dev_get_parent_priv(dev); slave->dev = dev; } plat = dev_get_parent_platdata(dev); if (!speed) { speed = plat->max_hz; mode = plat->mode; } ret = spi_set_speed_mode(bus, speed, mode); if (ret) goto err; *busp = bus; *devp = dev_get_parent_priv(dev); debug("%s: bus=%p, slave=%p\n", __func__, bus, *devp); return 0; err: debug("%s: Error path, created=%d, device '%s'\n", __func__, created, dev->name); if (created) { device_remove(dev); device_unbind(dev); } return ret; }
int spi_flash_remove(struct udevice *dev) { return device_remove(dev); }
void spi_free_slave(struct spi_slave *slave) { device_remove(slave->dev, DM_REMOVE_NORMAL); slave->dev = NULL; }
/* Test that we can find buses and chip-selects */ static int dm_test_spi_find(struct dm_test_state *dms) { struct sandbox_state *state = state_get_current(); struct spi_slave *slave; struct udevice *bus, *dev; const int busnum = 0, cs = 0, mode = 0, speed = 1000000, cs_b = 1; struct spi_cs_info info; int of_offset; ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_SPI, busnum, false, &bus)); /* * spi_post_bind() will bind devices to chip selects. Check this then * remove the emulation and the slave device. */ ut_asserteq(0, uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus)); ut_assertok(spi_cs_info(bus, cs, &info)); of_offset = info.dev->of_offset; device_remove(info.dev); device_unbind(info.dev); /* * Even though the device is gone, the sandbox SPI drivers always * reports that CS 0 is present */ ut_assertok(spi_cs_info(bus, cs, &info)); ut_asserteq_ptr(NULL, info.dev); /* This finds nothing because we removed the device */ ut_asserteq(-ENODEV, spi_find_bus_and_cs(busnum, cs, &bus, &dev)); ut_asserteq(-ENODEV, spi_get_bus_and_cs(busnum, cs, speed, mode, NULL, 0, &bus, &slave)); /* * This forces the device to be re-added, but there is no emulation * connected so the probe will fail. We require that bus is left * alone on failure, and that the spi_get_bus_and_cs() does not add * a 'partially-inited' device. */ ut_asserteq(-ENODEV, spi_find_bus_and_cs(busnum, cs, &bus, &dev)); ut_asserteq(-ENOENT, spi_get_bus_and_cs(busnum, cs, speed, mode, "spi_flash_std", "name", &bus, &slave)); sandbox_sf_unbind_emul(state_get_current(), busnum, cs); ut_assertok(spi_cs_info(bus, cs, &info)); ut_asserteq_ptr(NULL, info.dev); /* Add the emulation and try again */ ut_assertok(sandbox_sf_bind_emul(state, busnum, cs, bus, of_offset, "name")); ut_assertok(spi_find_bus_and_cs(busnum, cs, &bus, &dev)); ut_assertok(spi_get_bus_and_cs(busnum, cs, speed, mode, "spi_flash_std", "name", &bus, &slave)); ut_assertok(spi_cs_info(bus, cs, &info)); ut_asserteq_ptr(info.dev, slave->dev); /* We should be able to add something to another chip select */ ut_assertok(sandbox_sf_bind_emul(state, busnum, cs_b, bus, of_offset, "name")); ut_assertok(spi_get_bus_and_cs(busnum, cs_b, speed, mode, "spi_flash_std", "name", &bus, &slave)); ut_assertok(spi_cs_info(bus, cs_b, &info)); ut_asserteq_ptr(info.dev, slave->dev); /* * Since we are about to destroy all devices, we must tell sandbox * to forget the emulation device */ sandbox_sf_unbind_emul(state_get_current(), busnum, cs); sandbox_sf_unbind_emul(state_get_current(), busnum, cs_b); return 0; }
static void mbr_unbind(void* ctx) { mbrpart_device_t* device = ctx; device_remove(device->zxdev); }
static int test_bus_parent_platdata(struct unit_test_state *uts) { struct dm_test_parent_platdata *plat; struct udevice *bus, *dev; int child_count; /* Check that the bus has no children */ ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); device_find_first_child(bus, &dev); ut_asserteq_ptr(NULL, dev); ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); for (device_find_first_child(bus, &dev), child_count = 0; dev; device_find_next_child(&dev)) { /* Check that platform data is allocated */ plat = dev_get_parent_platdata(dev); ut_assert(plat != NULL); /* * Check that it is not affected by the device being * probed/removed */ plat->count++; ut_asserteq(1, plat->count); device_probe(dev); device_remove(dev); ut_asserteq_ptr(plat, dev_get_parent_platdata(dev)); ut_asserteq(1, plat->count); ut_assertok(device_probe(dev)); child_count++; } ut_asserteq(3, child_count); /* Removing the bus should also have no effect (it is still bound) */ device_remove(bus); for (device_find_first_child(bus, &dev), child_count = 0; dev; device_find_next_child(&dev)) { /* Check that platform data is allocated */ plat = dev_get_parent_platdata(dev); ut_assert(plat != NULL); ut_asserteq(1, plat->count); child_count++; } ut_asserteq(3, child_count); /* Unbind all the children */ do { device_find_first_child(bus, &dev); if (dev) device_unbind(dev); } while (dev); /* Now the child platdata should be removed and re-added */ device_probe(bus); for (device_find_first_child(bus, &dev), child_count = 0; dev; device_find_next_child(&dev)) { /* Check that platform data is allocated */ plat = dev_get_parent_platdata(dev); ut_assert(plat != NULL); ut_asserteq(0, plat->count); child_count++; } ut_asserteq(3, child_count); return 0; }
static int mbr_bind_thread(void* arg) { mbrpart_device_t* first_dev = (mbrpart_device_t*)arg; zx_device_t* dev = first_dev->parent; // Classic MBR supports 4 partitions. uint8_t partition_count = 0; block_impl_protocol_t bp; memcpy(&bp, &first_dev->bp, sizeof(bp)); block_info_t block_info; size_t block_op_size; block_impl_query(&bp, &block_info, &block_op_size); zx_handle_t vmo = ZX_HANDLE_INVALID; block_op_t* bop = calloc(1, block_op_size); if (bop == NULL) { goto unbind; } // We need to read at least 512B to parse the MBR. Determine if we should // read the device's block size or we should ready exactly 512B. size_t iosize = 0; if (block_info.block_size >= MBR_SIZE) { iosize = block_info.block_size; } else { // Make sure we're reading some multiple of the block size. iosize = DIV_ROUND_UP(MBR_SIZE, block_info.block_size) * block_info.block_size; } if (zx_vmo_create(iosize, 0, &vmo) != ZX_OK) { zxlogf(ERROR, "mbr: cannot allocate vmo\n"); goto unbind; } sync_completion_t cplt = SYNC_COMPLETION_INIT; bop->command = BLOCK_OP_READ; bop->rw.vmo = vmo; bop->rw.length = iosize / block_info.block_size; bop->rw.offset_dev = 0; bop->rw.offset_vmo = 0; bp.ops->queue(bp.ctx, bop, mbr_read_sync_complete, &cplt); sync_completion_wait(&cplt, ZX_TIME_INFINITE); if (bop->command != ZX_OK) { zxlogf(ERROR, "mbr: could not read mbr from device, retcode = %d\n", bop->command); goto unbind; } uint8_t buffer[MBR_SIZE]; mbr_t* mbr = (mbr_t*)buffer; if (vmo_read(vmo, buffer, 0, MBR_SIZE) != ZX_OK) { goto unbind; } // Validate the MBR boot signature. if (mbr->boot_signature != MBR_BOOT_SIGNATURE) { zxlogf(ERROR, "mbr: invalid mbr boot signature, expected 0x%04x got 0x%04x\n", MBR_BOOT_SIGNATURE, mbr->boot_signature); goto unbind; } // Parse the partitions out of the MBR. for (; partition_count < MBR_NUM_PARTITIONS; partition_count++) { mbr_partition_entry_t* entry = &mbr->partition[partition_count]; if (entry->type == PARTITION_TYPE_NONE) { // This partition entry is empty and does not refer to a partition, // skip it. continue; } zxlogf(SPEW, "mbr: found partition, entry = %d, type = 0x%02x, " "start = %u, length = %u\n", partition_count + 1, entry->type, entry->start_sector_lba, entry->sector_partition_length); mbrpart_device_t* pdev; // use first_dev for first partition if (first_dev) { pdev = first_dev; } else { pdev = calloc(1, sizeof(*pdev)); if (!pdev) { zxlogf(ERROR, "mbr: out of memory\n"); goto unbind; } pdev->parent = dev; memcpy(&pdev->bp, &bp, sizeof(bp)); } memcpy(&pdev->partition, entry, sizeof(*entry)); block_info.block_count = pdev->partition.sector_partition_length; memcpy(&pdev->info, &block_info, sizeof(block_info)); pdev->block_op_size = block_op_size; if (first_dev) { // make our initial device visible and use if for partition zero device_make_visible(first_dev->zxdev); first_dev = NULL; } else { char name[16]; snprintf(name, sizeof(name), "part-%03u",partition_count); device_add_args_t args = { .version = DEVICE_ADD_ARGS_VERSION, .name = name, .ctx = pdev, .ops = &mbr_proto, .proto_id = ZX_PROTOCOL_BLOCK_IMPL, .proto_ops = &block_ops, }; if (device_add(dev, &args, &pdev->zxdev) != ZX_OK) { free(pdev); continue; } } } free(bop); zx_handle_close(vmo); return 0; unbind: free(bop); zx_handle_close(vmo); if (first_dev) { // handle case where no partitions were found device_remove(first_dev->zxdev); } return -1; }
void spi_flash_free(struct spi_flash *flash) { device_remove(flash->spi->dev, DM_REMOVE_NORMAL); }
void spi_flash_free(struct spi_flash *flash) { device_remove(flash->spi->dev); }
static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct cros_ec_dev *dev; struct udevice *udev; const char *cmd; int ret = 0; if (argc < 2) return CMD_RET_USAGE; cmd = argv[1]; if (0 == strcmp("init", cmd)) { /* Remove any existing device */ ret = uclass_find_device(UCLASS_CROS_EC, 0, &udev); if (!ret) device_remove(udev); ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev); if (ret) { printf("Could not init cros_ec device (err %d)\n", ret); return 1; } return 0; } ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev); if (ret) { printf("Cannot get cros-ec device (err=%d)\n", ret); return 1; } dev = dev_get_uclass_priv(udev); if (0 == strcmp("id", cmd)) { char id[MSG_BYTES]; if (cros_ec_read_id(dev, id, sizeof(id))) { debug("%s: Could not read KBC ID\n", __func__); return 1; } printf("%s\n", id); } else if (0 == strcmp("info", cmd)) { struct ec_response_mkbp_info info; if (cros_ec_info(dev, &info)) { debug("%s: Could not read KBC info\n", __func__); return 1; } printf("rows = %u\n", info.rows); printf("cols = %u\n", info.cols); printf("switches = %#x\n", info.switches); } else if (0 == strcmp("curimage", cmd)) { enum ec_current_image image; if (cros_ec_read_current_image(dev, &image)) { debug("%s: Could not read KBC image\n", __func__); return 1; } printf("%d\n", image); } else if (0 == strcmp("hash", cmd)) { struct ec_response_vboot_hash hash; int i; if (cros_ec_read_hash(dev, &hash)) { debug("%s: Could not read KBC hash\n", __func__); return 1; } if (hash.hash_type == EC_VBOOT_HASH_TYPE_SHA256) printf("type: SHA-256\n"); else printf("type: %d\n", hash.hash_type); printf("offset: 0x%08x\n", hash.offset); printf("size: 0x%08x\n", hash.size); printf("digest: "); for (i = 0; i < hash.digest_size; i++) printf("%02x", hash.hash_digest[i]); printf("\n"); } else if (0 == strcmp("reboot", cmd)) { int region; enum ec_reboot_cmd cmd; if (argc >= 3 && !strcmp(argv[2], "cold")) cmd = EC_REBOOT_COLD; else { region = cros_ec_decode_region(argc - 2, argv + 2); if (region == EC_FLASH_REGION_RO) cmd = EC_REBOOT_JUMP_RO; else if (region == EC_FLASH_REGION_RW) cmd = EC_REBOOT_JUMP_RW; else return CMD_RET_USAGE; } if (cros_ec_reboot(dev, cmd, 0)) { debug("%s: Could not reboot KBC\n", __func__); return 1; } } else if (0 == strcmp("events", cmd)) { uint32_t events; if (cros_ec_get_host_events(dev, &events)) { debug("%s: Could not read host events\n", __func__); return 1; } printf("0x%08x\n", events); } else if (0 == strcmp("clrevents", cmd)) { uint32_t events = 0x7fffffff; if (argc >= 3) events = simple_strtol(argv[2], NULL, 0); if (cros_ec_clear_host_events(dev, events)) { debug("%s: Could not clear host events\n", __func__); return 1; } } else if (0 == strcmp("read", cmd)) { ret = do_read_write(dev, 0, argc, argv); if (ret > 0) return CMD_RET_USAGE; } else if (0 == strcmp("write", cmd)) { ret = do_read_write(dev, 1, argc, argv); if (ret > 0) return CMD_RET_USAGE; } else if (0 == strcmp("erase", cmd)) { int region = cros_ec_decode_region(argc - 2, argv + 2); uint32_t offset, size; if (region == -1) return CMD_RET_USAGE; if (cros_ec_flash_offset(dev, region, &offset, &size)) { debug("%s: Could not read region info\n", __func__); ret = -1; } else { ret = cros_ec_flash_erase(dev, offset, size); if (ret) { debug("%s: Could not erase region\n", __func__); } } } else if (0 == strcmp("regioninfo", cmd)) { int region = cros_ec_decode_region(argc - 2, argv + 2); uint32_t offset, size; if (region == -1) return CMD_RET_USAGE; ret = cros_ec_flash_offset(dev, region, &offset, &size); if (ret) { debug("%s: Could not read region info\n", __func__); } else { printf("Region: %s\n", region == EC_FLASH_REGION_RO ? "RO" : "RW"); printf("Offset: %x\n", offset); printf("Size: %x\n", size); } } else if (0 == strcmp("vbnvcontext", cmd)) { uint8_t block[EC_VBNV_BLOCK_SIZE]; char buf[3]; int i, len; unsigned long result; if (argc <= 2) { ret = cros_ec_read_vbnvcontext(dev, block); if (!ret) { printf("vbnv_block: "); for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++) printf("%02x", block[i]); putc('\n'); } } else { /* * TODO(clchiou): Move this to a utility function as * cmd_spi might want to call it. */ memset(block, 0, EC_VBNV_BLOCK_SIZE); len = strlen(argv[2]); buf[2] = '\0'; for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++) { if (i * 2 >= len) break; buf[0] = argv[2][i * 2]; if (i * 2 + 1 >= len) buf[1] = '0'; else buf[1] = argv[2][i * 2 + 1]; strict_strtoul(buf, 16, &result); block[i] = result; } ret = cros_ec_write_vbnvcontext(dev, block); } if (ret) { debug("%s: Could not %s VbNvContext\n", __func__, argc <= 2 ? "read" : "write"); } } else if (0 == strcmp("test", cmd)) { int result = cros_ec_test(dev); if (result) printf("Test failed with error %d\n", result); else puts("Test passed\n"); } else if (0 == strcmp("version", cmd)) { struct ec_response_get_version *p; char *build_string; ret = cros_ec_read_version(dev, &p); if (!ret) { /* Print versions */ printf("RO version: %1.*s\n", (int)sizeof(p->version_string_ro), p->version_string_ro); printf("RW version: %1.*s\n", (int)sizeof(p->version_string_rw), p->version_string_rw); printf("Firmware copy: %s\n", (p->current_image < ARRAY_SIZE(ec_current_image_name) ? ec_current_image_name[p->current_image] : "?")); ret = cros_ec_read_build_info(dev, &build_string); if (!ret) printf("Build info: %s\n", build_string); } } else if (0 == strcmp("ldo", cmd)) { uint8_t index, state; char *endp; if (argc < 3) return CMD_RET_USAGE; index = simple_strtoul(argv[2], &endp, 10); if (*argv[2] == 0 || *endp != 0) return CMD_RET_USAGE; if (argc > 3) { state = simple_strtoul(argv[3], &endp, 10); if (*argv[3] == 0 || *endp != 0) return CMD_RET_USAGE; ret = cros_ec_set_ldo(udev, index, state); } else { ret = cros_ec_get_ldo(udev, index, &state); if (!ret) { printf("LDO%d: %s\n", index, state == EC_LDO_STATE_ON ? "on" : "off"); } } if (ret) { debug("%s: Could not access LDO%d\n", __func__, index); return ret; } } else { return CMD_RET_USAGE; } if (ret < 0) { printf("Error: CROS-EC command failed (error %d)\n", ret); ret = 1; } return ret; }
int host_dev_bind(int devnum, char *filename) { struct host_block_dev *host_dev; struct udevice *dev; char dev_name[20], *str, *fname; int ret, fd; /* Remove and unbind the old device, if any */ ret = blk_get_device(IF_TYPE_HOST, devnum, &dev); if (ret == 0) { ret = device_remove(dev); if (ret) return ret; ret = device_unbind(dev); if (ret) return ret; } else if (ret != -ENODEV) { return ret; } if (!filename) return 0; snprintf(dev_name, sizeof(dev_name), "host%d", devnum); str = strdup(dev_name); if (!str) return -ENOMEM; fname = strdup(filename); if (!fname) { free(str); return -ENOMEM; } fd = os_open(filename, OS_O_RDWR); if (fd == -1) { printf("Failed to access host backing file '%s'\n", filename); ret = -ENOENT; goto err; } ret = blk_create_device(gd->dm_root, "sandbox_host_blk", str, IF_TYPE_HOST, devnum, 512, os_lseek(fd, 0, OS_SEEK_END), &dev); if (ret) goto err_file; ret = device_probe(dev); if (ret) { device_unbind(dev); goto err_file; } host_dev = dev_get_priv(dev); host_dev->fd = fd; host_dev->filename = fname; return blk_prepare_device(dev); err_file: os_close(fd); err: free(fname); free(str); return ret; }
static int dm_test_children(struct unit_test_state *uts) { struct dm_test_state *dms = uts->priv; struct udevice *top[NODE_COUNT]; struct udevice *child[NODE_COUNT]; struct udevice *grandchild[NODE_COUNT]; struct udevice *dev; int total; int ret; int i; /* We don't care about the numbering for this test */ dms->skip_post_probe = 1; ut_assert(NODE_COUNT > 5); /* First create 10 top-level children */ ut_assertok(create_children(uts, dms->root, NODE_COUNT, 0, top)); /* Now a few have their own children */ ut_assertok(create_children(uts, top[2], NODE_COUNT, 2, NULL)); ut_assertok(create_children(uts, top[5], NODE_COUNT, 5, child)); /* And grandchildren */ for (i = 0; i < NODE_COUNT; i++) ut_assertok(create_children(uts, child[i], NODE_COUNT, 50 * i, i == 2 ? grandchild : NULL)); /* Check total number of devices */ total = NODE_COUNT * (3 + NODE_COUNT); ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_BIND]); /* Try probing one of the grandchildren */ ut_assertok(uclass_get_device(UCLASS_TEST, NODE_COUNT * 3 + 2 * NODE_COUNT, &dev)); ut_asserteq_ptr(grandchild[0], dev); /* * This should have probed the child and top node also, for a total * of 3 nodes. */ ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PROBE]); /* Probe the other grandchildren */ for (i = 1; i < NODE_COUNT; i++) ut_assertok(device_probe(grandchild[i])); ut_asserteq(2 + NODE_COUNT, dm_testdrv_op_count[DM_TEST_OP_PROBE]); /* Probe everything */ for (ret = uclass_first_device(UCLASS_TEST, &dev); dev; ret = uclass_next_device(&dev)) ; ut_assertok(ret); ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_PROBE]); /* Remove a top-level child and check that the children are removed */ ut_assertok(device_remove(top[2])); ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_REMOVE]); dm_testdrv_op_count[DM_TEST_OP_REMOVE] = 0; /* Try one with grandchildren */ ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev)); ut_asserteq_ptr(dev, top[5]); ut_assertok(device_remove(dev)); ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT), dm_testdrv_op_count[DM_TEST_OP_REMOVE]); /* Try the same with unbind */ ut_assertok(device_unbind(top[2])); ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]); dm_testdrv_op_count[DM_TEST_OP_UNBIND] = 0; /* Try one with grandchildren */ ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev)); ut_asserteq_ptr(dev, top[6]); ut_assertok(device_unbind(top[5])); ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT), dm_testdrv_op_count[DM_TEST_OP_UNBIND]); return 0; }
/** * connman_device_unregister: * @device: device structure * * Unregister device with the system */ void connman_device_unregister(struct connman_device *device) { __connman_storage_save_device(device); device_remove(device); }