Пример #1
0
static int
nandsim_detach(device_t dev)
{
	struct nandsim_softc *sc;
	struct sim_ctrl_conf *params;
	int i;

	sc = device_get_softc(dev);
	params = &ctrls[device_get_unit(dev)];

	for (i = 0; i < params->num_cs; i++)
		if (sc->chips[i] != NULL)
			nandsim_chip_destroy(sc->chips[i]);

	nandsim_log_close(sc);

	return (0);
}
Пример #2
0
struct nandsim_chip *
nandsim_chip_init(struct nandsim_softc* sc, uint8_t chip_num,
    struct sim_chip *sim_chip)
{
	struct nandsim_chip *chip;
	struct onfi_params *chip_param;
	char swapfile[20];
	uint32_t size;
	int error;

	chip = malloc(sizeof(*chip), M_NANDSIM, M_WAITOK | M_ZERO);
	if (!chip)
		return (NULL);

	mtx_init(&chip->ns_lock, "nandsim lock", NULL, MTX_DEF);
	callout_init(&chip->ns_callout, 1);
	STAILQ_INIT(&chip->nandsim_events);

	chip->chip_num = chip_num;
	chip->ctrl_num = sim_chip->ctrl_num;
	chip->sc = sc;

	if (!sim_chip->is_wp)
		nandchip_set_status(chip, NAND_STATUS_WP);

	chip_param = &chip->params;

	chip->id.dev_id = sim_chip->device_id;
	chip->id.man_id = sim_chip->manufact_id;

	chip->error_ratio = sim_chip->error_ratio;
	chip->wear_level = sim_chip->wear_level;
	chip->prog_delay = sim_chip->prog_time;
	chip->erase_delay = sim_chip->erase_time;
	chip->read_delay = sim_chip->read_time;

	chip_param->t_prog = sim_chip->prog_time;
	chip_param->t_bers = sim_chip->erase_time;
	chip_param->t_r = sim_chip->read_time;
	bcopy("onfi", &chip_param->signature, 4);

	chip_param->manufacturer_id = sim_chip->manufact_id;
	strncpy(chip_param->manufacturer_name, sim_chip->manufacturer, 12);
	chip_param->manufacturer_name[11] = 0;
	strncpy(chip_param->device_model, sim_chip->device_model, 20);
	chip_param->device_model[19] = 0;

	chip_param->bytes_per_page = sim_chip->page_size;
	chip_param->spare_bytes_per_page = sim_chip->oob_size;
	chip_param->pages_per_block = sim_chip->pgs_per_blk;
	chip_param->blocks_per_lun = sim_chip->blks_per_lun;
	chip_param->luns = sim_chip->luns;

	init_chip_geom(&chip->cg, chip_param->luns, chip_param->blocks_per_lun,
	    chip_param->pages_per_block, chip_param->bytes_per_page,
	    chip_param->spare_bytes_per_page);

	chip_param->address_cycles = sim_chip->row_addr_cycles |
	    (sim_chip->col_addr_cycles << 4);
	chip_param->features = sim_chip->features;
	if (sim_chip->width == 16)
		chip_param->features |= ONFI_FEAT_16BIT;

	size = chip_param->blocks_per_lun * chip_param->luns;

	error = nandsim_blk_state_init(chip, size, sim_chip->wear_level);
	if (error) {
		mtx_destroy(&chip->ns_lock);
		free(chip, M_NANDSIM);
		return (NULL);
	}

	error = nandsim_bbm_init(chip, size, sim_chip->bad_block_map);
	if (error) {
		mtx_destroy(&chip->ns_lock);
		nandsim_blk_state_destroy(chip);
		free(chip, M_NANDSIM);
		return (NULL);
	}

	nandsim_start_handler(chip, poweron_evh);

	nand_debug(NDBG_SIM,"Create thread for chip%d [%8p]", chip->chip_num,
	    chip);
	/* Create chip thread */
	error = kproc_kthread_add(nandsim_loop, chip, &nandsim_proc,
	    &chip->nandsim_td, RFSTOPPED | RFHIGHPID,
	    0, "nandsim", "chip");
	if (error) {
		mtx_destroy(&chip->ns_lock);
		nandsim_blk_state_destroy(chip);
		free(chip, M_NANDSIM);
		return (NULL);
	}

	thread_lock(chip->nandsim_td);
	sched_class(chip->nandsim_td, PRI_REALTIME);
	sched_add(chip->nandsim_td, SRQ_BORING);
	thread_unlock(chip->nandsim_td);

	size = (chip_param->bytes_per_page +
	    chip_param->spare_bytes_per_page) *
	    chip_param->pages_per_block;

	sprintf(swapfile, "chip%d%d.swp", chip->ctrl_num, chip->chip_num);
	chip->swap = nandsim_swap_init(swapfile, chip_param->blocks_per_lun *
	    chip_param->luns, size);
	if (!chip->swap)
		nandsim_chip_destroy(chip);

	/* Wait for new thread to enter main loop */
	tsleep(chip->nandsim_td, PWAIT, "ns_chip", 1 * hz);

	return (chip);
}