Check for command errors and clear the error status if an error is found.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/hw/sdcard.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/hw/sdcard.c b/src/hw/sdcard.c index 5f9ce4a..1f26291 100644 --- a/src/hw/sdcard.c +++ b/src/hw/sdcard.c @@ -79,6 +79,7 @@ struct sdhci_s { #define SI_TRANS_DONE (1<<1) #define SI_WRITE_READY (1<<4) #define SI_READ_READY (1<<5) +#define SI_ERROR (1<<15)
// SDHCI present_state flags #define SP_CMD_INHIBIT (1<<0) @@ -186,9 +187,16 @@ sdcard_pio(struct sdhci_s *regs, int cmd, u32 *param) // Send command writel(®s->arg, *param); writew(®s->cmd, cmd); - int ret = sdcard_waitw(®s->irq_status, SI_CMD_COMPLETE); + int ret = sdcard_waitw(®s->irq_status, SI_ERROR|SI_CMD_COMPLETE); if (ret < 0) return ret; + if (ret & SI_ERROR) { + u16 err = readw(®s->error_irq_status); + dprintf(3, "sdcard_pio command stop (code=%x)\n", err); + sdcard_reset(regs, SRF_CMD|SRF_DATA); + writew(®s->error_irq_status, err); + return -1; + } writew(®s->irq_status, SI_CMD_COMPLETE); // Read response memcpy(param, regs->response, sizeof(regs->response)); @@ -424,8 +432,11 @@ sdcard_controller_setup(void *data) , readl(®s->cap_lo), readl(®s->cap_hi)); sdcard_reset(regs, SRF_ALL); writew(®s->irq_signal, 0); - writew(®s->irq_enable, 0xffff); + writew(®s->irq_enable, 0x01ff); + writew(®s->irq_status, readw(®s->irq_status)); writew(®s->error_signal, 0); + writew(®s->error_irq_enable, 0x03ff); + writew(®s->error_irq_status, readw(®s->error_irq_status)); writeb(®s->timeout_control, 0x0e); // Set to max timeout int volt = sdcard_set_power(regs); if (volt < 0)