PERFORCE change 119171 for review

John Baldwin jhb at FreeBSD.org
Wed May 2 16:32:47 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=119171

Change 119171 by jhb at jhb_mutex on 2007/05/02 16:32:12

	IFC @119170.

Affected files ...

.. //depot/projects/smpng/sys/dev/ata/atapi-cam.c#34 integrate
.. //depot/projects/smpng/sys/dev/pci/pci.c#91 integrate

Differences ...

==== //depot/projects/smpng/sys/dev/ata/atapi-cam.c#34 (text+ko) ====

@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ata/atapi-cam.c,v 1.53 2007/04/30 09:33:57 thomas Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ata/atapi-cam.c,v 1.54 2007/05/02 15:30:24 scottl Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -48,6 +48,7 @@
 #include <cam/cam_periph.h>
 #include <cam/cam_sim.h>
 #include <cam/cam_xpt_sim.h>
+#include <cam/cam_xpt_periph.h>
 #include <cam/cam_debug.h>
 #include <cam/scsi/scsi_all.h>
 
@@ -210,14 +211,16 @@
     }
 
     if ((sim = cam_sim_alloc(atapi_action, atapi_poll, "ata",
-		 (void *)scp, unit, &Giant, 1, 1, devq)) == NULL) {
+		 (void *)scp, unit, &scp->state_lock, 1, 1, devq)) == NULL) {
 	error = ENOMEM;
 	goto out;
     }
     scp->sim = sim;
 
+    mtx_lock(&scp->state_lock);
     if (xpt_bus_register(sim, 0) != CAM_SUCCESS) {
 	error = EINVAL;
+	mtx_unlock(&scp->state_lock);
 	goto out;
     }
     scp->flags |= BUS_REGISTERED;
@@ -226,6 +229,7 @@
 		cam_sim_path(sim), CAM_TARGET_WILDCARD,
 		CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
 	error = ENOMEM;
+	mtx_unlock(&scp->state_lock);
 	goto out;
     }
     scp->path = path;
@@ -235,6 +239,7 @@
     setup_async_cb(scp, AC_LOST_DEVICE);
     reinit_bus(scp, cold ? BOOT_ATTACH : ATTACH);
     error = 0;
+    mtx_unlock(&scp->state_lock);
 
 out:
     if (error != 0)
@@ -248,10 +253,8 @@
 {
     struct atapi_xpt_softc *scp = device_get_softc(dev);
 
-    mtx_lock(&Giant);
+    mtx_lock(&scp->state_lock);
     xpt_freeze_simq(scp->sim, 1 /*count*/);
-    mtx_unlock(&Giant);
-    mtx_lock(&scp->state_lock);
     scp->flags |= DETACHING;
     mtx_unlock(&scp->state_lock);
     free_softc(scp);
@@ -268,7 +271,9 @@
      */
 
     if (scp != NULL) {
+	mtx_lock(&scp->state_lock);
 	reinit_bus(scp, RESET);
+	mtx_unlock(&scp->state_lock);
     }
     return (0);
 }
@@ -283,7 +288,6 @@
 	return;
     }
 
-    mtx_lock(&scp->state_lock);
     old_atadev[0] = scp->atadev[0];
     old_atadev[1] = scp->atadev[1];
     scp->atadev[0] = NULL;
@@ -303,7 +307,6 @@
     }
     dev_changed = (old_atadev[0] != scp->atadev[0])
 	       || (old_atadev[1] != scp->atadev[1]);
-    mtx_unlock(&scp->state_lock);
     free(children, M_TEMP);
 
     switch (reason) {
@@ -327,14 +330,12 @@
 {
     struct ccb_setasync csa;
 
-    mtx_lock(&Giant);
     xpt_setup_ccb(&csa.ccb_h, scp->path, /*priority*/ 5);
     csa.ccb_h.func_code = XPT_SASYNC_CB;
     csa.event_enable = events;
     csa.callback = &atapi_async;
     csa.callback_arg = scp->sim;
     xpt_action((union ccb *) &csa);
-    mtx_unlock(&Giant);
 }
 
 static void
@@ -377,11 +378,9 @@
 	cpi->protocol_version = SCSI_REV_2;
 
 	if (softc->ata_ch && tid != CAM_TARGET_WILDCARD) {
-	    mtx_lock(&softc->state_lock);
 	    if (softc->atadev[tid] == NULL) {
 		ccb->ccb_h.status = CAM_DEV_NOT_THERE;
 		xpt_done(ccb);
-		mtx_unlock(&softc->state_lock);
 		return;
 	    }
 	    switch (softc->atadev[ccb_h->target_id]->mode) {
@@ -414,7 +413,6 @@
 	    default:
 		break;
 	    }
-	    mtx_unlock(&softc->state_lock);
 	}
 	ccb->ccb_h.status = CAM_REQ_CMP;
 	xpt_done(ccb);
@@ -425,7 +423,9 @@
 	int tid = ccb_h->target_id;
 
 	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, ("dev reset\n"));
+	mtx_unlock(&softc->state_lock);
 	ata_controlcmd(softc->atadev[tid]->dev, ATA_DEVICE_RESET, 0, 0, 0);
+	mtx_lock(&softc->state_lock);
 	ccb->ccb_h.status = CAM_REQ_CMP;
 	xpt_done(ccb);
 	return;
@@ -433,7 +433,9 @@
 
     case XPT_RESET_BUS:
 	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, ("bus reset\n"));
+	mtx_unlock(&softc->state_lock);
 	ata_reinit(softc->parent);
+	mtx_lock(&softc->state_lock);
 	ccb->ccb_h.status = CAM_REQ_CMP;
 	xpt_done(ccb);
 	return;
@@ -475,18 +477,15 @@
 
 	CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, ("XPT_SCSI_IO\n"));
 
-	mtx_lock(&softc->state_lock);
 	if (softc->flags & DETACHING) {
 	    ccb->ccb_h.status = CAM_REQ_ABORTED;
 	    xpt_done(ccb);
-	    mtx_unlock(&softc->state_lock);
 	    return;
 	}
 
 	if (softc->atadev[tid] == NULL) {
 	    ccb->ccb_h.status = CAM_DEV_NOT_THERE;
 	    xpt_done(ccb);
-	    mtx_unlock(&softc->state_lock);
 	    return;
 	}
 
@@ -494,7 +493,6 @@
 	if ((ccb_h->status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
 	    printf("XPT_SCSI_IO received but already in progress?\n");
 	    xpt_done(ccb);
-	    mtx_unlock(&softc->state_lock);
 	    return;
 	}
 	if (lid > 0) {
@@ -641,6 +639,7 @@
 	mtx_unlock(&softc->state_lock);
 
 	ata_queue_request(request);
+	mtx_lock(&softc->state_lock);
 	return;
     }
 
@@ -657,21 +656,19 @@
 	ata_free_request(request);
     if (hcb != NULL)
 	free_hcb(hcb);
-    mtx_unlock(&softc->state_lock);
-    mtx_lock(&Giant);
     xpt_print_path(ccb_h->path);
     printf("out of memory, freezing queue.\n");
     softc->flags |= RESOURCE_SHORTAGE;
     xpt_freeze_simq(sim, /*count*/ 1);
-    mtx_unlock(&Giant);
     ccb_h->status = CAM_REQUEUE_REQ;
     xpt_done(ccb);
+    mtx_unlock(&softc->state_lock);
     return;
 
 action_invalid:
-    mtx_unlock(&softc->state_lock);
     ccb_h->status = CAM_REQ_INVALID;
     xpt_done(ccb);
+    mtx_unlock(&softc->state_lock);
     return;
 }
 
@@ -829,20 +826,22 @@
 		      ("Rescan succeeded\n"));
 	}
 	xpt_free_path(ccb->ccb_h.path);
-	free(ccb, M_ATACAM);
+	xpt_free_ccb(ccb);
 }
 
 static void
 cam_rescan(struct cam_sim *sim)
 {
     struct cam_path *path;
-    union ccb *ccb = malloc(sizeof(union ccb), M_ATACAM, M_WAITOK | M_ZERO);
+    union ccb *ccb;
+
+    ccb = xpt_alloc_ccb_nowait();
+    if (ccb == NULL)
+	return;
 
-    mtx_lock(&Giant);
     if (xpt_create_path(&path, xpt_periph, cam_sim_path(sim),
 			CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
-	mtx_unlock(&Giant);
-	free(ccb, M_ATACAM);
+	xpt_free_ccb(ccb);
 	return;
     }
 
@@ -853,7 +852,6 @@
     ccb->crcn.flags = CAM_FLAG_NONE;
     xpt_action(ccb);
     /* scan is in progress now */
-    mtx_unlock(&Giant);
 }
 
 static struct atapi_hcb *
@@ -891,8 +889,6 @@
 	TAILQ_FOREACH(hcb, &scp->pending_hcbs, chain) {
 	    free_hcb_and_ccb_done(hcb, CAM_UNREC_HBA_ERROR);
 	}
-	mtx_unlock(&scp->state_lock);
-	mtx_lock(&Giant);
 	if (scp->path != NULL) {
 	    setup_async_cb(scp, 0);
 	    xpt_free_path(scp->path);
@@ -908,7 +904,6 @@
 		printf("Can't free %s SIM (still registered)\n",
 		       cam_sim_name(scp->sim));
 	}
-	mtx_unlock(&Giant);
 	mtx_destroy(&scp->state_lock);
     }
 }

==== //depot/projects/smpng/sys/dev/pci/pci.c#91 (text+ko) ====

@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/pci/pci.c,v 1.349 2007/04/25 14:45:46 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/pci/pci.c,v 1.350 2007/05/02 16:21:18 jhb Exp $");
 
 #include "opt_bus.h"
 
@@ -1013,29 +1013,29 @@
 pci_enable_msix(device_t dev, u_int index, uint64_t address, uint32_t data)
 {
 	struct pci_devinfo *dinfo = device_get_ivars(dev);
-	pcicfgregs *cfg = &dinfo->cfg;
+	struct pcicfg_msix *msix = &dinfo->cfg.msix;
 	uint32_t offset;
 
-	KASSERT(cfg->msix.msix_alloc > index, ("bogus index"));
-	offset = cfg->msix.msix_table_offset + index * 16;
-	bus_write_4(cfg->msix.msix_table_res, offset, address & 0xffffffff);
-	bus_write_4(cfg->msix.msix_table_res, offset + 4, address >> 32);
-	bus_write_4(cfg->msix.msix_table_res, offset + 8, data);
+	KASSERT(msix->msix_alloc > index, ("bogus index"));
+	offset = msix->msix_table_offset + index * 16;
+	bus_write_4(msix->msix_table_res, offset, address & 0xffffffff);
+	bus_write_4(msix->msix_table_res, offset + 4, address >> 32);
+	bus_write_4(msix->msix_table_res, offset + 8, data);
 }
 
 void
 pci_mask_msix(device_t dev, u_int index)
 {
 	struct pci_devinfo *dinfo = device_get_ivars(dev);
-	pcicfgregs *cfg = &dinfo->cfg;
+	struct pcicfg_msix *msix = &dinfo->cfg.msix;
 	uint32_t offset, val;
 
-	KASSERT(cfg->msix.msix_msgnum > index, ("bogus index"));
-	offset = cfg->msix.msix_table_offset + index * 16 + 12;
-	val = bus_read_4(cfg->msix.msix_table_res, offset);
+	KASSERT(msix->msix_msgnum > index, ("bogus index"));
+	offset = msix->msix_table_offset + index * 16 + 12;
+	val = bus_read_4(msix->msix_table_res, offset);
 	if (!(val & PCIM_MSIX_VCTRL_MASK)) {
 		val |= PCIM_MSIX_VCTRL_MASK;
-		bus_write_4(cfg->msix.msix_table_res, offset, val);
+		bus_write_4(msix->msix_table_res, offset, val);
 	}
 }
 
@@ -1043,15 +1043,15 @@
 pci_unmask_msix(device_t dev, u_int index)
 {
 	struct pci_devinfo *dinfo = device_get_ivars(dev);
-	pcicfgregs *cfg = &dinfo->cfg;
+	struct pcicfg_msix *msix = &dinfo->cfg.msix;
 	uint32_t offset, val;
 
-	KASSERT(cfg->msix.msix_alloc > index, ("bogus index"));
-	offset = cfg->msix.msix_table_offset + index * 16 + 12;
-	val = bus_read_4(cfg->msix.msix_table_res, offset);
+	KASSERT(msix->msix_alloc > index, ("bogus index"));
+	offset = msix->msix_table_offset + index * 16 + 12;
+	val = bus_read_4(msix->msix_table_res, offset);
 	if (val & PCIM_MSIX_VCTRL_MASK) {
 		val &= ~PCIM_MSIX_VCTRL_MASK;
-		bus_write_4(cfg->msix.msix_table_res, offset, val);
+		bus_write_4(msix->msix_table_res, offset, val);
 	}
 }
 
@@ -1059,13 +1059,13 @@
 pci_pending_msix(device_t dev, u_int index)
 {
 	struct pci_devinfo *dinfo = device_get_ivars(dev);
-	pcicfgregs *cfg = &dinfo->cfg;
+	struct pcicfg_msix *msix = &dinfo->cfg.msix;
 	uint32_t offset, bit;
 
-	KASSERT(cfg->msix.msix_alloc > index, ("bogus index"));
-	offset = cfg->msix.msix_pba_offset + (index / 32) * 4;
+	KASSERT(msix->msix_alloc > index, ("bogus index"));
+	offset = msix->msix_pba_offset + (index / 32) * 4;
 	bit = 1 << index % 32;
-	return (bus_read_4(cfg->msix.msix_pba_res, offset) & bit);
+	return (bus_read_4(msix->msix_pba_res, offset) & bit);
 }
 
 /*
@@ -1285,16 +1285,16 @@
 pci_release_msix(device_t dev, device_t child)
 {
 	struct pci_devinfo *dinfo = device_get_ivars(child);
-	pcicfgregs *cfg = &dinfo->cfg;
+	struct pcicfg_msix *msix = &dinfo->cfg.msix;
 	struct resource_list_entry *rle;
 	int count, i;
 
 	/* Do we have any messages to release? */
-	if (cfg->msix.msix_alloc == 0)
+	if (msix->msix_alloc == 0)
 		return (ENODEV);
 
 	/* Make sure none of the resources are allocated. */
-	for (i = 1, count = 0; count < cfg->msix.msix_alloc; i++) {
+	for (i = 1, count = 0; count < msix->msix_alloc; i++) {
 		rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, i);
 		if (rle == NULL)
 			continue;
@@ -1303,13 +1303,13 @@
 		count++;
 	}
 
-	/* Update control register with to disable MSI-X. */
-	cfg->msix.msix_ctrl &= ~PCIM_MSIXCTRL_MSIX_ENABLE;
-	pci_write_config(child, cfg->msix.msix_location + PCIR_MSIX_CTRL,
-	    cfg->msix.msix_ctrl, 2);
+	/* Update control register to disable MSI-X. */
+	msix->msix_ctrl &= ~PCIM_MSIXCTRL_MSIX_ENABLE;
+	pci_write_config(child, msix->msix_location + PCIR_MSIX_CTRL,
+	    msix->msix_ctrl, 2);
 
 	/* Release the messages. */
-	for (i = 1, count = 0; count < cfg->msix.msix_alloc; i++) {
+	for (i = 1, count = 0; count < msix->msix_alloc; i++) {
 		rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, i);
 		if (rle == NULL)
 			continue;
@@ -1320,7 +1320,7 @@
 	}
 
 	/* Update alloc count. */
-	cfg->msix.msix_alloc = 0;
+	msix->msix_alloc = 0;
 	return (0);
 }
 
@@ -1334,10 +1334,10 @@
 pci_msix_count_method(device_t dev, device_t child)
 {
 	struct pci_devinfo *dinfo = device_get_ivars(child);
-	pcicfgregs *cfg = &dinfo->cfg;
+	struct pcicfg_msix *msix = &dinfo->cfg.msix;
 
-	if (pci_do_msix && cfg->msix.msix_location != 0)
-		return (cfg->msix.msix_msgnum);
+	if (pci_do_msix && msix->msix_location != 0)
+		return (msix->msix_msgnum);
 	return (0);
 }
 
@@ -1348,26 +1348,26 @@
 pci_enable_msi(device_t dev, uint64_t address, uint16_t data)
 {
 	struct pci_devinfo *dinfo = device_get_ivars(dev);
-	pcicfgregs *cfg = &dinfo->cfg;
+	struct pcicfg_msi *msi = &dinfo->cfg.msi;
 
 	/* Write data and address values. */
-	cfg->msi.msi_addr = address;
-	cfg->msi.msi_data = data;
-	pci_write_config(dev, cfg->msi.msi_location + PCIR_MSI_ADDR,
+	msi->msi_addr = address;
+	msi->msi_data = data;
+	pci_write_config(dev, msi->msi_location + PCIR_MSI_ADDR,
 	    address & 0xffffffff, 4);
-	if (cfg->msi.msi_ctrl & PCIM_MSICTRL_64BIT) {
-		pci_write_config(dev, cfg->msi.msi_location +
-		    PCIR_MSI_ADDR_HIGH, address >> 32, 4);
-		pci_write_config(dev, cfg->msi.msi_location +
-		    PCIR_MSI_DATA_64BIT, data, 2);
+	if (msi->msi_ctrl & PCIM_MSICTRL_64BIT) {
+		pci_write_config(dev, msi->msi_location + PCIR_MSI_ADDR_HIGH,
+		    address >> 32, 4);
+		pci_write_config(dev, msi->msi_location + PCIR_MSI_DATA_64BIT,
+		    data, 2);
 	} else
-		pci_write_config(dev, cfg->msi.msi_location +
-		    PCIR_MSI_DATA, data, 2);
+		pci_write_config(dev, msi->msi_location + PCIR_MSI_DATA, data,
+		    2);
 
 	/* Enable MSI in the control register. */
-	cfg->msi.msi_ctrl |= PCIM_MSICTRL_MSI_ENABLE;
-	pci_write_config(dev, cfg->msi.msi_location + PCIR_MSI_CTRL,
-	    cfg->msi.msi_ctrl, 2);
+	msi->msi_ctrl |= PCIM_MSICTRL_MSI_ENABLE;
+	pci_write_config(dev, msi->msi_location + PCIR_MSI_CTRL, msi->msi_ctrl,
+	    2);
 }
 
 /*
@@ -1379,26 +1379,26 @@
 pci_resume_msi(device_t dev)
 {
 	struct pci_devinfo *dinfo = device_get_ivars(dev);
-	pcicfgregs *cfg = &dinfo->cfg;
+	struct pcicfg_msi *msi = &dinfo->cfg.msi;
 	uint64_t address;
 	uint16_t data;
 
-	if (cfg->msi.msi_ctrl & PCIM_MSICTRL_MSI_ENABLE) {
-		address = cfg->msi.msi_addr;
-		data = cfg->msi.msi_data;
-		pci_write_config(dev, cfg->msi.msi_location + PCIR_MSI_ADDR,
+	if (msi->msi_ctrl & PCIM_MSICTRL_MSI_ENABLE) {
+		address = msi->msi_addr;
+		data = msi->msi_data;
+		pci_write_config(dev, msi->msi_location + PCIR_MSI_ADDR,
 		    address & 0xffffffff, 4);
-		if (cfg->msi.msi_ctrl & PCIM_MSICTRL_64BIT) {
-			pci_write_config(dev, cfg->msi.msi_location +
+		if (msi->msi_ctrl & PCIM_MSICTRL_64BIT) {
+			pci_write_config(dev, msi->msi_location +
 			    PCIR_MSI_ADDR_HIGH, address >> 32, 4);
-			pci_write_config(dev, cfg->msi.msi_location +
+			pci_write_config(dev, msi->msi_location +
 			    PCIR_MSI_DATA_64BIT, data, 2);
 		} else
-			pci_write_config(dev, cfg->msi.msi_location +
-			    PCIR_MSI_DATA, data, 2);
+			pci_write_config(dev, msi->msi_location + PCIR_MSI_DATA,
+			    data, 2);
 	}
-	pci_write_config(dev, cfg->msi.msi_location + PCIR_MSI_CTRL,
-	    cfg->msi.msi_ctrl, 2);
+	pci_write_config(dev, msi->msi_location + PCIR_MSI_CTRL, msi->msi_ctrl,
+	    2);
 }
 
 /*
@@ -1556,7 +1556,7 @@
 		}
 	}
 
-	/* Update control register with actual count and enable MSI. */
+	/* Update control register with actual count. */
 	ctrl = cfg->msi.msi_ctrl;
 	ctrl &= ~PCIM_MSICTRL_MME_MASK;
 	ctrl |= (ffs(actual) - 1) << 4;
@@ -1574,7 +1574,7 @@
 pci_release_msi_method(device_t dev, device_t child)
 {
 	struct pci_devinfo *dinfo = device_get_ivars(child);
-	pcicfgregs *cfg = &dinfo->cfg;
+	struct pcicfg_msi *msi = &dinfo->cfg.msi;
 	struct resource_list_entry *rle;
 	int error, i, irqs[32];
 
@@ -1584,12 +1584,12 @@
 		return (error);
 
 	/* Do we have any messages to release? */
-	if (cfg->msi.msi_alloc == 0)
+	if (msi->msi_alloc == 0)
 		return (ENODEV);
-	KASSERT(cfg->msi.msi_alloc <= 32, ("more than 32 alloc'd messages"));
+	KASSERT(msi->msi_alloc <= 32, ("more than 32 alloc'd messages"));
 
 	/* Make sure none of the resources are allocated. */
-	for (i = 0; i < cfg->msi.msi_alloc; i++) {
+	for (i = 0; i < msi->msi_alloc; i++) {
 		rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, i + 1);
 		KASSERT(rle != NULL, ("missing MSI resource"));
 		if (rle->res != NULL)
@@ -1598,18 +1598,17 @@
 	}
 
 	/* Update control register with 0 count and disable MSI. */
-	cfg->msi.msi_ctrl &= ~(PCIM_MSICTRL_MME_MASK | PCIM_MSICTRL_MSI_ENABLE);
-	pci_write_config(child, cfg->msi.msi_location + PCIR_MSI_CTRL,
-	    cfg->msi.msi_ctrl, 2);
+	msi->msi_ctrl &= ~(PCIM_MSICTRL_MME_MASK | PCIM_MSICTRL_MSI_ENABLE);
+	pci_write_config(child, msi->msi_location + PCIR_MSI_CTRL,
+	    msi->msi_ctrl, 2);
 
 	/* Release the messages. */
-	PCIB_RELEASE_MSI(device_get_parent(dev), child, cfg->msi.msi_alloc,
-	    irqs);
-	for (i = 0; i < cfg->msi.msi_alloc; i++)
+	PCIB_RELEASE_MSI(device_get_parent(dev), child, msi->msi_alloc, irqs);
+	for (i = 0; i < msi->msi_alloc; i++)
 		resource_list_delete(&dinfo->resources, SYS_RES_IRQ, i + 1);
 
 	/* Update alloc count. */
-	cfg->msi.msi_alloc = 0;
+	msi->msi_alloc = 0;
 	return (0);
 }
 
@@ -1623,10 +1622,10 @@
 pci_msi_count_method(device_t dev, device_t child)
 {
 	struct pci_devinfo *dinfo = device_get_ivars(child);
-	pcicfgregs *cfg = &dinfo->cfg;
+	struct pcicfg_msi *msi = &dinfo->cfg.msi;
 
-	if (pci_do_msi && cfg->msi.msi_location != 0)
-		return (cfg->msi.msi_msgnum);
+	if (pci_do_msi && msi->msi_location != 0)
+		return (msi->msi_msgnum);
 	return (0);
 }
 


More information about the p4-projects mailing list