sdhci: Remove class "virtual" methods

The SDHCIClass defines a series of class "methods".  However, no code
in the QEMU tree overrides these methods or even uses them outside of
sdhci.c.

Remove the virtual methods and replace them with direct calls to the
underlying functions.  This simplifies the process of extending the
sdhci code to support PCI devices (which have a different parent
class).

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Kevin O'Connor 2014-12-08 18:10:30 -05:00 committed by Paolo Bonzini
parent c7ff8daacf
commit d368ba4376
2 changed files with 40 additions and 106 deletions

View File

@ -198,12 +198,7 @@ static void sdhci_reset(SDHCIState *s)
s->stopped_state = sdhc_not_stopped;
}
static void sdhci_do_data_transfer(void *opaque)
{
SDHCIState *s = (SDHCIState *)opaque;
SDHCI_GET_CLASS(s)->data_transfer(s);
}
static void sdhci_data_transfer(void *opaque);
static void sdhci_send_command(SDHCIState *s)
{
@ -261,7 +256,7 @@ static void sdhci_send_command(SDHCIState *s)
if (s->blksize && (s->cmdreg & SDHC_CMD_DATA_PRESENT)) {
s->data_count = 0;
sdhci_do_data_transfer(s);
sdhci_data_transfer(s);
}
}
@ -367,9 +362,9 @@ static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned size)
/* stop at gap request */
(s->stopped_state == sdhc_gap_read &&
!(s->prnsts & SDHC_DAT_LINE_ACTIVE))) {
SDHCI_GET_CLASS(s)->end_data_transfer(s);
sdhci_end_transfer(s);
} else { /* if there are more data, read next block from card */
SDHCI_GET_CLASS(s)->read_block_from_card(s);
sdhci_read_block_from_card(s);
}
break;
}
@ -410,7 +405,7 @@ static void sdhci_write_block_to_card(SDHCIState *s)
if ((s->trnmod & SDHC_TRNS_MULTI) == 0 ||
((s->trnmod & SDHC_TRNS_MULTI) &&
(s->trnmod & SDHC_TRNS_BLK_CNT_EN) && (s->blkcnt == 0))) {
SDHCI_GET_CLASS(s)->end_data_transfer(s);
sdhci_end_transfer(s);
} else if (s->norintstsen & SDHC_NISEN_WBUFRDY) {
s->norintsts |= SDHC_NIS_WBUFRDY;
}
@ -422,7 +417,7 @@ static void sdhci_write_block_to_card(SDHCIState *s)
if (s->norintstsen & SDHC_EISEN_BLKGAP) {
s->norintsts |= SDHC_EIS_BLKGAP;
}
SDHCI_GET_CLASS(s)->end_data_transfer(s);
sdhci_end_transfer(s);
}
sdhci_update_irq(s);
@ -450,7 +445,7 @@ static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size)
s->data_count = 0;
s->prnsts &= ~SDHC_SPACE_AVAILABLE;
if (s->prnsts & SDHC_DOING_WRITE) {
SDHCI_GET_CLASS(s)->write_block_to_card(s);
sdhci_write_block_to_card(s);
}
}
}
@ -537,7 +532,7 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
}
if (s->blkcnt == 0) {
SDHCI_GET_CLASS(s)->end_data_transfer(s);
sdhci_end_transfer(s);
} else {
if (s->norintstsen & SDHC_NISEN_DMA) {
s->norintsts |= SDHC_NIS_DMA;
@ -571,7 +566,7 @@ static void sdhci_sdma_transfer_single_block(SDHCIState *s)
s->blkcnt--;
}
SDHCI_GET_CLASS(s)->end_data_transfer(s);
sdhci_end_transfer(s);
}
typedef struct ADMADescr {
@ -758,7 +753,7 @@ static void sdhci_do_adma(SDHCIState *s)
sdhci_update_irq(s);
}
SDHCI_GET_CLASS(s)->end_data_transfer(s);
sdhci_end_transfer(s);
return;
}
@ -771,9 +766,9 @@ static void sdhci_do_adma(SDHCIState *s)
/* Perform data transfer according to controller configuration */
static void sdhci_data_transfer(SDHCIState *s)
static void sdhci_data_transfer(void *opaque)
{
SDHCIClass *k = SDHCI_GET_CLASS(s);
SDHCIState *s = (SDHCIState *)opaque;
if (s->trnmod & SDHC_TRNS_DMA) {
switch (SDHC_DMA_TYPE(s->hostctl)) {
@ -784,9 +779,9 @@ static void sdhci_data_transfer(SDHCIState *s)
}
if ((s->blkcnt == 1) || !(s->trnmod & SDHC_TRNS_MULTI)) {
k->do_sdma_single(s);
sdhci_sdma_transfer_single_block(s);
} else {
k->do_sdma_multi(s);
sdhci_sdma_transfer_multi_blocks(s);
}
break;
@ -796,7 +791,7 @@ static void sdhci_data_transfer(SDHCIState *s)
break;
}
k->do_adma(s);
sdhci_do_adma(s);
break;
case SDHC_CTRL_ADMA2_32:
if (!(s->capareg & SDHC_CAN_DO_ADMA2)) {
@ -804,7 +799,7 @@ static void sdhci_data_transfer(SDHCIState *s)
break;
}
k->do_adma(s);
sdhci_do_adma(s);
break;
case SDHC_CTRL_ADMA2_64:
if (!(s->capareg & SDHC_CAN_DO_ADMA2) ||
@ -813,7 +808,7 @@ static void sdhci_data_transfer(SDHCIState *s)
break;
}
k->do_adma(s);
sdhci_do_adma(s);
break;
default:
ERRPRINT("Unsupported DMA type\n");
@ -823,11 +818,11 @@ static void sdhci_data_transfer(SDHCIState *s)
if ((s->trnmod & SDHC_TRNS_READ) && sd_data_ready(s->card)) {
s->prnsts |= SDHC_DOING_READ | SDHC_DATA_INHIBIT |
SDHC_DAT_LINE_ACTIVE;
SDHCI_GET_CLASS(s)->read_block_from_card(s);
sdhci_read_block_from_card(s);
} else {
s->prnsts |= SDHC_DOING_WRITE | SDHC_DAT_LINE_ACTIVE |
SDHC_SPACE_AVAILABLE | SDHC_DATA_INHIBIT;
SDHCI_GET_CLASS(s)->write_block_to_card(s);
sdhci_write_block_to_card(s);
}
}
}
@ -858,8 +853,9 @@ sdhci_buff_access_is_sequential(SDHCIState *s, unsigned byte_num)
return true;
}
static uint32_t sdhci_read(SDHCIState *s, unsigned int offset, unsigned size)
static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
{
SDHCIState *s = (SDHCIState *)opaque;
uint32_t ret = 0;
switch (offset & ~0x3) {
@ -880,8 +876,8 @@ static uint32_t sdhci_read(SDHCIState *s, unsigned int offset, unsigned size)
break;
case SDHC_BDATA:
if (sdhci_buff_access_is_sequential(s, offset - SDHC_BDATA)) {
ret = SDHCI_GET_CLASS(s)->bdata_read(s, size);
DPRINT_L2("read %ub: addr[0x%04x] -> %u(0x%x)\n", size, offset,
ret = sdhci_read_dataport(s, size);
DPRINT_L2("read %ub: addr[0x%04x] -> %u(0x%x)\n", size, (int)offset,
ret, ret);
return ret;
}
@ -927,13 +923,13 @@ static uint32_t sdhci_read(SDHCIState *s, unsigned int offset, unsigned size)
ret = (SD_HOST_SPECv2_VERS << 16) | sdhci_slotint(s);
break;
default:
ERRPRINT("bad %ub read: addr[0x%04x]\n", size, offset);
ERRPRINT("bad %ub read: addr[0x%04x]\n", size, (int)offset);
break;
}
ret >>= (offset & 0x3) * 8;
ret &= (1ULL << (size * 8)) - 1;
DPRINT_L2("read %ub: addr[0x%04x] -> %u(0x%x)\n", size, offset, ret, ret);
DPRINT_L2("read %ub: addr[0x%04x] -> %u(0x%x)\n", size, (int)offset, ret, ret);
return ret;
}
@ -948,10 +944,10 @@ static inline void sdhci_blkgap_write(SDHCIState *s, uint8_t value)
(s->blkgap & SDHC_STOP_AT_GAP_REQ) == 0) {
if (s->stopped_state == sdhc_gap_read) {
s->prnsts |= SDHC_DAT_LINE_ACTIVE | SDHC_DOING_READ;
SDHCI_GET_CLASS(s)->read_block_from_card(s);
sdhci_read_block_from_card(s);
} else {
s->prnsts |= SDHC_DAT_LINE_ACTIVE | SDHC_DOING_WRITE;
SDHCI_GET_CLASS(s)->write_block_to_card(s);
sdhci_write_block_to_card(s);
}
s->stopped_state = sdhc_not_stopped;
} else if (!s->stopped_state && (value & SDHC_STOP_AT_GAP_REQ)) {
@ -967,7 +963,7 @@ static inline void sdhci_reset_write(SDHCIState *s, uint8_t value)
{
switch (value) {
case SDHC_RESET_ALL:
DEVICE_GET_CLASS(s)->reset(DEVICE(s));
sdhci_reset(s);
break;
case SDHC_RESET_CMD:
s->prnsts &= ~SDHC_CMD_INHIBIT;
@ -987,10 +983,12 @@ static inline void sdhci_reset_write(SDHCIState *s, uint8_t value)
}
static void
sdhci_write(SDHCIState *s, unsigned int offset, uint32_t value, unsigned size)
sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
{
SDHCIState *s = (SDHCIState *)opaque;
unsigned shift = 8 * (offset & 0x3);
uint32_t mask = ~(((1ULL << (size * 8)) - 1) << shift);
uint32_t value = val;
value <<= shift;
switch (offset & ~0x3) {
@ -1000,7 +998,7 @@ sdhci_write(SDHCIState *s, unsigned int offset, uint32_t value, unsigned size)
/* Writing to last byte of sdmasysad might trigger transfer */
if (!(mask & 0xFF000000) && TRANSFERRING_DATA(s->prnsts) && s->blkcnt &&
s->blksize && SDHC_DMA_TYPE(s->hostctl) == SDHC_CTRL_SDMA) {
SDHCI_GET_CLASS(s)->do_sdma_multi(s);
sdhci_sdma_transfer_multi_blocks(s);
}
break;
case SDHC_BLKSIZE:
@ -1022,15 +1020,15 @@ sdhci_write(SDHCIState *s, unsigned int offset, uint32_t value, unsigned size)
MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16);
/* Writing to the upper byte of CMDREG triggers SD command generation */
if ((mask & 0xFF000000) || !SDHCI_GET_CLASS(s)->can_issue_command(s)) {
if ((mask & 0xFF000000) || !sdhci_can_issue_command(s)) {
break;
}
SDHCI_GET_CLASS(s)->send_command(s);
sdhci_send_command(s);
break;
case SDHC_BDATA:
if (sdhci_buff_access_is_sequential(s, offset - SDHC_BDATA)) {
SDHCI_GET_CLASS(s)->bdata_write(s, value >> shift, size);
sdhci_write_dataport(s, value >> shift, size);
}
break;
case SDHC_HOSTCTL:
@ -1111,32 +1109,16 @@ sdhci_write(SDHCIState *s, unsigned int offset, uint32_t value, unsigned size)
break;
default:
ERRPRINT("bad %ub write offset: addr[0x%04x] <- %u(0x%x)\n",
size, offset, value >> shift, value >> shift);
size, (int)offset, value >> shift, value >> shift);
break;
}
DPRINT_L2("write %ub: addr[0x%04x] <- %u(0x%x)\n",
size, offset, value >> shift, value >> shift);
}
static uint64_t
sdhci_readfn(void *opaque, hwaddr offset, unsigned size)
{
SDHCIState *s = (SDHCIState *)opaque;
return SDHCI_GET_CLASS(s)->mem_read(s, offset, size);
}
static void
sdhci_writefn(void *opaque, hwaddr off, uint64_t val, unsigned sz)
{
SDHCIState *s = (SDHCIState *)opaque;
SDHCI_GET_CLASS(s)->mem_write(s, off, val, sz);
size, (int)offset, value >> shift, value >> shift);
}
static const MemoryRegionOps sdhci_mmio_ops = {
.read = sdhci_readfn,
.write = sdhci_writefn,
.read = sdhci_read,
.write = sdhci_write,
.valid = {
.min_access_size = 1,
.max_access_size = 4,
@ -1175,7 +1157,7 @@ static void sdhci_initfn(Object *obj)
sd_set_cb(s->card, s->ro_cb, s->eject_cb);
s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s);
s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_do_data_transfer, s);
s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s);
}
static void sdhci_uninitfn(Object *obj)
@ -1254,36 +1236,13 @@ static void sdhci_realize(DeviceState *dev, Error ** errp)
sysbus_init_mmio(sbd, &s->iomem);
}
static void sdhci_generic_reset(DeviceState *ds)
{
SDHCIState *s = SDHCI(ds);
SDHCI_GET_CLASS(s)->reset(s);
}
static void sdhci_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SDHCIClass *k = SDHCI_CLASS(klass);
dc->vmsd = &sdhci_vmstate;
dc->props = sdhci_properties;
dc->reset = sdhci_generic_reset;
dc->realize = sdhci_realize;
k->reset = sdhci_reset;
k->mem_read = sdhci_read;
k->mem_write = sdhci_write;
k->send_command = sdhci_send_command;
k->can_issue_command = sdhci_can_issue_command;
k->data_transfer = sdhci_data_transfer;
k->end_data_transfer = sdhci_end_transfer;
k->do_sdma_single = sdhci_sdma_transfer_single_block;
k->do_sdma_multi = sdhci_sdma_transfer_multi_blocks;
k->do_adma = sdhci_do_adma;
k->read_block_from_card = sdhci_read_block_from_card;
k->write_block_to_card = sdhci_write_block_to_card;
k->bdata_read = sdhci_read_dataport;
k->bdata_write = sdhci_write_dataport;
}
static const TypeInfo sdhci_type_info = {
@ -1293,7 +1252,6 @@ static const TypeInfo sdhci_type_info = {
.instance_init = sdhci_initfn,
.instance_finalize = sdhci_uninitfn,
.class_init = sdhci_class_init,
.class_size = sizeof(SDHCIClass)
};
static void sdhci_register_types(void)

View File

@ -279,34 +279,10 @@ typedef struct SDHCIState {
/* RO Host Controller Version Register always reads as 0x2401 */
} SDHCIState;
typedef struct SDHCIClass {
SysBusDeviceClass busdev_class;
void (*reset)(SDHCIState *s);
uint32_t (*mem_read)(SDHCIState *s, unsigned int offset, unsigned size);
void (*mem_write)(SDHCIState *s, unsigned int offset, uint32_t value,
unsigned size);
void (*send_command)(SDHCIState *s);
bool (*can_issue_command)(SDHCIState *s);
void (*data_transfer)(SDHCIState *s);
void (*end_data_transfer)(SDHCIState *s);
void (*do_sdma_single)(SDHCIState *s);
void (*do_sdma_multi)(SDHCIState *s);
void (*do_adma)(SDHCIState *s);
void (*read_block_from_card)(SDHCIState *s);
void (*write_block_to_card)(SDHCIState *s);
uint32_t (*bdata_read)(SDHCIState *s, unsigned size);
void (*bdata_write)(SDHCIState *s, uint32_t value, unsigned size);
} SDHCIClass;
extern const VMStateDescription sdhci_vmstate;
#define TYPE_SDHCI "generic-sdhci"
#define SDHCI(obj) \
OBJECT_CHECK(SDHCIState, (obj), TYPE_SDHCI)
#define SDHCI_CLASS(klass) \
OBJECT_CLASS_CHECK(SDHCIClass, (klass), TYPE_SDHCI)
#define SDHCI_GET_CLASS(obj) \
OBJECT_GET_CLASS(SDHCIClass, (obj), TYPE_SDHCI)
#endif /* SDHCI_H */