예제 #1
0
/* Return true if this partition is supported by the fastboot format command.
 * It is also used to determine if we should first erase a partition before
 * flashing it with an ext4 filesystem.  See needs_erase()
 *
 * Not all devices report the filesystem type, so don't report any errors,
 * just return false.
 */
int fb_format_supported(usb_handle *usb, const char *partition)
{
    char response[FB_RESPONSE_SZ+1];
    struct generator *generator = NULL;
    int status;
    unsigned int i;

    status = fb_getvar(usb, response, "partition-type:%s", partition);
    if (status) {
        return 0;
    }

    for (i = 0; i < ARRAY_SIZE(generators); i++) {
        if (!strncmp(generators[i].fs_type, response, FB_RESPONSE_SZ)) {
            generator = &generators[i];
            break;
        }
    }

    if (generator) {
        return 1;
    }

    return 0;
}
예제 #2
0
static int64_t get_target_sparse_limit(struct usb_handle *usb)
{
    int64_t limit = 0;
    char response[FB_RESPONSE_SZ + 1];
    int status = fb_getvar(usb, response, "max-download-size");

    if (!status) {
        limit = strtoul(response, NULL, 0);
        if (limit > 0) {
            fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n",
                    limit);
        }
    }

    return limit;
}
예제 #3
0
static int64_t get_target_sparse_limit(transport_t *trans)
{
    int64_t limit = 0;
    char response[FB_RESPONSE_SZ + 1];
    int status = fb_getvar(trans, response, "max-download-size");

    if (!status) {
        limit = strtoul(response, NULL, 0);
        if (limit > 0) {
            fprintf(stderr, "target reported max download size of %lld bytes\n",
                    limit);
        }
    }

    return limit;
}
예제 #4
0
void fb_perform_format(usb_handle* usb,
                       const char *partition, int skip_if_not_supported,
                       const char *type_override, const char *size_override)
{
    char pTypeBuff[FB_RESPONSE_SZ + 1], pSizeBuff[FB_RESPONSE_SZ + 1];
    char *pType = pTypeBuff;
    char *pSize = pSizeBuff;
    unsigned int limit = INT_MAX;
    struct fastboot_buffer buf;
    const char *errMsg = NULL;
    const struct fs_generator *gen;
    uint64_t pSz;
    int status;
    int fd;

    if (target_sparse_limit > 0 && target_sparse_limit < limit)
        limit = target_sparse_limit;
    if (sparse_limit > 0 && sparse_limit < limit)
        limit = sparse_limit;

    status = fb_getvar(usb, pType, "partition-type:%s", partition);
    if (status) {
        errMsg = "Can't determine partition type.\n";
        goto failed;
    }
    if (type_override) {
        if (strcmp(type_override, pType)) {
            fprintf(stderr,
                    "Warning: %s type is %s, but %s was requested for formating.\n",
                    partition, pType, type_override);
        }
        pType = (char *)type_override;
    }

    status = fb_getvar(usb, pSize, "partition-size:%s", partition);
    if (status) {
        errMsg = "Unable to get partition size\n";
        goto failed;
    }
    if (size_override) {
        if (strcmp(size_override, pSize)) {
            fprintf(stderr,
                    "Warning: %s size is %s, but %s was requested for formating.\n",
                    partition, pSize, size_override);
        }
        pSize = (char *)size_override;
    }

    gen = fs_get_generator(pType);
    if (!gen) {
        if (skip_if_not_supported) {
            fprintf(stderr, "Erase successful, but not automatically formatting.\n");
            fprintf(stderr, "File system type %s not supported.\n", pType);
            return;
        }
        fprintf(stderr, "Formatting is not supported for filesystem with type '%s'.\n", pType);
        return;
    }

    pSz = strtoll(pSize, (char **)NULL, 16);

    fd = fileno(tmpfile());
    if (fs_generator_generate(gen, fd, pSz)) {
        close(fd);
        fprintf(stderr, "Cannot generate image.\n");
        return;
    }

    if (load_buf_fd(usb, fd, &buf)) {
        fprintf(stderr, "Cannot read image.\n");
        close(fd);
        return;
    }
    flash_buf(partition, &buf);

    return;


failed:
    if (skip_if_not_supported) {
        fprintf(stderr, "Erase successful, but not automatically formatting.\n");
        if (errMsg)
            fprintf(stderr, "%s", errMsg);
    }
    fprintf(stderr,"FAILED (%s)\n", fb_get_error());
}
예제 #5
0
int fb_format(Action *a, usb_handle *usb, int skip_if_not_supported)
{
    const char *partition = a->cmd;
    char response[FB_RESPONSE_SZ+1];
    int status = 0;
    struct image_data image;
    struct generator *generator = NULL;
    int fd;
    unsigned i;
    char cmd[CMD_SIZE];

    status = fb_getvar(usb, response, "partition-type:%s", partition);
    if (status) {
        if (skip_if_not_supported) {
            fprintf(stderr,
                    "Erase successful, but not automatically formatting.\n");
            fprintf(stderr,
                    "Can't determine partition type.\n");
            return 0;
        }
        fprintf(stderr,"FAILED (%s)\n", fb_get_error());
        return status;
    }

    for (i = 0; i < ARRAY_SIZE(generators); i++) {
        if (!strncmp(generators[i].fs_type, response, FB_RESPONSE_SZ)) {
            generator = &generators[i];
            break;
        }
    }
    if (!generator) {
        if (skip_if_not_supported) {
            fprintf(stderr,
                    "Erase successful, but not automatically formatting.\n");
            fprintf(stderr,
                    "File system type %s not supported.\n", response);
            return 0;
        }
        fprintf(stderr,"Formatting is not supported for filesystem with type '%s'.\n",
                response);
        return -1;
    }

    status = fb_getvar(usb, response, "partition-size:%s", partition);
    if (status) {
        if (skip_if_not_supported) {
            fprintf(stderr,
                    "Erase successful, but not automatically formatting.\n");
            fprintf(stderr, "Unable to get partition size\n.");
            return 0;
        }
        fprintf(stderr,"FAILED (%s)\n", fb_get_error());
        return status;
    }
    image.partition_size = strtoll(response, (char **)NULL, 16);

    generator->generate(&image);
    if (!image.buffer) {
        fprintf(stderr,"Cannot generate image.\n");
        return -1;
    }

    // Following piece of code is similar to fb_queue_flash() but executes
    // actions directly without queuing
    fprintf(stderr, "sending '%s' (%lli KB)...\n", partition, image.image_size/1024);
    status = fb_download_data(usb, image.buffer, image.image_size);
    if (status) goto cleanup;

    fprintf(stderr, "writing '%s'...\n", partition);
    snprintf(cmd, sizeof(cmd), "flash:%s", partition);
    status = fb_command(usb, cmd);
    if (status) goto cleanup;

cleanup:
    generator->cleanup(&image);

    return status;
}
예제 #6
0
파일: vfb.c 프로젝트: bojoer/advancemame
adv_error fb_mode_set(const fb_video_mode* mode)
{
	unsigned req_xres;
	unsigned req_yres;
	unsigned req_bits_per_pixel;

	assert(fb_is_active() && !fb_mode_is_active());

	log_std(("video:fb: fb_mode_set()\n"));

	log_std(("video:fb: get old\n"));

	/* get the current info */
	if (fb_getvar(&fb_state.oldinfo, 0) != 0) {
		error_set("Error getting the variable video mode information.\n");
		goto err;
	}

	fb_log(0, &fb_state.oldinfo);

	fb_preset(&fb_state.varinfo,
		mode->crtc.pixelclock,
		mode->crtc.hde, mode->crtc.hrs, mode->crtc.hre, mode->crtc.ht,
		mode->crtc.vde, mode->crtc.vrs, mode->crtc.vre, mode->crtc.vt,
		crtc_is_doublescan(&mode->crtc), crtc_is_interlace(&mode->crtc), crtc_is_nhsync(&mode->crtc), crtc_is_nvsync(&mode->crtc),
		mode->index, FB_ACTIVATE_NOW
	);

	log_std(("video:fb: set new\n"));

	fb_log(0, &fb_state.varinfo);

	/* save the minimun required data */
	req_xres = fb_state.varinfo.xres;
	req_yres = fb_state.varinfo.yres;
	req_bits_per_pixel = fb_state.varinfo.bits_per_pixel;

	/* set the mode */
	if (fb_setvar(&fb_state.varinfo) != 0) {
		error_set("Error setting the variable video mode information.\n");
		goto err;
	}

	log_std(("video:fb: get new\n"));

	/* get the fixed info */
	if (fb_getfix(&fb_state.fixinfo) != 0) {
		error_set("Error getting the fixed video mode information.\n");
		goto err_restore;
	}

	/* get the variable info */
	if (fb_getvar(&fb_state.varinfo, mode->index) != 0) {
		error_set("Error getting the variable video mode information.\n");
		goto err_restore;
	}

	fb_state.freq = fb_state.varinfo.pixclock;
	fb_state.freq *= fb_state.varinfo.xres + fb_state.varinfo.left_margin + fb_state.varinfo.right_margin + fb_state.varinfo.hsync_len;
	fb_state.freq *= fb_state.varinfo.yres + fb_state.varinfo.upper_margin + fb_state.varinfo.lower_margin + fb_state.varinfo.vsync_len;
	if (fb_state.freq != 0) {
		fb_state.freq = 1000000000000LL / fb_state.freq;
	}

	log_std(("video:fb: frequency %g\n", fb_state.freq));

	fb_log(&fb_state.fixinfo, &fb_state.varinfo);

	/* check the validity of the resulting video mode */
	if (req_xres > fb_state.varinfo.xres
		|| req_yres > fb_state.varinfo.yres
		|| req_bits_per_pixel != fb_state.varinfo.bits_per_pixel
	) {
		log_std(("ERROR:video:fb: request for mode %dx%d %d bits resulted in mode %dx%dx %d bits\n", req_xres, req_yres, req_bits_per_pixel, fb_state.varinfo.xres, fb_state.varinfo.yres, fb_state.varinfo.bits_per_pixel));
		error_set("Error setting the requested video mode.\n");
		goto err_restore;
	}
	if (req_xres != fb_state.varinfo.xres
		|| req_yres != fb_state.varinfo.yres
	) {
		/* allow bigger modes */
		log_std(("WARNING:video:fb: request for mode %dx%d resulted in mode %dx%dx\n", req_xres, req_yres, fb_state.varinfo.xres, fb_state.varinfo.yres));
	}

	if (fb_setup_color() != 0) {
		error_set("Error setting the color information.\n");
		goto err_restore;
	}

	fb_write_line = fb_linear_write_line;

	fb_state.bytes_per_pixel = (fb_state.varinfo.bits_per_pixel + 7) / 8;
	fb_state.bytes_per_scanline = fb_state.fixinfo.line_length;
	fb_state.index = mode->index;

	fb_state.ptr = mmap(0,
		fb_state.fixinfo.smem_len,
		PROT_READ | PROT_WRITE,
		MAP_SHARED,
		fb_state.fd,
		0
	);

	if (fb_state.ptr == MAP_FAILED) {
		error_set("Error mapping the video memory.\n");
		goto err_restore;
	}

	fb_state.wait_last = 0;
	fb_state.wait = fb_wait_detect; /* reset the wait mode */
	fb_state.wait_error = 0;

	fb_state.mode_active = 1;

	return 0;

err_restore:
	fb_setvar(&fb_state.oldinfo); /* ignore error */
err:
	return -1;
}
예제 #7
0
파일: vfb.c 프로젝트: bojoer/advancemame
adv_error fb_init(int device_id, adv_output output, unsigned overlay_size, adv_cursor cursor)
{
	const char* fb;
	char id_buffer[64];
	char* term;

	(void)cursor;
	(void)overlay_size;

	assert(!fb_is_active());

	log_std(("video:fb: fb_init()\n"));

	if (sizeof(fb_video_mode) > MODE_DRIVER_MODE_SIZE_MAX)
		return -1;

	if (os_internal_wm_active()) {
		error_set("Unsupported in X. Try with the SDL library.\n");
		return -1;
	}

	term = getenv("TERM");
	if (!term || strcmp(term, "linux")!=0) {
		error_set("Works only with TERM=linux terminals.\n");
		return -1;
	}

	if (output != adv_output_auto && output != adv_output_fullscreen) {
		error_set("Only fullscreen output is supported.\n");
		return -1;
	}

	fb = getenv("FRAMEBUFFER");
	if (fb && fb[0]) {
		fb_state.fd = open(fb, O_RDWR);
	} else {
		fb = "/dev/fb0";
		fb_state.fd = open(fb, O_RDWR);
		if (fb_state.fd < 0 && errno == ENOENT) {
			fb = "/dev/fb/0";
			fb_state.fd = open(fb, O_RDWR);
		}
	}
	if (fb_state.fd < 0) {
		if (errno == ENODEV) {
			error_set("Video board not supported. Error %d (%s).\n", errno, strerror(errno));
		} else {
			error_set("Error opening the frame buffer %s. Error %d (%s).\n", fb, errno, strerror(errno));
		}
		return -1;
	}

	/* get the fixed info */
	if (fb_getfix(&fb_state.fixinfo) != 0) {
		error_set("Error getting the fixed video mode information.\n");
		goto err_close;
	}

	/* get the variable info */
	if (fb_getvar(&fb_state.varinfo, 0) != 0) {
		error_set("Error getting the variable video mode information.\n");
		goto err_close;
	}

	/* copy the id in a safe way, it may be not 0 terminated */
	sncpyn(id_buffer, sizeof(id_buffer), fb_state.fixinfo.id, sizeof(fb_state.fixinfo.id));

	log_std(("video:fb: id %s\n", id_buffer));

	fb_log(&fb_state.fixinfo, &fb_state.varinfo);

	if (strcmp(id_buffer, "VESA VGA")==0) {
		error_set("The 'vesafb' FrameBuffer driver doesn't allow the creation of new video modes.\n");
		goto err_close;
	}

	fb_state.flags = VIDEO_DRIVER_FLAGS_MODE_PALETTE8 | VIDEO_DRIVER_FLAGS_MODE_BGR15 | VIDEO_DRIVER_FLAGS_MODE_BGR16 | VIDEO_DRIVER_FLAGS_MODE_BGR24 | VIDEO_DRIVER_FLAGS_MODE_BGR32
		| VIDEO_DRIVER_FLAGS_PROGRAMMABLE_ALL
		| VIDEO_DRIVER_FLAGS_OUTPUT_FULLSCREEN;

	if (fb_detect() != 0) {
		goto err_close;
	}

	if ((fb_state.flags & (VIDEO_DRIVER_FLAGS_MODE_PALETTE8 | VIDEO_DRIVER_FLAGS_MODE_BGR15 | VIDEO_DRIVER_FLAGS_MODE_BGR16 | VIDEO_DRIVER_FLAGS_MODE_BGR24 | VIDEO_DRIVER_FLAGS_MODE_BGR32)) == 0) {
		error_set("This '%s' FrameBuffer driver doesn't seem to allow the creation of new video modes.\n", id_buffer);
		goto err_close;
	}

	fb_state.active = 1;

	return 0;

err_close:
	close(fb_state.fd);
	return -1;
}