Commit f7c6b96c authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging



# gpg: Signature made Fri 19 Jan 2018 22:31:27 GMT
# gpg:                using RSA key 0x7DEF8106AAFC390E
# gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>"
# Primary key fingerprint: FAEB 9711 A12C F475 812F  18F2 88A9 064D 1835 61EB
#      Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76  CBD0 7DEF 8106 AAFC 390E

* remotes/jnsnow/tags/ide-pull-request:
  hw/ide: Remove duplicated definitions from ahci_internal.h
  ide: abort TRIM operation for invalid range
  ide: move ide_sect_range_ok() up
  ide: pass IDEState to trim AIO callback

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents b384cd95 3161906d
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -311,8 +311,6 @@ struct AHCIPCIState {
    AHCIState ahci;
};

#define TYPE_ICH9_AHCI "ich9-ahci"

#define ICH_AHCI(obj) \
    OBJECT_CHECK(AHCIPCIState, (obj), TYPE_ICH9_AHCI)

@@ -375,10 +373,8 @@ void ahci_uninit(AHCIState *s);

void ahci_reset(AHCIState *s);

#define TYPE_SYSBUS_AHCI "sysbus-ahci"
#define SYSBUS_AHCI(obj) OBJECT_CHECK(SysbusAHCIState, (obj), TYPE_SYSBUS_AHCI)

#define TYPE_ALLWINNER_AHCI "allwinner-ahci"
#define ALLWINNER_AHCI(obj) OBJECT_CHECK(AllwinnerAHCIState, (obj), \
                       TYPE_ALLWINNER_AHCI)

+33 −20
Original line number Diff line number Diff line
@@ -380,14 +380,27 @@ static void ide_set_signature(IDEState *s)
    }
}

static bool ide_sect_range_ok(IDEState *s,
                              uint64_t sector, uint64_t nb_sectors)
{
    uint64_t total_sectors;

    blk_get_geometry(s->blk, &total_sectors);
    if (sector > total_sectors || nb_sectors > total_sectors - sector) {
        return false;
    }
    return true;
}

typedef struct TrimAIOCB {
    BlockAIOCB common;
    BlockBackend *blk;
    IDEState *s;
    QEMUBH *bh;
    int ret;
    QEMUIOVector *qiov;
    BlockAIOCB *aiocb;
    int i, j;
    bool is_invalid;
} TrimAIOCB;

static void trim_aio_cancel(BlockAIOCB *acb)
@@ -415,8 +428,11 @@ static void ide_trim_bh_cb(void *opaque)
{
    TrimAIOCB *iocb = opaque;

    if (iocb->is_invalid) {
        ide_dma_error(iocb->s);
    } else {
        iocb->common.cb(iocb->common.opaque, iocb->ret);

    }
    qemu_bh_delete(iocb->bh);
    iocb->bh = NULL;
    qemu_aio_unref(iocb);
@@ -425,6 +441,8 @@ static void ide_trim_bh_cb(void *opaque)
static void ide_issue_trim_cb(void *opaque, int ret)
{
    TrimAIOCB *iocb = opaque;
    IDEState *s = iocb->s;

    if (ret >= 0) {
        while (iocb->j < iocb->qiov->niov) {
            int j = iocb->j;
@@ -441,8 +459,13 @@ static void ide_issue_trim_cb(void *opaque, int ret)
                    continue;
                }

                if (!ide_sect_range_ok(s, sector, count)) {
                    iocb->is_invalid = true;
                    goto done;
                }

                /* Got an entry! Submit and exit.  */
                iocb->aiocb = blk_aio_pdiscard(iocb->blk,
                iocb->aiocb = blk_aio_pdiscard(s->blk,
                                               sector << BDRV_SECTOR_BITS,
                                               count << BDRV_SECTOR_BITS,
                                               ide_issue_trim_cb, opaque);
@@ -456,6 +479,7 @@ static void ide_issue_trim_cb(void *opaque, int ret)
        iocb->ret = ret;
    }

done:
    iocb->aiocb = NULL;
    if (iocb->bh) {
        qemu_bh_schedule(iocb->bh);
@@ -466,16 +490,17 @@ BlockAIOCB *ide_issue_trim(
        int64_t offset, QEMUIOVector *qiov,
        BlockCompletionFunc *cb, void *cb_opaque, void *opaque)
{
    BlockBackend *blk = opaque;
    IDEState *s = opaque;
    TrimAIOCB *iocb;

    iocb = blk_aio_get(&trim_aiocb_info, blk, cb, cb_opaque);
    iocb->blk = blk;
    iocb = blk_aio_get(&trim_aiocb_info, s->blk, cb, cb_opaque);
    iocb->s = s;
    iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
    iocb->ret = 0;
    iocb->qiov = qiov;
    iocb->i = -1;
    iocb->j = 0;
    iocb->is_invalid = false;
    ide_issue_trim_cb(iocb, 0);
    return &iocb->common;
}
@@ -601,18 +626,6 @@ static void ide_rw_error(IDEState *s) {
    ide_set_irq(s->bus);
}

static bool ide_sect_range_ok(IDEState *s,
                              uint64_t sector, uint64_t nb_sectors)
{
    uint64_t total_sectors;

    blk_get_geometry(s->blk, &total_sectors);
    if (sector > total_sectors || nb_sectors > total_sectors - sector) {
        return false;
    }
    return true;
}

static void ide_buffered_readv_cb(void *opaque, int ret)
{
    IDEBufferedRequest *req = opaque;
@@ -900,7 +913,7 @@ static void ide_dma_cb(void *opaque, int ret)
    case IDE_DMA_TRIM:
        s->bus->dma->aiocb = dma_blk_io(blk_get_aio_context(s->blk),
                                        &s->sg, offset, BDRV_SECTOR_SIZE,
                                        ide_issue_trim, s->blk, ide_dma_cb, s,
                                        ide_issue_trim, s, ide_dma_cb, s,
                                        DMA_DIRECTION_TO_DEVICE);
        break;
    default:
+0 −6
Original line number Diff line number Diff line
@@ -54,14 +54,10 @@ typedef struct AHCIPCIState AHCIPCIState;

#define TYPE_ICH9_AHCI "ich9-ahci"

#define ICH_AHCI(obj) \
    OBJECT_CHECK(AHCIPCIState, (obj), TYPE_ICH9_AHCI)

int32_t ahci_get_num_ports(PCIDevice *dev);
void ahci_ide_create_devs(PCIDevice *dev, DriveInfo **hd);

#define TYPE_SYSBUS_AHCI "sysbus-ahci"
#define SYSBUS_AHCI(obj) OBJECT_CHECK(SysbusAHCIState, (obj), TYPE_SYSBUS_AHCI)

typedef struct SysbusAHCIState {
    /*< private >*/
@@ -73,8 +69,6 @@ typedef struct SysbusAHCIState {
} SysbusAHCIState;

#define TYPE_ALLWINNER_AHCI "allwinner-ahci"
#define ALLWINNER_AHCI(obj) OBJECT_CHECK(AllwinnerAHCIState, (obj), \
                       TYPE_ALLWINNER_AHCI)

#define ALLWINNER_AHCI_MMIO_OFF  0x80
#define ALLWINNER_AHCI_MMIO_SIZE 0x80