mirror of
https://github.com/qemu/qemu.git
synced 2025-07-28 22:23:42 +00:00

The I2C block read function of pm_smbus was completely broken. It required doing some direct I2C handling because it didn't have a defined size, the OS code just reads bytes until it marks the transaction finished. This also required adjusting how the AMIBIOS workaround code worked, the I2C block mode was setting STS_HOST_BUSY during a transaction, so that bit could no longer be used to inform the host status read code to start the transaction. Create a explicit bool for that operation. Also, don't read the next byte from the device in byte-by-byte mode unless the OS is actually clearing the byte done bit. Just assuming that's what the OS is doing is a bad idea. Signed-off-by: Corey Minyard <cminyard@mvista.com>
47 lines
1.1 KiB
C
47 lines
1.1 KiB
C
#ifndef PM_SMBUS_H
|
|
#define PM_SMBUS_H
|
|
|
|
#include "hw/i2c/smbus_master.h"
|
|
|
|
#define PM_SMBUS_MAX_MSG_SIZE 32
|
|
|
|
typedef struct PMSMBus {
|
|
I2CBus *smbus;
|
|
MemoryRegion io;
|
|
|
|
uint8_t smb_stat;
|
|
uint8_t smb_ctl;
|
|
uint8_t smb_cmd;
|
|
uint8_t smb_addr;
|
|
uint8_t smb_data0;
|
|
uint8_t smb_data1;
|
|
uint8_t smb_data[PM_SMBUS_MAX_MSG_SIZE];
|
|
uint8_t smb_blkdata;
|
|
uint8_t smb_auxctl;
|
|
uint32_t smb_index;
|
|
|
|
/* Set by pm_smbus.c */
|
|
void (*reset)(struct PMSMBus *s);
|
|
|
|
/* Set by the user. */
|
|
bool i2c_enable;
|
|
void (*set_irq)(struct PMSMBus *s, bool enabled);
|
|
void *opaque;
|
|
|
|
/* Internally used by pm_smbus. */
|
|
|
|
/* Set on block transfers after the last byte has been read, so the
|
|
INTR bit can be set at the right time. */
|
|
bool op_done;
|
|
|
|
/* Set during an I2C block read, so we know how to handle data. */
|
|
bool in_i2c_block_read;
|
|
|
|
/* Used to work around a bug in AMIBIOS, see smb_transaction_start() */
|
|
bool start_transaction_on_status_read;
|
|
} PMSMBus;
|
|
|
|
void pm_smbus_init(DeviceState *parent, PMSMBus *smb, bool force_aux_blk);
|
|
|
|
#endif /* PM_SMBUS_H */
|