static int guess_disk_lchs(BlockDriverState *bs,

                           int *pcylinders, int *pheads, int *psectors)

{

    uint8_t buf[BDRV_SECTOR_SIZE];

    int i, heads, sectors, cylinders;

    struct partition *p;

    uint32_t nr_sects;

    uint64_t nb_sectors;



    bdrv_get_geometry(bs, &nb_sectors);



    /**

     * The function will be invoked during startup not only in sync I/O mode,

     * but also in async I/O mode. So the I/O throttling function has to

     * be disabled temporarily here, not permanently.

     */

    if (bdrv_read_unthrottled(bs, 0, buf, 1) < 0) {

        return -1;

    }

    /* test msdos magic */

    if (buf[510] != 0x55 || buf[511] != 0xaa) {

        return -1;

    }

    for (i = 0; i < 4; i++) {

        p = ((struct partition *)(buf + 0x1be)) + i;

        nr_sects = le32_to_cpu(p->nr_sects);

        if (nr_sects && p->end_head) {

            /* We make the assumption that the partition terminates on

               a cylinder boundary */

            heads = p->end_head + 1;

            sectors = p->end_sector & 63;

            if (sectors == 0) {

                continue;

            }

            cylinders = nb_sectors / (heads * sectors);

            if (cylinders < 1 || cylinders > 16383) {

                continue;

            }

            *pheads = heads;

            *psectors = sectors;

            *pcylinders = cylinders;

            trace_hd_geometry_lchs_guess(bs, cylinders, heads, sectors);

            return 0;

        }

    }

    return -1;

}

static int guess_disk_lchs(BlockDriverState *bs,

                           int *pcylinders, int *pheads, int *psectors)

{

    uint8_t buf[BDRV_SECTOR_SIZE];

    int i, heads, sectors, cylinders;

    struct partition *p;

    uint32_t nr_sects;

    uint64_t nb_sectors;



    bdrv_get_geometry(bs, &nb_sectors);



    









    if (bdrv_read_unthrottled(bs, 0, buf, 1) < 0) {

        return -1;

    }

    

    if (buf[510] != 0x55 || buf[511] != 0xaa) {

        return -1;

    }

    for (i = 0; i < 4; i++) {

        p = ((struct partition *)(buf + 0x1be)) + i;

        nr_sects = le32_to_cpu(p->nr_sects);

        if (nr_sects && p->end_head) {

            



            heads = p->end_head + 1;

            sectors = p->end_sector & 63;

            if (sectors == 0) {

                continue;

            }

            cylinders = nb_sectors / (heads * sectors);

            if (cylinders < 1 || cylinders > 16383) {

                continue;

            }

            *pheads = heads;

            *psectors = sectors;

            *pcylinders = cylinders;

            trace_hd_geometry_lchs_guess(bs, cylinders, heads, sectors);

            return 0;

        }

    }

    return -1;

}

static int FUNC_0(BlockDriverState *VAR_0,

                           int *VAR_1, int *VAR_2, int *VAR_3)

{

    uint8_t buf[BDRV_SECTOR_SIZE];

    int VAR_4, VAR_5, VAR_6, VAR_7;

    struct partition *VAR_8;

    uint32_t nr_sects;

    uint64_t nb_sectors;



    bdrv_get_geometry(VAR_0, &nb_sectors);



    









    if (bdrv_read_unthrottled(VAR_0, 0, buf, 1) < 0) {

        return -1;

    }

    

    if (buf[510] != 0x55 || buf[511] != 0xaa) {

        return -1;

    }

    for (VAR_4 = 0; VAR_4 < 4; VAR_4++) {

        VAR_8 = ((struct partition *)(buf + 0x1be)) + VAR_4;

        nr_sects = le32_to_cpu(VAR_8->nr_sects);

        if (nr_sects && VAR_8->end_head) {

            



            VAR_5 = VAR_8->end_head + 1;

            VAR_6 = VAR_8->end_sector & 63;

            if (VAR_6 == 0) {

                continue;

            }

            VAR_7 = nb_sectors / (VAR_5 * VAR_6);

            if (VAR_7 < 1 || VAR_7 > 16383) {

                continue;

            }

            *VAR_2 = VAR_5;

            *VAR_3 = VAR_6;

            *VAR_1 = VAR_7;

            trace_hd_geometry_lchs_guess(VAR_0, VAR_7, VAR_5, VAR_6);

            return 0;

        }

    }

    return -1;

}

static int FUNC_0(BlockDriverState *VAR_0,
int *VAR_1, int *VAR_2, int *VAR_3)
{ uint8_t buf[BDRV_SECTOR_SIZE]; int VAR_4, VAR_5, VAR_6, VAR_7; struct partition *VAR_8; uint32_t nr_sects; uint64_t nb_sectors; bdrv_get_geometry(VAR_0, &nb_sectors); if (bdrv_read_unthrottled(VAR_0, 0, buf, 1) < 0) { return -1; } if (buf[510] != 0x55 || buf[511] != 0xaa) { return -1; } for (VAR_4 = 0; VAR_4 < 4; VAR_4++) { VAR_8 = ((struct partition *)(buf + 0x1be)) + VAR_4; nr_sects = le32_to_cpu(VAR_8->nr_sects); if (nr_sects && VAR_8->end_head) { VAR_5 = VAR_8->end_head + 1; VAR_6 = VAR_8->end_sector & 63; if (VAR_6 == 0) { continue; } VAR_7 = nb_sectors / (VAR_5 * VAR_6); if (VAR_7 < 1 || VAR_7 > 16383) { continue; } *VAR_2 = VAR_5; *VAR_3 = VAR_6; *VAR_1 = VAR_7; trace_hd_geometry_lchs_guess(VAR_0, VAR_7, VAR_5, VAR_6); return 0; } } return -1; }