diff --git a/Kernel/Modules/virtio/devices/mod.rs b/Kernel/Modules/virtio/devices/mod.rs
index 7b81754719c271370fd8b1316722ba3b158ab066..6448f9585714c89b5537695f6dde785488aaa6c6 100644
--- a/Kernel/Modules/virtio/devices/mod.rs
+++ b/Kernel/Modules/virtio/devices/mod.rs
@@ -10,19 +10,19 @@ mod block;
 mod video;
 //mod network;
 
-pub fn new_boxed<T: Interface+Send+Sync+'static>(dev: u32, io: device_manager::IOBinding, irq: u32) -> Box<device_manager::DriverInstance>
+pub fn new_boxed<T: Interface+Send+Sync+'static>(dev_id: u32, int: T) -> Box<device_manager::DriverInstance>
 {
-	match dev
+	match dev_id
 	{
 	// 0: Reserved/invalid
 	0 => Box::new( NullDevice ),
-	//1 => Box::new( network::NetDevice::new(T::new(io, irq)) ),
+	//1 => Box::new( network::NetDevice::new(int) ),
 	1 => {
 		log_notice!("TODO: Support VirtIO network devices (type = 1)");
 		Box::new(NullDevice)
 		}
-	2 => Box::new( block::BlockDevice::new(T::new(io, irq)) ),
-	16 => Box::new( video::VideoDevice::new(T::new(io, irq)) ),
+	2 => Box::new( block::BlockDevice::new(int) ),	// 2 = Block device
+	16 => Box::new( video::VideoDevice::new(int) ),	// 16 = Graphics Adapter
 	dev @ _ => {
 		log_error!("VirtIO device has unknown device ID {:#x}", dev);
 		Box::new(NullDevice)
diff --git a/Kernel/Modules/virtio/devices/video.rs b/Kernel/Modules/virtio/devices/video.rs
index 47be6b8122b3d6354bd8c8f6645c474d0c5d9199..0ad3579a8f0b2a35c764c731abf95b35bad23c62 100644
--- a/Kernel/Modules/virtio/devices/video.rs
+++ b/Kernel/Modules/virtio/devices/video.rs
@@ -5,7 +5,7 @@ use kernel::metadevs::video;
 use interface::Interface;
 use queue::{Queue,Buffer};
 use kernel::lib::mem::aref::{Aref,ArefBorrow};
-use kernel::async::Mutex;
+use kernel::sync::Mutex;
 
 pub struct VideoDevice<I>
 where
@@ -27,7 +27,7 @@ where
 	controlq: Queue,
 	cursorq: Queue,
 
-	scanouts: Mutex<Vec<Option<Framebuffer<I>>>>,
+	scanouts: Mutex<Vec<Option<video::FramebufferRegistration>>>,
 }
 
 struct Framebuffer<I>
@@ -35,8 +35,8 @@ where
 	I: Interface + Send + Sync
 {
 	dev: ArefBorrow<DeviceCore<I>>,
-	/// Handle to video metadev registration
-	_video_handle: video::FramebufferRegistration,
+	scanout_idx: usize,
+	dims: (u32, u32,),
 }
 
 impl<I> VideoDevice<I>
@@ -56,7 +56,14 @@ where
 			});
 
 		let di = core.get_display_info();
-		log_debug!("di = {:?}", di);
+		for (i,screen) in Iterator::enumerate( di[..num_scanouts].iter() )
+		{
+			if screen.enabled != 0
+			{
+				log_debug!("Scanout #{} enabled: {:?} flags={:#x}", i, screen.r, screen.flags);
+				core.scanouts.lock()[i] = Some(video::add_output( Box::new(Framebuffer::new(core.borrow(), i, screen)) ));
+			}
+		}
 
 		VideoDevice {
 			_core: core,
@@ -80,19 +87,38 @@ where
 			};
 		let mut ret_hdr: hw::CtrlHeader = ::kernel::lib::PodHelpers::zeroed();
 		let mut ret_info: [hw::DisplayOne; 16] = ::kernel::lib::PodHelpers::zeroed();
-		let h = self.controlq.send_buffers(&self.interface, &mut [
-			Buffer::Read(::kernel::lib::as_byte_slice(&hdr)),
-			Buffer::Write(::kernel::lib::as_byte_slice_mut(&mut ret_hdr)),
-			Buffer::Write(::kernel::lib::as_byte_slice_mut(&mut ret_info)),
-			]);
-		match h.wait_for_completion()
+		let rv = {
+			let h = self.controlq.send_buffers(&self.interface, &mut [
+				Buffer::Read(::kernel::lib::as_byte_slice(&hdr)),
+				Buffer::Write(::kernel::lib::as_byte_slice_mut(&mut ret_hdr)),
+				Buffer::Write(::kernel::lib::as_byte_slice_mut(&mut ret_info)),
+				]);
+			h.wait_for_completion()
+			};
+		match rv
 		{
-		Ok(bytes) => todo!("{} bytes from gpu request", bytes),
-		Err( () ) => panic!("TODO"),
+		Ok(bytes) => {
+			assert_eq!(bytes, ::core::mem::size_of_val(&ret_hdr) + ::core::mem::size_of_val(&ret_info), "Mismatched respose size");
+			ret_info
+			},
+		Err( () ) => panic!("TODO: Handle error waiting for VIRTIO_GPU_CMD_GET_DISPLAY_INFO response"),
 		}
 	}
 }
 
+impl<I> Framebuffer<I>
+where
+	I: 'static + Interface + Send + Sync
+{
+	fn new(dev: ArefBorrow<DeviceCore<I>>, scanout_idx: usize, info: &hw::DisplayOne) -> Self
+	{
+		Framebuffer {
+			dev: dev,
+			scanout_idx: scanout_idx,
+			dims: (info.r.width, info.r.height,),
+			}
+	}
+}
 impl<I> video::Framebuffer for Framebuffer<I>
 where
 	I: 'static + Interface + Send + Sync
@@ -105,8 +131,10 @@ where
 	}
 	
 	fn get_size(&self) -> video::Dims {
-		// TODO
-		todo!("");
+		video::Dims {
+			w: self.dims.0,
+			h: self.dims.1,
+			}
 	}
 	fn set_size(&mut self, _newsize: video::Dims) -> bool {
 		// TODO
@@ -114,15 +142,19 @@ where
 	}
 	
 	fn blit_inner(&mut self, dst: video::Rect, src: video::Rect) {
+		todo!("blit_inner");
 	}
 	fn blit_ext(&mut self, dst: video::Rect, src: video::Rect, srf: &video::Framebuffer) -> bool {
 		false
 	}
 	fn blit_buf(&mut self, dst: video::Rect, buf: &[u32]) {
+		todo!("blit_buf");
 	}
 	fn fill(&mut self, dst: video::Rect, colour: u32) {
+		todo!("fill");
 	}
 	fn move_cursor(&mut self, _p: Option<video::Pos>) {
+		todo!("move_cursor");
 	}
 }
 
@@ -162,6 +194,7 @@ mod hw
 	pub const VIRTIO_GPU_FLAG_FENCE: u32 = 1 << 0;
 
 	#[repr(C)]
+	#[derive(Debug)]
 	pub struct CtrlHeader
 	{
 		pub type_: u32,
@@ -172,7 +205,6 @@ mod hw
 	}
 
 	#[repr(C)]
-	#[derive(Debug)]
 	pub struct Rect
 	{
 		pub x: u32,
@@ -180,6 +212,11 @@ mod hw
 		pub width: u32,
 		pub height: u32,
 	}
+	impl ::core::fmt::Debug for Rect {
+		fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+			write!(f, "Rect {{ {},{} {}x{} }}", self.x, self.y, self.width, self.height)
+		}
+	}
 	#[repr(C)]
 	#[derive(Debug)]
 	pub struct DisplayOne
diff --git a/Kernel/Modules/virtio/drivers.rs b/Kernel/Modules/virtio/drivers.rs
index 66d2d59dca047a0ead89e3e742370e81449e80ec..7ac858ae3e8553c774bafe3a51d02eb127ed62b0 100644
--- a/Kernel/Modules/virtio/drivers.rs
+++ b/Kernel/Modules/virtio/drivers.rs
@@ -49,7 +49,7 @@ impl device_manager::Driver for FdtMmioDriver
 			return Box::new( NullDevice );
 		}
 
-		::devices::new_boxed::<::interface::Mmio>(dev, io, bus_dev.get_irq(0))
+		::devices::new_boxed(dev, ::interface::Mmio::new(io, bus_dev.get_irq(0)))
 	}
 }
 
@@ -79,7 +79,6 @@ impl device_manager::Driver for Pci
 		// TODO: The IO space may not be in BAR0? Instead referenced in PCI capabilities
 		// - The PCI capabilities list includes entries for each region the driver uses, which can sub-slice a BAR
 		// - Need to be able to read the capabilities list, AND get a sub-slice of a BAR
-		let io = bus_dev.bind_io(0);
 		let dev = match bus_dev.get_attr("device").unwrap_u32()
 			{
 			0x1000 => 1,	// network card
@@ -95,7 +94,129 @@ impl device_manager::Driver for Pci
 			v @ _ => panic!("BUGCHECK: Binding with unexpected PCI device id {:#x}", v),
 			};
 
-		::devices::new_boxed::<::interface::Mmio>(dev, io, irq)
+		let mut common_bar = None;
+		let mut device_cfg_bar = None;
+		let mut notify_bar = None;
+		for cap in pci_helpers::CapabilityIter::new(&*bus_dev)
+		{
+			match cap.id
+			{
+			9 => {
+				let bar = cap.read_32(1) as usize;
+				let ofs = cap.read_32(2) as usize;
+				let len = cap.read_32(3) as usize;
+				match cap.byte0
+				{
+				1 => {
+					log_debug!("Common: BAR{} {:#x}+{:#x}", bar, ofs, len);
+					let io = (bar, ofs, len);
+					if common_bar.is_none() {
+						common_bar = Some(io);
+					}
+					},
+				2 => {
+					log_debug!("Notify: BAR{} {:#x}+{:#x}", bar, ofs, len);
+					let io = (bar, ofs, len);
+					let mult = cap.read_32(4);
+
+					if notify_bar.is_none() {
+						notify_bar = Some( (io, mult,) );
+					}
+					},
+				3 => log_debug!("Isr: BAR{} {:#x}+{:#x}", bar, ofs, len),
+				4 => {
+					log_debug!("Device Config: BAR{} {:#x}+{:#x}", bar, ofs, len);
+					let io = (bar, ofs, len);
+					if device_cfg_bar.is_none() {
+						device_cfg_bar = Some(io);
+					}
+					},
+				5 => log_debug!("PCI CFG: BAR{} {:#x}+{:#x}", bar, ofs, len),
+				_ => {},
+				}
+				},
+			_ => {},
+			}
+		}
+
+		match (common_bar, device_cfg_bar, notify_bar)
+		{
+		( Some(common), Some(dev_cfg), Some( (notify, notify_mult) ) ) => {
+			let io = ::interface::PciRegions {
+				common: bus_dev.bind_io_slice( common.0, Some((common.1, common.2)) ),
+				notify: bus_dev.bind_io_slice( notify.0, Some((notify.1, notify.2)) ),
+				notify_off_mult: notify_mult,
+				dev_cfg: bus_dev.bind_io_slice( dev_cfg.0, Some((dev_cfg.1, dev_cfg.2)) ),
+				};
+			::devices::new_boxed(dev, ::interface::Pci::new(io, irq))
+			},
+		(common_bar, device_cfg_bar, notify_bar,) => {
+			log_error!("VirtIO PCI device doesn't have a full set of capabilities - common={:?} dev_cfg={:?} notify={:?}", common_bar, device_cfg_bar, notify_bar);
+			return Box::new( NullDevice );
+			},
+		}
 	}
 }
 
+mod pci_helpers
+{
+	pub struct Capability<'a> {
+		dev: &'a ::kernel::device_manager::BusDevice,
+		pub id: u8,
+		ofs: u8,
+		len: u8,
+		pub byte0: u8,
+	}
+	impl<'a> Capability<'a>
+	{
+		pub fn read_32(&self, idx: usize) -> u32 {
+			assert!(idx < self.len as usize / 4);
+			self.dev.get_attr_idx("raw_config", self.ofs as usize + idx*4).unwrap_u32()
+		}
+	}
+
+	pub struct CapabilityIter<'a>
+	{
+		dev: &'a ::kernel::device_manager::BusDevice,
+		cap_ptr: u8,
+	}
+	impl<'a> CapabilityIter<'a>
+	{
+		pub fn new(dev: &'a ::kernel::device_manager::BusDevice) -> Self
+		{
+			// TODO: Assert that it's PCI
+			CapabilityIter {
+				dev: dev,
+				cap_ptr: if (dev.get_attr_idx("raw_config", 0x4).unwrap_u32() >> 16) & 0x10 != 0 {
+						(dev.get_attr_idx("raw_config", 0x34).unwrap_u32() & 0xFC) as u8
+					}
+					else {
+						0
+					},
+				}
+		}
+	}
+	impl<'a> Iterator for CapabilityIter<'a>
+	{
+		type Item = Capability<'a>;
+		fn next(&mut self) -> Option<Capability<'a>>
+		{
+			if self.cap_ptr == 0 {
+				None
+			}
+			else {
+				let cap_hdr = self.dev.get_attr_idx("raw_config", self.cap_ptr as usize).unwrap_u32();
+				let (id, next, len, byte0) = (cap_hdr as u8, (cap_hdr >> 8) as u8, (cap_hdr >> 16) as u8, (cap_hdr >> 24) as u8);
+				let rv = Capability {
+					dev: self.dev,
+					id: id,
+					ofs: self.cap_ptr,
+					len: len,
+					byte0: byte0,
+					};
+				self.cap_ptr = next;
+				Some(rv)
+			}
+		}
+	}
+}
diff --git a/Kernel/Modules/virtio/interface.rs b/Kernel/Modules/virtio/interface.rs
index 187101d2036dc767567ef91e4a71e639daa73300..fd83014fba6384b1ac5ddda01e0c4ee416611892 100644
--- a/Kernel/Modules/virtio/interface.rs
+++ b/Kernel/Modules/virtio/interface.rs
@@ -9,8 +9,6 @@ use queue::Queue;
 
 pub trait Interface
 {
-	fn new(io: IOBinding, irq: u32) -> Self;
-
 	fn bind_interrupt(&mut self, cb: Box<FnMut()->bool + Send + 'static>);
 
 	fn negotiate_features(&mut self, supported: u32) -> u32;
@@ -27,6 +25,149 @@ pub trait Interface
 	unsafe fn cfg_write_32(&self, ofs: usize, v: u32);
 }
 
+pub struct PciRegions {
+	pub common: IOBinding,
+	pub notify: IOBinding,
+	pub notify_off_mult: u32,
+	pub dev_cfg: IOBinding,
+}
+#[repr(usize)]
+#[allow(dead_code,non_camel_case_types)]
+enum PciCommonReg {
+	device_feature_select = 0x0,	// u32 RW
+	device_feature        = 0x4,	// u32 RO
+	driver_feature_select = 0x8,	// u32 RW
+	driver_feature        = 0xC,	// u32 RW
+	msix_config           = 0x10,	// u16 RW
+	num_queues            = 0x12,	// u16 RO
+	device_status         = 0x14,	// u8 RW
+	config_generation     = 0x15,	// u8 RO
+	queue_select          = 0x16,	// u16
+	queue_size            = 0x18,	// u16
+	queue_msix_vector     = 0x1a,	// u16
+	queue_enable          = 0x1c,	// u16
+	queue_notify_off      = 0x1e,	// u16
+	queue_desc            = 0x20,	// u64
+	queue_avail           = 0x28,	// u64
+	queue_used            = 0x30,	// u64
+}
+pub struct Pci {
+	bars: PciRegions,
+
+	irq_gsi: u32,
+	irq_handle: Option<::kernel::irqs::ObjectHandle>,
+
+	queue_notify_offsets: Vec<u32>,
+}
+impl Pci
+{
+	pub fn new(io: PciRegions, irq_gsi: u32) -> Self {
+		// SAFE: Unique access, read-only
+		let nqueues = unsafe { io.common.read_16(PciCommonReg::num_queues as usize) as usize };
+		let queue_notify_offsets = (0 .. nqueues).map(|q| {
+			// SAFE: Unique access, no memory
+			unsafe {
+				io.common.write_16(PciCommonReg::queue_select as usize, q as u16);
+				io.common.read_16(PciCommonReg::queue_notify_off as usize) as u32 * io.notify_off_mult
+			}
+			}).collect();
+		log_debug!("nqueues = {}, queue_notify_offsets={:?}", nqueues, queue_notify_offsets);
+
+		let mut rv = Pci {
+			bars: io,
+			irq_gsi: irq_gsi,
+			irq_handle: None,
+			queue_notify_offsets: queue_notify_offsets,
+			};
+		// SAFE: Unique access
+		unsafe {
+			rv.set_device_status(0x0);	// Reset
+			rv.set_device_status(0x1);	// Acknowledge
+		}
+		rv
+	}
+	unsafe fn set_device_status(&mut self, val: u8) {
+		self.bars.common.write_8(0x10, val);	// device_status
+	}
+}
+impl Interface for Pci
+{
+	fn bind_interrupt(&mut self, cb: Box<FnMut()->bool + Send + 'static>) {
+		self.irq_handle = Some( ::kernel::irqs::bind_object(self.irq_gsi, cb) );
+	}
+
+	fn negotiate_features(&mut self, supported: u32) -> u32 {
+		// SAFE: Unique access
+		unsafe {
+			let dev_supported = self.bars.common.read_32(PciCommonReg::device_feature as usize);
+			let common = dev_supported & supported;
+			self.bars.common.write_32(PciCommonReg::device_feature_select as usize, common);
+			common
+		}
+	}
+
+	fn get_queue(&mut self, idx: usize, size: usize) -> Option<Queue> {
+		if idx >= self.queue_notify_offsets.len() {
+			log_error!("Request for queue {} is out of valid range {}", idx, self.queue_notify_offsets.len());
+			return None
+		}
+		// SAFE: Unique access, so no race possible
+		unsafe {
+			self.bars.common.write_16(PciCommonReg::queue_select as usize, idx as u16);
+		}
+		// SAFE: Unique access
+		let max_size = unsafe { self.bars.common.read_16(PciCommonReg::queue_size as usize) as usize };
+		if max_size == 0 {
+			None
+		}
+		else {
+			let size = if size == 0 || size > max_size { max_size } else { size };
+			let queue = Queue::new(idx, size);
+
+			// SAFE: Unique access, so no race possible
+			unsafe {
+				self.bars.common.write_32(PciCommonReg::queue_size as usize, size as u32);	// queue_size
+				let addr = queue.phys_addr_desctab();
+				self.bars.common.write_32(PciCommonReg::queue_desc as usize, addr as u32);
+				self.bars.common.write_32(PciCommonReg::queue_desc as usize + 4, (addr >> 32) as u32);
+				let addr = queue.phys_addr_avail();
+				self.bars.common.write_32(PciCommonReg::queue_avail as usize, addr as u32);
+				self.bars.common.write_32(PciCommonReg::queue_avail as usize + 4, (addr >> 32) as u32);
+				let addr = queue.phys_addr_used();
+				self.bars.common.write_32(PciCommonReg::queue_used as usize, addr as u32);
+				self.bars.common.write_32(PciCommonReg::queue_used as usize + 4, (addr >> 32) as u32);
+
+				self.bars.common.write_16(PciCommonReg::queue_enable as usize, 1);
+			}
+
+			Some(queue)
+		}
+	}
+
+	fn set_driver_ok(&mut self) {
+		// SAFE: Unique access
+		unsafe {
+			self.set_device_status(0x4);
+		}
+	}
+	
+	fn notify_queue(&self, idx: usize) {
+		log_trace!("notify_queue({})", idx);
+		// SAFE: Atomic write
+		unsafe {
+			self.bars.notify.write_16(self.queue_notify_offsets[idx] as usize, idx as u16)
+		}
+	}
+
+	unsafe fn cfg_read_32(&self, ofs: usize) -> u32 {
+		assert!(ofs + 4 <= 0x100);
+		self.bars.dev_cfg.read_32(ofs)
+	}
+	unsafe fn cfg_write_32(&self, ofs: usize, v: u32) {
+		assert!(ofs + 4 <= 0x100);
+		self.bars.dev_cfg.write_32(ofs, v);
+	}
+}
 
 /// Memory-Mapped IO binding
 pub struct Mmio {
@@ -34,9 +175,9 @@ pub struct Mmio {
 	irq_gsi: u32,
 	irq_handle: Option<::kernel::irqs::ObjectHandle>,
 }
-impl Interface for Mmio
+impl Mmio
 {
-	fn new(io: IOBinding, irq_gsi: u32) -> Self {
+	pub fn new(io: IOBinding, irq_gsi: u32) -> Self {
 		let mut rv = Mmio {
 			io: io,
 			irq_gsi: irq_gsi,
@@ -50,7 +191,12 @@ impl Interface for Mmio
 		}
 		rv
 	}
-
+	unsafe fn set_device_status(&mut self, val: u32) {
+		self.io.write_32(0x70, val);
+	}
+}
+impl Interface for Mmio
+{
 	fn bind_interrupt(&mut self, cb: Box<FnMut()->bool + Send + 'static>) {
 		self.irq_handle = Some( ::kernel::irqs::bind_object(self.irq_gsi, cb) );
 	}
@@ -83,7 +229,8 @@ impl Interface for Mmio
 			unsafe {
 				self.io.write_32(0x38, size as u32);
 				//self.io.write_32(0x3C, );	// QueueAlign - TODO: What value to use here
-				let page = queue.phys_addr() / ::kernel::PAGE_SIZE as u64;
+				// TODO: This is for the legacy spec
+				let page = queue.phys_addr_desctab() / ::kernel::PAGE_SIZE as u64;
 				log_debug!("size = {}, page={:#x}", size, page);
 				self.io.write_32(0x40, page as u32);
 			}
@@ -115,8 +262,3 @@ impl Interface for Mmio
 		self.io.write_32(0x100 + ofs, v);
 	}
 }
-impl Mmio {
-	unsafe fn set_device_status(&mut self, val: u32) {
-			self.io.write_32(0x70, val);
-	}
-}
diff --git a/Kernel/Modules/virtio/queue.rs b/Kernel/Modules/virtio/queue.rs
index 2f9ac08e5bf79c02f810a8639fc499f84f8cc052..90dd75b5ea80222b237b0caab12badbfb871dbc4 100644
--- a/Kernel/Modules/virtio/queue.rs
+++ b/Kernel/Modules/virtio/queue.rs
@@ -45,12 +45,14 @@ pub const VRING_DESC_F_WRITE	: u16 = 2;
 pub const VRING_DESC_F_INDIRECT	: u16 = 4;
 
 #[repr(C)]
+// sizeof = 16
 pub struct VRingDesc {
 	addr: u64,
 	length: u32,
 	flags: u16,
 	next: u16,
 }
+const SIZEOF_VRING_DESC: usize = ::core::mem::size_of::<VRingDesc>();
 #[repr(C)]
 #[derive(Debug)]
 struct AvailRing {
@@ -77,11 +79,14 @@ struct UsedElem {
 impl Queue
 {
 	fn get_first_size(count: usize) -> usize {
-		let first = 16 * count + (2 + count + 1) * 2;
+		let first =
+			SIZEOF_VRING_DESC * count	// VRingDesc entries
+			+ (2 + count + 1) * 2	// AvailRing
+			;
 		(first + 0xFFF) & !0xFFF
 	}
 	fn get_alloc_size(count: usize) -> usize {
-		let second = 2*3 + 8 * count;
+		let second = 2*3 + 8 * count;	// UsedRing header (and footer) plus UsedElem entries
 		Self::get_first_size(count) + ((second + 0xFFF) & !0xFFF)
 	}
 
@@ -114,9 +119,15 @@ impl Queue
 		}
 	}
 
-	pub fn phys_addr(&self) -> u64 {
+	pub fn phys_addr_desctab(&self) -> u64 {
 		::kernel::memory::virt::get_phys(self.buffer.as_ref::<u8>(0)) as u64
 	}
+	pub fn phys_addr_avail(&self) -> u64 {
+		::kernel::memory::virt::get_phys(&self.avail_ring().flags) as u64
+	}
+	pub fn phys_addr_used(&self) -> u64 {
+		::kernel::memory::virt::get_phys(&self.used_ring().flags) as u64
+	}
 
 	pub fn send_buffers<'a, I: Interface>(&'a self, interface: &I, buffers: &mut [Buffer<'a>]) -> Request<'a> {
 		assert!(buffers.len() > 0);
@@ -175,7 +186,7 @@ impl Queue
 			_lh: self.avail_ring_lock.lock(),
 			// SAFE: Locked
 			ptr: unsafe { 
-				let base_ptr: *const u16 = self.buffer.as_int_mut(16 * self.size);
+				let base_ptr: *const u16 = self.buffer.as_int_mut(SIZEOF_VRING_DESC * self.size);
 				// NOTE: Constructing an unsized struct pointer
 				let ptr: &mut AvailRing = ::core::mem::transmute( (base_ptr, self.size) );
 				assert_eq!(&ptr.flags as *const _, base_ptr);