svn commit: r222830 - projects/bhyve/usr.sbin/bhyve

Peter Grehan grehan at FreeBSD.org
Tue Jun 7 18:35:45 UTC 2011


Author: grehan
Date: Tue Jun  7 18:35:45 2011
New Revision: 222830
URL: http://svn.freebsd.org/changeset/base/222830

Log:
  Allow access to the device's config area with any size i/o access at any
  offset. This is now spec-compliant.

Modified:
  projects/bhyve/usr.sbin/bhyve/pci_virtio_block.c
  projects/bhyve/usr.sbin/bhyve/pci_virtio_net.c

Modified: projects/bhyve/usr.sbin/bhyve/pci_virtio_block.c
==============================================================================
--- projects/bhyve/usr.sbin/bhyve/pci_virtio_block.c	Tue Jun  7 17:40:33 2011	(r222829)
+++ projects/bhyve/usr.sbin/bhyve/pci_virtio_block.c	Tue Jun  7 18:35:45 2011	(r222830)
@@ -439,6 +439,7 @@ uint32_t
 pci_vtblk_read(struct pci_devinst *pi, int baridx, int offset, int size)
 {
 	struct pci_vtblk_softc *sc = pi->pi_arg;
+	void *ptr;
 	uint32_t value;
 
 	if (offset + size > VTBLK_REGSZ) {
@@ -481,8 +482,15 @@ pci_vtblk_read(struct pci_devinst *pi, i
 		sc->vbsc_isr = 0;     /* a read clears this flag */
 		break;
 	case VTBLK_R_CFG ... VTBLK_R_CFG_END:
-		assert(size == 1);
-		value = *((uint8_t *)&sc->vbsc_cfg + offset - VTBLK_R_CFG);
+		assert(size + offset <= (VTBLK_R_CFG_END + 1));
+		ptr = (uint8_t *)&sc->vbsc_cfg + offset - VTBLK_R_CFG;
+		if (size == 1) {
+			value = *(uint8_t *) ptr;
+		} else if (size == 2) {
+			value = *(uint16_t *) ptr;
+		} else {
+			value = *(uint32_t *) ptr;
+		}
 		break;
 	default:
 		DPRINTF(("vtblk: unknown i/o read offset %d\n\r", offset));

Modified: projects/bhyve/usr.sbin/bhyve/pci_virtio_net.c
==============================================================================
--- projects/bhyve/usr.sbin/bhyve/pci_virtio_net.c	Tue Jun  7 17:40:33 2011	(r222829)
+++ projects/bhyve/usr.sbin/bhyve/pci_virtio_net.c	Tue Jun  7 18:35:45 2011	(r222830)
@@ -594,7 +594,8 @@ pci_vtnet_write(struct pci_devinst *pi, 
 		uint32_t value)
 {
 	struct pci_vtnet_softc *sc = pi->pi_arg;
-	
+	void *ptr;
+
 	if (offset + size > VTNET_REGSZ) {
 		DPRINTF(("vtnet_write: 2big, offset %d size %d\n",
 			 offset, size));
@@ -632,11 +633,19 @@ pci_vtnet_write(struct pci_devinst *pi, 
 	case VTNET_R_CFG3:
 	case VTNET_R_CFG4:
 	case VTNET_R_CFG5:
+		assert((size + offset) <= (VTNET_R_CFG5 + 1));
+		ptr = &sc->vsc_macaddr[offset - VTNET_R_CFG0];
 		/*
 		 * The driver is allowed to change the MAC address
 		 */
-		assert(size == 1);
 		sc->vsc_macaddr[offset - VTNET_R_CFG0] = value;
+		if (size == 1) {
+			*(uint8_t *) ptr = value;
+		} else if (size == 2) {
+			*(uint16_t *) ptr = value;
+		} else {
+			*(uint32_t *) ptr = value;
+		}
 		break;
 	case VTCFG_R_HOSTCAP:
 	case VTCFG_R_QNUM:
@@ -658,6 +667,7 @@ uint32_t
 pci_vtnet_read(struct pci_devinst *pi, int baridx, int offset, int size)
 {
 	struct pci_vtnet_softc *sc = pi->pi_arg;
+	void *ptr;
 	uint32_t value;
 
 	if (offset + size > VTNET_REGSZ) {
@@ -708,16 +718,23 @@ pci_vtnet_read(struct pci_devinst *pi, i
 	case VTNET_R_CFG3:
 	case VTNET_R_CFG4:
 	case VTNET_R_CFG5:
-		assert(size == 1);
-		value = sc->vsc_macaddr[offset - VTNET_R_CFG0];
+                assert((size + offset) <= (VTNET_R_CFG5 + 1));
+                ptr = &sc->vsc_macaddr[offset - VTNET_R_CFG0];
+                if (size == 1) {
+                        value = *(uint8_t *) ptr;
+                } else if (size == 2) {
+                        value = *(uint16_t *) ptr;
+                } else {
+                        value = *(uint32_t *) ptr;
+                }
 		break;
 	case VTNET_R_CFG6:
-		assert(size == 1);
-		value = 0x01;	/* XXX link always up */
+		assert(size != 4);
+		value = 0x01; /* XXX link always up */
 		break;
 	case VTNET_R_CFG7:
 		assert(size == 1);
-		value = 0;  /* link status is in the LSB */
+		value = 0; /* XXX link status in LSB */
 		break;
 	default:
 		DPRINTF(("vtnet: unknown i/o read offset %d\n\r", offset));


More information about the svn-src-projects mailing list