Merge pull request #2919 from embassy-rs/fix-peripheralref-deref
Fix PeripheralRef soundness issue allowing &T.
This commit is contained in:
commit
1166bcd799
2 changed files with 23 additions and 14 deletions
|
@ -1,5 +1,5 @@
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::ops::Deref;
|
use core::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
/// An exclusive reference to a peripheral.
|
/// An exclusive reference to a peripheral.
|
||||||
///
|
///
|
||||||
|
@ -155,7 +155,7 @@ pub trait Peripheral: Sized {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, T: Deref> Peripheral for T
|
impl<'b, T: DerefMut> Peripheral for T
|
||||||
where
|
where
|
||||||
T::Target: Peripheral,
|
T::Target: Peripheral,
|
||||||
{
|
{
|
||||||
|
@ -163,6 +163,15 @@ where
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn clone_unchecked(&self) -> Self::P {
|
unsafe fn clone_unchecked(&self) -> Self::P {
|
||||||
self.deref().clone_unchecked()
|
T::Target::clone_unchecked(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b, T: Peripheral> Peripheral for PeripheralRef<'_, T> {
|
||||||
|
type P = T::P;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn clone_unchecked(&self) -> Self::P {
|
||||||
|
T::clone_unchecked(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -338,7 +338,7 @@ impl<'d, T: Instance> PdPhy<'d, T> {
|
||||||
|
|
||||||
let dma = unsafe {
|
let dma = unsafe {
|
||||||
Transfer::new_read(
|
Transfer::new_read(
|
||||||
&self.rx_dma_ch,
|
&mut self.rx_dma_ch,
|
||||||
self.rx_dma_req,
|
self.rx_dma_req,
|
||||||
r.rxdr().as_ptr() as *mut u8,
|
r.rxdr().as_ptr() as *mut u8,
|
||||||
buf,
|
buf,
|
||||||
|
@ -356,7 +356,7 @@ impl<'d, T: Instance> PdPhy<'d, T> {
|
||||||
r.cr().modify(|w| w.set_phyrxen(true));
|
r.cr().modify(|w| w.set_phyrxen(true));
|
||||||
let _on_drop = OnDrop::new(|| {
|
let _on_drop = OnDrop::new(|| {
|
||||||
r.cr().modify(|w| w.set_phyrxen(false));
|
r.cr().modify(|w| w.set_phyrxen(false));
|
||||||
self.enable_rx_interrupt(false);
|
Self::enable_rx_interrupt(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
|
@ -377,7 +377,7 @@ impl<'d, T: Instance> PdPhy<'d, T> {
|
||||||
Poll::Ready(ret)
|
Poll::Ready(ret)
|
||||||
} else {
|
} else {
|
||||||
T::state().waker.register(cx.waker());
|
T::state().waker.register(cx.waker());
|
||||||
self.enable_rx_interrupt(true);
|
Self::enable_rx_interrupt(true);
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -393,7 +393,7 @@ impl<'d, T: Instance> PdPhy<'d, T> {
|
||||||
Ok(r.rx_payszr().read().rxpaysz().into())
|
Ok(r.rx_payszr().read().rxpaysz().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enable_rx_interrupt(&self, enable: bool) {
|
fn enable_rx_interrupt(enable: bool) {
|
||||||
T::REGS.imr().modify(|w| w.set_rxmsgendie(enable));
|
T::REGS.imr().modify(|w| w.set_rxmsgendie(enable));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,7 +405,7 @@ impl<'d, T: Instance> PdPhy<'d, T> {
|
||||||
// might still be running because there is no way to abort an ongoing
|
// might still be running because there is no way to abort an ongoing
|
||||||
// message transmission. Wait for it to finish but ignore errors.
|
// message transmission. Wait for it to finish but ignore errors.
|
||||||
if r.cr().read().txsend() {
|
if r.cr().read().txsend() {
|
||||||
if let Err(TxError::HardReset) = self.wait_tx_done().await {
|
if let Err(TxError::HardReset) = Self::wait_tx_done().await {
|
||||||
return Err(TxError::HardReset);
|
return Err(TxError::HardReset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -419,7 +419,7 @@ impl<'d, T: Instance> PdPhy<'d, T> {
|
||||||
// Start the DMA and let it do its thing in the background.
|
// Start the DMA and let it do its thing in the background.
|
||||||
let _dma = unsafe {
|
let _dma = unsafe {
|
||||||
Transfer::new_write(
|
Transfer::new_write(
|
||||||
&self.tx_dma_ch,
|
&mut self.tx_dma_ch,
|
||||||
self.tx_dma_req,
|
self.tx_dma_req,
|
||||||
buf,
|
buf,
|
||||||
r.txdr().as_ptr() as *mut u8,
|
r.txdr().as_ptr() as *mut u8,
|
||||||
|
@ -434,11 +434,11 @@ impl<'d, T: Instance> PdPhy<'d, T> {
|
||||||
w.set_txsend(true);
|
w.set_txsend(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.wait_tx_done().await
|
Self::wait_tx_done().await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_tx_done(&self) -> Result<(), TxError> {
|
async fn wait_tx_done() -> Result<(), TxError> {
|
||||||
let _on_drop = OnDrop::new(|| self.enable_tx_interrupts(false));
|
let _on_drop = OnDrop::new(|| Self::enable_tx_interrupts(false));
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
let r = T::REGS;
|
let r = T::REGS;
|
||||||
let sr = r.sr().read();
|
let sr = r.sr().read();
|
||||||
|
@ -453,14 +453,14 @@ impl<'d, T: Instance> PdPhy<'d, T> {
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
} else {
|
} else {
|
||||||
T::state().waker.register(cx.waker());
|
T::state().waker.register(cx.waker());
|
||||||
self.enable_tx_interrupts(true);
|
Self::enable_tx_interrupts(true);
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enable_tx_interrupts(&self, enable: bool) {
|
fn enable_tx_interrupts(enable: bool) {
|
||||||
T::REGS.imr().modify(|w| {
|
T::REGS.imr().modify(|w| {
|
||||||
w.set_txmsgdiscie(enable);
|
w.set_txmsgdiscie(enable);
|
||||||
w.set_txmsgsentie(enable);
|
w.set_txmsgsentie(enable);
|
||||||
|
|
Loading…
Reference in a new issue