Add a missing wakeup when releasing ownership of the SPI hardware.

Also, validate the chipselect parameter before grabbing ownership of the
hardware, and report timeout errors after releasing it.

PR:		200584
This commit is contained in:
Ian Lepore 2015-06-02 16:07:28 +00:00
parent 92284ce807
commit 148ddb8a6f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=283918

View File

@ -427,6 +427,15 @@ bcm_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
("TX/RX data sizes should be equal"));
/* Get the proper chip select for this child. */
spibus_get_cs(child, &cs);
if (cs < 0 || cs > 2) {
device_printf(dev,
"Invalid chip select %d requested by %s\n", cs,
device_get_nameunit(child));
return (EINVAL);
}
BCM_SPI_LOCK(sc);
/* If the controller is in use wait until it is available. */
@ -441,16 +450,6 @@ bcm_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
SPI_CS_CLEAR_RXFIFO | SPI_CS_CLEAR_TXFIFO,
SPI_CS_CLEAR_RXFIFO | SPI_CS_CLEAR_TXFIFO);
/* Get the proper chip select for this child. */
spibus_get_cs(child, &cs);
if (cs < 0 || cs > 2) {
device_printf(dev,
"Invalid chip select %d requested by %s\n", cs,
device_get_nameunit(child));
BCM_SPI_UNLOCK(sc);
return (EINVAL);
}
/* Save a pointer to the SPI command. */
sc->sc_cmd = cmd;
sc->sc_read = 0;
@ -471,8 +470,10 @@ bcm_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
/* Make sure the SPI engine and interrupts are disabled. */
bcm_spi_modifyreg(sc, SPI_CS, SPI_CS_TA | SPI_CS_INTR | SPI_CS_INTD, 0);
/* Clear the controller flags. */
/* Release the controller and wakeup the next thread waiting for it. */
sc->sc_flags = 0;
wakeup_one(dev);
BCM_SPI_UNLOCK(sc);
/*
* Check for transfer timeout. The SPI controller doesn't
@ -483,8 +484,6 @@ bcm_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
err = EIO;
}
BCM_SPI_UNLOCK(sc);
return (err);
}