/*
 * Hard disk geometry utilities
 *
 * Copyright (C) 2012 Red Hat, Inc.
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 * This file incorporates work covered by the following copyright and
 * permission notice:
 *
 * Copyright (c) 2003 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "sysemu/block-backend.h"
#include "qapi/qapi-types-block.h"
#include "qemu/bswap.h"
#include "hw/block/block.h"
#include "trace.h"

struct partition {
        uint8_t boot_ind;           /* 0x80 - active */
        uint8_t head;               /* starting head */
        uint8_t sector;             /* starting sector */
        uint8_t cyl;                /* starting cylinder */
        uint8_t sys_ind;            /* What partition type */
        uint8_t end_head;           /* end head */
        uint8_t end_sector;         /* end sector */
        uint8_t end_cyl;            /* end cylinder */
        uint32_t start_sect;        /* starting sector counting from 0 */
        uint32_t nr_sects;          /* nr of sectors in partition */
} QEMU_PACKED;

/* try to guess the disk logical geometry from the MSDOS partition table.
   Return 0 if OK, -1 if could not guess */
static int guess_disk_lchs(BlockBackend *blk,
                           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;

    blk_get_geometry(blk, &nb_sectors);

    if (blk_pread(blk, 0, buf, BDRV_SECTOR_SIZE) < 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(blk, cylinders, heads, sectors);
            return 0;
        }
    }
    return -1;
}

static void guess_chs_for_size(BlockBackend *blk,
                uint32_t *pcyls, uint32_t *pheads, uint32_t *psecs)
{
    uint64_t nb_sectors;
    int cylinders;

    blk_get_geometry(blk, &nb_sectors);

    cylinders = nb_sectors / (16 * 63);
    if (cylinders > 16383) {
        cylinders = 16383;
    } else if (cylinders < 2) {
        cylinders = 2;
    }
    *pcyls = cylinders;
    *pheads = 16;
    *psecs = 63;
}

void hd_geometry_guess(BlockBackend *blk,
                       uint32_t *pcyls, uint32_t *pheads, uint32_t *psecs,
                       int *ptrans)
{
    int cylinders, heads, secs, translation;
    HDGeometry geo;

    /* Try to probe the backing device geometry, otherwise fallback
       to the old logic. (as of 12/2014 probing only succeeds on DASDs) */
    if (blk_probe_geometry(blk, &geo) == 0) {
        *pcyls = geo.cylinders;
        *psecs = geo.sectors;
        *pheads = geo.heads;
        translation = BIOS_ATA_TRANSLATION_NONE;
    } else if (guess_disk_lchs(blk, &cylinders, &heads, &secs) < 0) {
        /* no LCHS guess: use a standard physical disk geometry  */
        guess_chs_for_size(blk, pcyls, pheads, psecs);
        translation = hd_bios_chs_auto_trans(*pcyls, *pheads, *psecs);
    } else if (heads > 16) {
        /* LCHS guess with heads > 16 means that a BIOS LBA
           translation was active, so a standard physical disk
           geometry is OK */
        guess_chs_for_size(blk, pcyls, pheads, psecs);
        translation = *pcyls * *pheads <= 131072
            ? BIOS_ATA_TRANSLATION_LARGE
            : BIOS_ATA_TRANSLATION_LBA;
    } else {
        /* LCHS guess with heads <= 16: use as physical geometry */
        *pcyls = cylinders;
        *pheads = heads;
        *psecs = secs;
        /* disable any translation to be in sync with
           the logical geometry */
        translation = BIOS_ATA_TRANSLATION_NONE;
    }
    if (ptrans) {
        *ptrans = translation;
    }
    trace_hd_geometry_guess(blk, *pcyls, *pheads, *psecs, translation);
}

int hd_bios_chs_auto_trans(uint32_t cyls, uint32_t heads, uint32_t secs)
{
    return cyls <= 1024 && heads <= 16 && secs <= 63
        ? BIOS_ATA_TRANSLATION_NONE
        : BIOS_ATA_TRANSLATION_LBA;
}
