protocols: attach gets its reverse — block detach, usb-transfer dma_detach
The kernel was always symmetric (dma_bind 51 / dma_unbind 52); the two protocols that forward an attachment up the stack were one-way, so a live client could grant a device reach into its buffer but never revoke it while alive — exactly the one-way lifecycle the storage architecture's enforcement section forbids. Death stays the mechanical backstop; detach is the living process's path. Both verbs are appended, so every existing number holds. The shape mirrors attach precisely: the same region capability rides the cap slot again — the kernel matches the region, so no layer retains anything between the calls (the bus never kept the handle; now it never needs to). fat's bring-up does attach -> detach -> attach, exercising both verbs through the whole chain (fat -> storage -> bus -> kernel) on every boot: a broken detach fails every fat case instead of lying dormant until the first buffer replacement. Honest scope: the round trip proves the plumbing; unbind semantics are the kernel iommu tests' (map/unmap/translationOf); the full composition (detach then DMA faults) is a future iommu-fault extension.
This commit is contained in:
@@ -136,6 +136,15 @@ pub const Device = struct {
|
||||
return self.call(.dma_attach, {}, &.{}, handle, &reply) != null;
|
||||
}
|
||||
|
||||
/// The reverse of `attachDma`: unbind the buffer from the controller's IOMMU
|
||||
/// domain. The same region capability rides again — the kernel matches the
|
||||
/// region, so neither side kept state between the two calls. Do not name the
|
||||
/// buffer's physical address in any transfer after this.
|
||||
pub fn detachDma(self: *Device, handle: ipc.Handle) bool {
|
||||
var reply: [usb_transfer_protocol.message_maximum]u8 = undefined;
|
||||
return self.call(.dma_detach, {}, &.{}, handle, &reply) != null;
|
||||
}
|
||||
|
||||
/// One bulk transfer (IN or OUT per `endpoint_address`'s direction bit) to or
|
||||
/// from the caller's own DMA buffer at `physical`. Returns the bytes moved.
|
||||
pub fn bulk(self: *Device, endpoint_address: u8, physical: u64, length: u32) ?u32 {
|
||||
|
||||
Reference in New Issue
Block a user