Пример #1
0
/*
 * called when the userspace process writes to the tty (/dev/noz*).
 * Data is inserted into a fifo, which is then read and transferred to the modem.
 */
static int ntty_write(struct tty_struct *tty, const unsigned char *buffer,
		      int count)
{
	int rval = -EINVAL;
	struct nozomi *dc = get_dc_by_tty(tty);
	struct port *port = tty->driver_data;
	unsigned long flags;

	/* DBG1( "WRITEx: %d, index = %d", count, index); */

	if (!dc || !port)
		return -ENODEV;

	rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count);

	spin_lock_irqsave(&dc->spin_mutex, flags);
	/* CTS is only valid on the modem channel */
	if (port == &(dc->port[PORT_MDM])) {
		if (port->ctrl_dl.CTS) {
			DBG4("Enable interrupt");
			enable_transmit_ul(tty->index % MAX_PORT, dc);
		} else {
			dev_err(&dc->pdev->dev,
				"CTS not active on modem port?\n");
		}
	} else {
		enable_transmit_ul(tty->index % MAX_PORT, dc);
	}
	spin_unlock_irqrestore(&dc->spin_mutex, flags);

	return rval;
}
Пример #2
0
/*
 * Return 1 - send buffer to card and ack.
 * Return 0 - don't ack, don't send buffer to card.
 */
static int send_data(enum port_type index, struct nozomi *dc)
{
	u32 size = 0;
	struct port *port = &dc->port[index];
	const u8 toggle = port->toggle_ul;
	void __iomem *addr = port->ul_addr[toggle];
	const u32 ul_size = port->ul_size[toggle];

	/* Get data from tty and place in buf for now */
	size = kfifo_out(&port->fifo_ul, dc->send_buf,
			   ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX);

	if (size == 0) {
		DBG4("No more data to send, disable link:");
		return 0;
	}

	/* DUMP(buf, size); */

	/* Write length + data */
	write_mem32(addr, (u32 *) &size, 4);
	write_mem32(addr + 4, (u32 *) dc->send_buf, size);

	tty_port_tty_wakeup(&port->port);

	return 1;
}
Пример #3
0
bool CMDKImplementation::Work(float *psamples, int numsamples, int const mode)
{
    DBG4("(%p,%d,%d), HaveInput=%d\n",psamples,numsamples,mode,HaveInput);
  
	if ((mode & WM_READ) && HaveInput)
		DSP_Copy(psamples, Buffer, numsamples);

	bool ret = pmi->MDKWork(psamples, numsamples, mode);

	InputIterator = Inputs.begin();
	HaveInput = 0;

	return ret;
}
Пример #4
0
bool BuzzMDKHelper::WorkMonoToStereo(float *pin, float *pout, int numsamples, int const wm) {
	DBG4("(pin=%p,pout=%p,numsamples=%d,wm=%d)\n",pin,pout,numsamples,wm);
/*
	if ((wm & WM_READ) && HaveInput)
	{
		Copy(pout, Buffer, 2*numsamples);
	}
	else
	{
		// shouldn't need to do this, but .. some Buzz machines are crap and need it
		Zero(pout, 2*numsamples);
	}

	bool bOutputValid = pmi->MDKWorkStereo(pout, numsamples, wm);

	InputIterator = Inputs.begin();
	HaveInput = 0;
	return bOutputValid;
*/
	return(true);
}
Пример #5
0
static irqreturn_t interrupt_handler(int irq, void *dev_id)
{
	struct nozomi *dc = dev_id;
	unsigned int a;
	u16 read_iir;

	if (!dc)
		return IRQ_NONE;

	spin_lock(&dc->spin_mutex);
	read_iir = readw(dc->reg_iir);

	/* Card removed */
	if (read_iir == (u16)-1)
		goto none;
	/*
	 * Just handle interrupt enabled in IER
	 * (by masking with dc->last_ier)
	 */
	read_iir &= dc->last_ier;

	if (read_iir == 0)
		goto none;


	DBG4("%s irq:0x%04X, prev:0x%04X", interrupt2str(read_iir), read_iir,
		dc->last_ier);

	if (read_iir & RESET) {
		if (unlikely(!nozomi_read_config_table(dc))) {
			dc->last_ier = 0x0;
			writew(dc->last_ier, dc->reg_ier);
			dev_err(&dc->pdev->dev, "Could not read status from "
				"card, we should disable interface\n");
		} else {
			writew(RESET, dc->reg_fcr);
		}
		/* No more useful info if this was the reset interrupt. */
		goto exit_handler;
	}
	if (read_iir & CTRL_UL) {
		DBG1("CTRL_UL");
		dc->last_ier &= ~CTRL_UL;
		writew(dc->last_ier, dc->reg_ier);
		if (send_flow_control(dc)) {
			writew(CTRL_UL, dc->reg_fcr);
			dc->last_ier = dc->last_ier | CTRL_UL;
			writew(dc->last_ier, dc->reg_ier);
		}
	}
	if (read_iir & CTRL_DL) {
		receive_flow_control(dc);
		writew(CTRL_DL, dc->reg_fcr);
	}
	if (read_iir & MDM_DL) {
		if (!handle_data_dl(dc, PORT_MDM,
				&(dc->port[PORT_MDM].toggle_dl), read_iir,
				MDM_DL1, MDM_DL2)) {
			dev_err(&dc->pdev->dev, "MDM_DL out of sync!\n");
			goto exit_handler;
		}
	}
	if (read_iir & MDM_UL) {
		if (!handle_data_ul(dc, PORT_MDM, read_iir)) {
			dev_err(&dc->pdev->dev, "MDM_UL out of sync!\n");
			goto exit_handler;
		}
	}
	if (read_iir & DIAG_DL) {
		if (!handle_data_dl(dc, PORT_DIAG,
				&(dc->port[PORT_DIAG].toggle_dl), read_iir,
				DIAG_DL1, DIAG_DL2)) {
			dev_err(&dc->pdev->dev, "DIAG_DL out of sync!\n");
			goto exit_handler;
		}
	}
	if (read_iir & DIAG_UL) {
		dc->last_ier &= ~DIAG_UL;
		writew(dc->last_ier, dc->reg_ier);
		if (send_data(PORT_DIAG, dc)) {
			writew(DIAG_UL, dc->reg_fcr);
			dc->last_ier = dc->last_ier | DIAG_UL;
			writew(dc->last_ier, dc->reg_ier);
		}
	}
	if (read_iir & APP1_DL) {
		if (receive_data(PORT_APP1, dc))
			writew(APP1_DL, dc->reg_fcr);
	}
	if (read_iir & APP1_UL) {
		dc->last_ier &= ~APP1_UL;
		writew(dc->last_ier, dc->reg_ier);
		if (send_data(PORT_APP1, dc)) {
			writew(APP1_UL, dc->reg_fcr);
			dc->last_ier = dc->last_ier | APP1_UL;
			writew(dc->last_ier, dc->reg_ier);
		}
	}
	if (read_iir & APP2_DL) {
		if (receive_data(PORT_APP2, dc))
			writew(APP2_DL, dc->reg_fcr);
	}
	if (read_iir & APP2_UL) {
		dc->last_ier &= ~APP2_UL;
		writew(dc->last_ier, dc->reg_ier);
		if (send_data(PORT_APP2, dc)) {
			writew(APP2_UL, dc->reg_fcr);
			dc->last_ier = dc->last_ier | APP2_UL;
			writew(dc->last_ier, dc->reg_ier);
		}
	}

exit_handler:
	spin_unlock(&dc->spin_mutex);

	for (a = 0; a < NOZOMI_MAX_PORTS; a++)
		if (test_and_clear_bit(a, &dc->flip))
			tty_flip_buffer_push(&dc->port[a].port);

	return IRQ_HANDLED;
none:
	spin_unlock(&dc->spin_mutex);
	return IRQ_NONE;
}
Пример #6
0
static int
acebus_apply_range(ebus_devstate_t *ebus_p, dev_info_t *rdip,
    ebus_regspec_t *ebus_rp, pci_regspec_t *rp)
{
	int b;
	int rval = DDI_SUCCESS;
	struct ebus_pci_rangespec *rangep = ebus_p->rangep;
	int nrange = ebus_p->range_cnt;
	static const char out_of_range[] =
	    "Out of range register specification from device node <%s>";

	DBG3(D_MAP, ebus_p, "Range Matching Addr 0x%x.%x size 0x%x\n",
	    ebus_rp->addr_hi, ebus_rp->addr_low, ebus_rp->size);

	for (b = 0; b < nrange; ++b, ++rangep) {

		/* Check for the correct space */
		if (ebus_rp->addr_hi == rangep->ebus_phys_hi)
			/* See if we fit in this range */
			if ((ebus_rp->addr_low >=
			    rangep->ebus_phys_low) &&
			    ((ebus_rp->addr_low + ebus_rp->size - 1)
			    <= (rangep->ebus_phys_low +
			    rangep->rng_size - 1))) {
				uint_t addr_offset = ebus_rp->addr_low -
				    rangep->ebus_phys_low;
				/*
				 * Use the range entry to translate
				 * the EBUS physical address into the
				 * parents PCI space.
				 */
				rp->pci_phys_hi =
				    rangep->pci_phys_hi;
				rp->pci_phys_mid = rangep->pci_phys_mid;
				rp->pci_phys_low =
				    rangep->pci_phys_low + addr_offset;
				rp->pci_size_hi = 0;
				rp->pci_size_low =
				    min(ebus_rp->size, (rangep->rng_size -
				    addr_offset));

				DBG2(D_MAP, ebus_p, "Child hi0x%x lo0x%x ",
				    rangep->ebus_phys_hi,
				    rangep->ebus_phys_low);
				DBG4(D_MAP, ebus_p, "Parent hi0x%x "
				    "mid0x%x lo0x%x size 0x%x\n",
				    rangep->pci_phys_hi,
				    rangep->pci_phys_mid,
				    rangep->pci_phys_low,
				    rangep->rng_size);

				break;
			}
	}

	if (b == nrange)  {
		cmn_err(CE_WARN, out_of_range, ddi_get_name(rdip));
		return (DDI_ME_REGSPEC_RANGE);
	}

	return (rval);
}
Пример #7
0
/*
 * bus map entry point:
 *
 * 	if map request is for an rnumber
 *		get the corresponding regspec from device node
 * 	build a new regspec in our parent's format
 *	build a new map_req with the new regspec
 *	call up the tree to complete the mapping
 */
static int
acebus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
	off_t off, off_t len, caddr_t *addrp)
{
	ebus_devstate_t *ebus_p = get_acebus_soft_state(ddi_get_instance(dip));
	ebus_regspec_t *ebus_rp, *ebus_regs;
	pci_regspec_t pci_reg;
	ddi_map_req_t p_map_request;
	int rnumber, i, n;
	int rval = DDI_SUCCESS;

	/*
	 * Handle the mapping according to its type.
	 */
	DBG4(D_MAP, ebus_p, "rdip=%s%d: off=%x len=%x\n",
	    ddi_get_name(rdip), ddi_get_instance(rdip), off, len);
	switch (mp->map_type) {
	case DDI_MT_REGSPEC:

		/*
		 * We assume the register specification is in ebus format.
		 * We must convert it into a PCI format regspec and pass
		 * the request to our parent.
		 */
		DBG3(D_MAP, ebus_p, "rdip=%s%d: REGSPEC - handlep=%x\n",
		    ddi_get_name(rdip), ddi_get_instance(rdip),
		    mp->map_handlep);
		ebus_rp = (ebus_regspec_t *)mp->map_obj.rp;
		break;

	case DDI_MT_RNUMBER:

		/*
		 * Get the "reg" property from the device node and convert
		 * it to our parent's format.
		 */
		rnumber = mp->map_obj.rnumber;
		DBG4(D_MAP, ebus_p, "rdip=%s%d: rnumber=%x handlep=%x\n",
		    ddi_get_name(rdip), ddi_get_instance(rdip),
		    rnumber, mp->map_handlep);

		if (getprop(rdip, "reg", &ebus_regs, &i) != DDI_SUCCESS) {
			DBG(D_MAP, ebus_p, "can't get reg property\n");
			return (DDI_ME_RNUMBER_RANGE);
		}
		n = i / sizeof (ebus_regspec_t);

		if (rnumber < 0 || rnumber >= n) {
			DBG(D_MAP, ebus_p, "rnumber out of range\n");
			return (DDI_ME_RNUMBER_RANGE);
		}
		ebus_rp = &ebus_regs[rnumber];
		break;

	default:
		return (DDI_ME_INVAL);

	}

	/* Adjust our reg property with offset and length */
	ebus_rp->addr_low += off;
	if (len)
		ebus_rp->size = len;

	/*
	 * Now we have a copy the "reg" entry we're attempting to map.
	 * Translate this into our parents PCI address using the ranges
	 * property.
	 */
	rval = acebus_apply_range(ebus_p, rdip, ebus_rp, &pci_reg);

	if (mp->map_type == DDI_MT_RNUMBER)
		kmem_free((caddr_t)ebus_regs, i);

	if (rval != DDI_SUCCESS)
		return (rval);

#ifdef	ACEBUS_HOTPLUG
	/*
	 * The map operation provides a translated (not a re-assigned, or
	 * relocated) ebus address for the child in its address space(range).
	 * Ebus address space is relocatible but its child address space
	 * is not. As specified by their 'reg' properties, they reside
	 * at a fixed offset in their parent's (ebus's) space.
	 *
	 * By setting this bit, we will not run into HostPCI nexus
	 * trying to relocate a translated ebus address (which is already
	 * relocated) and failing the operation.
	 * The reason for doing this here is that the PCI hotplug configurator
	 * always marks the ebus space as relocatible (unlike OBP) and that
	 * information is implied for the child too, which is wrong.
	 */
	pci_reg.pci_phys_hi |= PCI_RELOCAT_B;
#endif
#ifdef DEBUG
	DBG5(D_MAP, ebus_p, "(%x,%x,%x)(%x,%x)\n",
	    pci_reg.pci_phys_hi,
	    pci_reg.pci_phys_mid,
	    pci_reg.pci_phys_low,
	    pci_reg.pci_size_hi,
	    pci_reg.pci_size_low);
#endif

	p_map_request = *mp;
	p_map_request.map_type = DDI_MT_REGSPEC;
	p_map_request.map_obj.rp = (struct regspec *)&pci_reg;
	rval = ddi_map(dip, &p_map_request, 0, 0, addrp);
	DBG1(D_MAP, ebus_p, "parent returned %x\n", rval);
	return (rval);
}
Пример #8
0
/**
 * create a symmetrically encrypted pkcs7 contentInfo object
 */
chunk_t pkcs7_build_envelopedData(chunk_t data, certificate_t *cert, int enc_alg)
{
	encryption_algorithm_t alg;
	size_t alg_key_size;
	chunk_t symmetricKey, protectedKey, iv, in, out;
	crypter_t *crypter;

	alg = encryption_algorithm_from_oid(enc_alg, &alg_key_size);
	crypter = lib->crypto->create_crypter(lib->crypto, alg,
										  alg_key_size/BITS_PER_BYTE);
	if (crypter == NULL)
	{
		DBG1(DBG_LIB, "crypter for %N not available", encryption_algorithm_names, alg);
		return chunk_empty;
	}

	/* generate a true random symmetric encryption key and a pseudo-random iv */
	{
		rng_t *rng;

		rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
		rng->allocate_bytes(rng, crypter->get_key_size(crypter), &symmetricKey);
		DBG4(DBG_LIB, "symmetric encryption key %B", &symmetricKey);
		rng->destroy(rng);

		rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
		rng->allocate_bytes(rng, crypter->get_iv_size(crypter), &iv);
		DBG4(DBG_LIB, "initialization vector: %B", &iv);
		rng->destroy(rng);
	}

	/* pad the data to a multiple of the block size */
	{
		size_t block_size = crypter->get_block_size(crypter);
		size_t padding = block_size - data.len % block_size;

		in.len = data.len + padding;
		in.ptr = malloc(in.len);

		DBG2(DBG_LIB, "padding %u bytes of data to multiple block size of %u bytes",
			 data.len, in.len);

		/* copy data */
		memcpy(in.ptr, data.ptr, data.len);
		/* append padding */
		memset(in.ptr + data.len, padding, padding);
	}
	DBG3(DBG_LIB, "padded unencrypted data %B", &in);

	/* symmetric encryption of data object */
	crypter->set_key(crypter, symmetricKey);
	crypter->encrypt(crypter, in, iv, &out);
	crypter->destroy(crypter);
	chunk_clear(&in);
    DBG3(DBG_LIB, "encrypted data %B", &out);

	/* protect symmetric key by public key encryption */
	{
		public_key_t *key = cert->get_public_key(cert);

		if (key == NULL)
		{
			DBG1(DBG_LIB, "public key not found in encryption certificate");
			chunk_clear(&symmetricKey);
			chunk_free(&iv);
			chunk_free(&out);
			return chunk_empty;
		}
		key->encrypt(key, ENCRYPT_RSA_PKCS1, symmetricKey, &protectedKey);
		key->destroy(key);
	}

	/* build pkcs7 enveloped data object */
	{

		chunk_t contentEncryptionAlgorithm = asn1_wrap(ASN1_SEQUENCE, "mm"
					, asn1_build_known_oid(enc_alg)
					, asn1_simple_object(ASN1_OCTET_STRING, iv));

		chunk_t encryptedContentInfo = asn1_wrap(ASN1_SEQUENCE, "mmm"
					, asn1_build_known_oid(OID_PKCS7_DATA)
					, contentEncryptionAlgorithm
					, asn1_wrap(ASN1_CONTEXT_S_0, "m", out));

		chunk_t encryptedKey = asn1_wrap(ASN1_OCTET_STRING, "m"
					, protectedKey);

		chunk_t recipientInfo = asn1_wrap(ASN1_SEQUENCE, "cmmm"
					, ASN1_INTEGER_0
					, pkcs7_build_issuerAndSerialNumber(cert)
					, asn1_algorithmIdentifier(OID_RSA_ENCRYPTION)
					, encryptedKey);

		chunk_t cInfo;
		contentInfo_t envelopedData;

		envelopedData.type = OID_PKCS7_ENVELOPED_DATA;
		envelopedData.content = asn1_wrap(ASN1_SEQUENCE, "cmm"
					, ASN1_INTEGER_0
					, asn1_wrap(ASN1_SET, "m", recipientInfo)
					, encryptedContentInfo);

		cInfo = pkcs7_build_contentInfo(&envelopedData);
		DBG3(DBG_LIB, "envelopedData %B", &cInfo);

		chunk_free(&envelopedData.content);
		chunk_free(&iv);
		chunk_clear(&symmetricKey);
		return cInfo;
	}
}
Пример #9
0
/**
 * Parse a PKCS#7 envelopedData object
 */
bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data,
							   chunk_t serialNumber,
							   private_key_t *key)
{
	asn1_parser_t *parser;
	chunk_t object;
	chunk_t iv                = chunk_empty;
	chunk_t symmetric_key     = chunk_empty;
	chunk_t encrypted_content = chunk_empty;

	crypter_t *crypter = NULL;

	int enc_alg         = OID_UNKNOWN;
	int content_enc_alg = OID_UNKNOWN;
	int version;
	int objectID;
	bool success = FALSE;

	contentInfo_t cInfo = empty_contentInfo;
	*data = chunk_empty;

	if (!pkcs7_parse_contentInfo(blob, 0, &cInfo))
	{
		goto failed;
	}
	if (cInfo.type != OID_PKCS7_ENVELOPED_DATA)
	{
		DBG1(DBG_LIB, "pkcs7 content type is not envelopedData");
		goto failed;
	}

	parser = asn1_parser_create(envelopedDataObjects, cInfo.content);
	parser->set_top_level(parser, 2);

	while (parser->iterate(parser, &objectID, &object))
	{
		u_int level = parser->get_level(parser);

		switch (objectID)
		{
		case PKCS7_ENVELOPED_VERSION:
			version = object.len ? (int)*object.ptr : 0;
			DBG2(DBG_LIB, "  v%d", version);
			if (version != 0)
			{
				DBG1(DBG_LIB, "envelopedData version is not 0");
				goto end;
			}
			break;
		case PKCS7_RECIPIENT_INFO_VERSION:
			version = object.len ? (int)*object.ptr : 0;
			DBG2(DBG_LIB, "  v%d", version);
			if (version != 0)
			{
				DBG1(DBG_LIB, "recipient info version is not 0");
				goto end;
			}
			break;
		case PKCS7_ISSUER:
			{
				identification_t *issuer = identification_create_from_encoding(
													ID_DER_ASN1_DN, object);
				DBG2(DBG_LIB, "  \"%Y\"", issuer);
				issuer->destroy(issuer);
				break;
			}
		case PKCS7_SERIAL_NUMBER:
			if (!chunk_equals(serialNumber, object))
			{
				DBG1(DBG_LIB, "serial numbers do not match");
				goto end;
			}
			break;
		case PKCS7_ENCRYPTION_ALG:
			enc_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
			if (enc_alg != OID_RSA_ENCRYPTION)
			{
				DBG1(DBG_LIB, "only rsa encryption supported");
				goto end;
			}
			break;
		case PKCS7_ENCRYPTED_KEY:
			if (!key->decrypt(key, ENCRYPT_RSA_PKCS1, object, &symmetric_key))
			{
				DBG1(DBG_LIB, "symmetric key could not be decrypted with rsa");
				goto end;
			}
			DBG4(DBG_LIB, "symmetric key %B", &symmetric_key);
			break;
		case PKCS7_CONTENT_TYPE:
			if (asn1_known_oid(object) != OID_PKCS7_DATA)
			{
				 DBG1(DBG_LIB, "encrypted content not of type pkcs7 data");
				 goto end;
			}
			break;
		case PKCS7_CONTENT_ENC_ALGORITHM:
			content_enc_alg = asn1_parse_algorithmIdentifier(object, level, &iv);

			if (content_enc_alg == OID_UNKNOWN)
			{
				DBG1(DBG_LIB, "unknown content encryption algorithm");
				goto end;
			}
			if (!asn1_parse_simple_object(&iv, ASN1_OCTET_STRING, level+1, "IV"))
			{
				DBG1(DBG_LIB, "IV could not be parsed");
				goto end;
			}
			break;
		case PKCS7_ENCRYPTED_CONTENT:
			encrypted_content = object;
			break;
		}
	}
	success = parser->success(parser);

end:
	parser->destroy(parser);
	if (!success)
	{
		goto failed;
	}
	success = FALSE;

	/* decrypt the content */
	{
		encryption_algorithm_t alg;
		size_t key_size;
		crypter_t *crypter;

		alg = encryption_algorithm_from_oid(content_enc_alg, &key_size);
		if (alg == ENCR_UNDEFINED)
		{
			DBG1(DBG_LIB, "unsupported content encryption algorithm");
			goto failed;
		}
		crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size);
		if (crypter == NULL)
		{
			DBG1(DBG_LIB, "crypter %N not available", encryption_algorithm_names, alg);
			goto failed;
		}
		if (symmetric_key.len != crypter->get_key_size(crypter))
		{
			DBG1(DBG_LIB, "symmetric key length %d is wrong", symmetric_key.len);
			goto failed;
		}
		if (iv.len != crypter->get_iv_size(crypter))
		{
			DBG1(DBG_LIB, "IV length %d is wrong", iv.len);
			goto failed;
		}
		crypter->set_key(crypter, symmetric_key);
		crypter->decrypt(crypter, encrypted_content, iv, data);
		DBG4(DBG_LIB, "decrypted content with padding: %B", data);
	}

	/* remove the padding */
	{
		u_char *pos = data->ptr + data->len - 1;
		u_char pattern = *pos;
		size_t padding = pattern;

		if (padding > data->len)
		{
			DBG1(DBG_LIB, "padding greater than data length");
			goto failed;
		}
		data->len -= padding;

		while (padding-- > 0)
		{
			if (*pos-- != pattern)
			{
				DBG1(DBG_LIB, "wrong padding pattern");
				goto failed;
			}
		}
	}
	success = TRUE;

failed:
	DESTROY_IF(crypter);
	chunk_clear(&symmetric_key);
	if (!success)
	{
		free(data->ptr);
	}
	return success;
}
Пример #10
0
int IMPI_Gateway_export(int *src_comm_lrank, int *dest_grank, int *tag, size_t *length, void **buffer)
{
  int gateway_flag = 0;

  int i;
  int iprobe_flag;
  size_t recv_msgcount;

  static int  my_comm_host_rank;
  static int  send_context;
  static int  procs_on_metahost;
  static int   *meta_header_sent;
  static char  *router_msg[1];
  static size_t router_msg_size[1];
  static size_t *meta_msg_i_size;
  static Meta_Header **meta_msg_i;

  static MPI_Status recv_status;
  struct MPIR_COMMUNICATOR *comm_host_ptr;

  static int firstcall=1;

  if(firstcall)
  {
    /* set up buffers */
    router_msg_size[0] = INIT_ROUTER_BUFFER_SIZE;
    router_msg[0] = (char *)malloc( INIT_ROUTER_BUFFER_SIZE * sizeof(char));
    if( router_msg[0]==NULL ) exit(-1);
    
    comm_host_ptr = MPIR_GET_COMM_PTR( MPI_COMM_HOST );
    my_comm_host_rank = comm_host_ptr->local_rank;
    send_context = comm_host_ptr->send_context;
    
    procs_on_metahost = 3;
    
    meta_msg_i = (Meta_Header **) malloc( procs_on_metahost * sizeof( Meta_Header * ) );
    meta_msg_i_size = (int *) malloc( procs_on_metahost * sizeof( int ) );
    meta_header_sent = (int *) malloc( procs_on_metahost * sizeof( int ) );

    for( i = 0; i < procs_on_metahost; i++ )
    {
      if( !(MPIR_meta_cfg.isRouter[i]) )
      {
	meta_msg_i[i] = (Meta_Header *) malloc( INIT_ROUTER_BUFFER_SIZE * sizeof(char) );
	meta_msg_i_size[i] = INIT_ROUTER_BUFFER_SIZE * sizeof(char);
	meta_header_sent[i] = 0;
      }
    }
    
    firstcall = 0;

    DBG("Check_gateway --> first call");
  } 
  
  /* receive messages from the mpi-processes of the localhost 
     and route them to the according host */
  
  MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_HOST, &iprobe_flag, &recv_status);
  DBG2("Iprobe is %d / Sender is %d", iprobe_flag, recv_status.MPI_SOURCE);
    
  if (!iprobe_flag)
  {
    /* No gateway message available...*/
    return 0;
  } 
  else 
  {
    if(buffer==NULL) return 1; /* <-- this is just a check-gateway call */

    /* get the size of the message to be received */
    MPI_Get_count(&recv_status, MPI_BYTE, &recv_msgcount);

    if( (recv_status.MPI_TAG == MPIR_SEPARATE_MSG_TAG) && (meta_header_sent[recv_status.MPI_SOURCE]) )
    {
      DBG2("SEPARATE_MSG_TAG %d %d",recv_msgcount,recv_msgcount-sizeof(Meta_Header));
      /* a meta header was sent and this is the message belonging to that header */
      meta_msg_i[recv_status.MPI_SOURCE] = (Meta_Header * )IMPI_adjustbuffer( (char *)(meta_msg_i[recv_status.MPI_SOURCE]),
									      meta_msg_i_size[recv_status.MPI_SOURCE],
									      recv_msgcount + sizeof( Meta_Header ) );
      if ( meta_msg_i_size[recv_status.MPI_SOURCE] < recv_msgcount + sizeof( Meta_Header ) )
	meta_msg_i_size[recv_status.MPI_SOURCE] = recv_msgcount + sizeof( Meta_Header );
    }      
    else
    {
      DBG2("No SEPARATE_MSG_TAG %d %d",recv_msgcount,recv_msgcount-sizeof(Meta_Header));
      router_msg[0] = IMPI_adjustbuffer(router_msg[0], router_msg_size[0], recv_msgcount);
      if( router_msg_size[0] < recv_msgcount ) router_msg_size[0] = recv_msgcount;
    }
    
    if( (recv_status.MPI_TAG == MPIR_SEPARATE_MSG_TAG) && (meta_header_sent[recv_status.MPI_SOURCE]) ) {
      
      /* we receive this message in the buffer for the sender process, directly after the meta header */
      MPI_Recv( meta_msg_i[recv_status.MPI_SOURCE] + 1, recv_msgcount, MPI_BYTE,
		recv_status.MPI_SOURCE, MPI_ANY_TAG, MPI_COMM_HOST, &recv_status);
      DBG("Local message received");
    }
    else {
      DBG2("Going to recv the router message (%d) from %d", recv_msgcount, recv_status.MPI_SOURCE);
      MPI_Recv(router_msg[0], recv_msgcount, MPI_BYTE, recv_status.MPI_SOURCE, MPI_ANY_TAG, MPI_COMM_HOST, &recv_status);
      DBG("Router message received");
    }
    
    
    /* check type of message - command message or MPI message ? */
    switch (recv_status.MPI_TAG)
    {
      case MPIR_SEPARATE_MSG_TAG:
      {
	DBG("MPIR_SEPARATE_MSG_TAG");

	/* 
	 |  IMPI: this connection mapping would correspond to the IMPI host mapping, but currently we
	 |  maintain only one IMPI host per IMPI client!
	 */
//      conn = get_conn_for_dest( meta_msg_i[recv_status.MPI_SOURCE]->msg.MPI.dest_grank );
		 
	DBG4("Gateway-msg for [a%d] from [m%d], tag %d, MPI size %d",
	     meta_msg_i[recv_status.MPI_SOURCE]->msg.MPI.dest_grank,
	     meta_msg_i[recv_status.MPI_SOURCE]->msg.MPI.src_comm_lrank,
	     meta_msg_i[recv_status.MPI_SOURCE]->msg.MPI.tag,
	     meta_msg_i[recv_status.MPI_SOURCE]->msg.MPI.count );

	*(dest_grank)     = meta_msg_i[recv_status.MPI_SOURCE]->msg.MPI.dest_grank;
	*(src_comm_lrank) = meta_msg_i[recv_status.MPI_SOURCE]->msg.MPI.src_comm_lrank;
	*(tag)            = meta_msg_i[recv_status.MPI_SOURCE]->msg.MPI.tag;
	*(length)         = meta_msg_i[recv_status.MPI_SOURCE]->msg.MPI.count;
	*(buffer)         = (void*)(meta_msg_i[recv_status.MPI_SOURCE] + 1);

	gateway_flag = 1;
	meta_header_sent[recv_status.MPI_SOURCE] = 0;
	
	break;
      }
		
      case MPIR_SEPARATE_META_HEADER_TAG:
      {
	DBG("MPIR_SEPARATE_META_HEADER_TAG");
	/*
	 | this is a short message containing the meta data for a nonblocking msg
	 | that comes later on, therefore we must save the data here 
	 */
	DBG2("memcpy (%d) in buffer of %d", recv_msgcount, recv_status.MPI_SOURCE);
	memcpy( meta_msg_i[recv_status.MPI_SOURCE], router_msg[0], recv_msgcount );
	meta_header_sent[recv_status.MPI_SOURCE] = 1;
	DBG("Header stored");

	break;
      }
		 
      case MPIR_ROUTMSG_TAG:
      {
	DBG("MPIR_ROUTMSG_TAG");
	switch (((Meta_Header *)router_msg[0])->msg.Rout.command) {
	  case FINALIZE:
	  {
	    break;
	  }
	  default:
	  {
	    /* ERROR: got router message with wrong command */
	    break;
	  }
	}
	break;
      }
		 
      default:
      {
        /* ERROR: got message with wrong tag */
      }
    }
  } /* if (!iprobe_flag) ... */ 
    
  DBG1("Leaving Check_gateway with %d", gateway_flag);

  return gateway_flag;
}
Пример #11
0
int IMPI_Tunnel_import(int src_comm_lrank, int dest_grank, int tag, size_t length, void **buffer, int get_buffer_flag)
{
  int i;

  static Meta_Header **meta_msg_i;
  static size_t *meta_msg_i_size;
  static int *meta_header_sent;
  
  static MPI_Status  *snd_status;
  static MPI_Request *snd_request;
    
  static IntQueue *availQ;
  static IntQueue *pendingQ;

  static IntQueue _availQ;
  static IntQueue _pendingQ;

  static size_t size;
  static int req_id;

  static char   **router_msg;
  static size_t *bufsize;
  static int    flag;

  static int procs_on_metahost = 3;

  static int firstcall=1;

  DBG("This is IMPI_Import_msgs");

  if(firstcall)
  {
    
    /* !!! This must be determined !!!*/
    procs_on_metahost = 3;

    meta_msg_i = (Meta_Header **) malloc( procs_on_metahost * sizeof( Meta_Header * ) );
    meta_msg_i_size = (int *) malloc( procs_on_metahost * sizeof( int ) );
    meta_header_sent = (int *) malloc( procs_on_metahost * sizeof( int ) );

    DBG("Import_msgs: meta_msg buffers allocated");
    
    for( i = 0; i < procs_on_metahost; i++ )
    {
      if( !(MPIR_meta_cfg.isRouter[i]) )
      {
	meta_msg_i[i] = (Meta_Header *) malloc( INIT_ROUTER_BUFFER_SIZE * sizeof(char) );
	meta_msg_i_size[i] = INIT_ROUTER_BUFFER_SIZE * sizeof(char);
	meta_header_sent[i] = 0;
      }
    }

    snd_status  = (MPI_Status *) malloc (MPIR_RouterConfig.isend_num * sizeof (MPI_Status));
    snd_request = (MPI_Request *) malloc (MPIR_RouterConfig.isend_num * sizeof (MPI_Request));
      
    Qinit (&_availQ, MPIR_RouterConfig.isend_num, 1);
    Qinit (&_pendingQ, MPIR_RouterConfig.isend_num, 0);

    availQ = &_availQ;
    pendingQ = &_pendingQ;

    if( !(router_msg = (char **)malloc( MPIR_RouterConfig.isend_num * sizeof(char *))) ) {
      PRERROR( "Could not allocate enough local memory" );
      ROUTER_ABORT;
    }	
    bufsize = (int *)malloc( MPIR_RouterConfig.isend_num * sizeof(int) );
    for (i = 0; i < MPIR_RouterConfig.isend_num; i++) {
      if( !( router_msg[i]  = (char *)malloc( INIT_ROUTER_BUFFER_SIZE * sizeof(char))) ) {
	PRERROR( "Could not allocate enough local memory" );
	ROUTER_ABORT;
      }
      bufsize[i]   = INIT_ROUTER_BUFFER_SIZE;
    }
    
    DBG("Import_msgs: router_msg buffer allocated");
    
    firstcall = 0;

    DBG("Import_msg --> first call");
  }

  /* size of the meta packet to be tunneld: */
  size = length + sizeof(Meta_Header);

  if(get_buffer_flag)
  {
    DBG("This is a 'get_buffer' call to IMPI_Send_tunnel");

    /* before we get req_id for this transaction (id of buffer to be used), we must make shure that
       not all buffers are full; if this is the case, we block until at least one buffer is available */
    while (Qfull (pendingQ))
    {
      for (i = Qfirst(pendingQ); i >= 0; i = Qnext(pendingQ))
      {	
	MPI_Test(&snd_request[i], &flag, &snd_status[i]);
	
	if (flag)
	{
	  /* message has been sent */
	  Qput (availQ, i);
	  Qremove (pendingQ, i);
	}
      }
    }

    /* get id for this transaction */
    req_id = Qget (availQ);
    Qput (pendingQ, req_id);
  
    router_msg[req_id] = IMPI_adjustbuffer (router_msg[req_id], bufsize[req_id], size);
    if( bufsize[req_id] < size )  bufsize[req_id] = size;
  
    *buffer = (Meta_Header *)router_msg[req_id]+1;

    DBG("Leaving Send_tunnel");
    return 0;
  }
  else
  {     
    DBG("This is a 'send_call' to IMPI_Send_tunnel");

    /*
     |   This is a Send_Call!
     */
    int dest = dest_grank;
    struct MPIR_COMMUNICATOR *comm_ptr;
    struct MPIR_DATATYPE     *dtype_ptr;
    MPIR_SHANDLE             *shandle;
    static char myname[] = "MPI_ISSEND";
    int mpi_errno = MPI_SUCCESS;
    int my_all_rank, my_all_size;

    /* Create MetaHeader: */
    memset((Meta_Header *)router_msg[req_id], 0, sizeof(Meta_Header));
    ((Meta_Header *)router_msg[req_id])->msg.MPI.dest_grank     = dest;
    ((Meta_Header *)router_msg[req_id])->msg.MPI.src_comm_lrank = src_comm_lrank;
    ((Meta_Header *)router_msg[req_id])->msg.MPI.tag            = tag;
    ((Meta_Header *)router_msg[req_id])->msg.MPI.count          = length;
    ((Meta_Header *)router_msg[req_id])->msg.MPI.msgrep         = 1;
    
#if 0
    /* even more to fake ??? */
    typedef struct _GW_MPI_msg {
      int src_comm_lrank;
      int dest_grank;
      int tag;         
      int context_id;
      MPI_Sendmode mode;
      unsigned int count;            /* byte-size of the original msg (appended to this struct) */
      int msgrep;      
      unsigned int msgid;                 /* id for cancelling */
    } GW_MPI_msg;
    
    typedef struct _Meta_Header {
      MPIR_GW_mode mode;
      union {
	GW_MPI_msg     MPI;
	GW_Router_msg  Rout;
      } msg;
      unsigned char dummychar;
    } Meta_Header;

#endif
    
    DBG4("Gateway-msg for [a%d] from [m%d], tag %d, MPI size %d",
	 ((Meta_Header *)router_msg[req_id])->msg.MPI.dest_grank,
	 ((Meta_Header *)router_msg[req_id])->msg.MPI.src_comm_lrank,
	 ((Meta_Header *)router_msg[req_id])->msg.MPI.tag,
	 ((Meta_Header *)router_msg[req_id])->msg.MPI.count);
    
    TR_PUSH(myname);
      
    MPI_Comm_rank(MPI_COMM_ALL, &my_all_rank);
    MPI_Comm_size(MPI_COMM_ALL, &my_all_size);
      
    comm_ptr = MPIR_GET_COMM_PTR(MPI_COMM_ALL);	  
    dtype_ptr = MPIR_GET_DTYPE_PTR(MPI_BYTE);

    MPIR_ALLOCFN(shandle, MPID_Send_alloc, comm_ptr, MPI_ERR_EXHAUSTED, myname);
      
    snd_request[req_id] = (MPI_Request)shandle;
    MPID_Request_init( (MPI_Request)shandle, MPIR_SEND );
	  
    /* we need the rank of dest in MPI_COMM_ALL in MPID_Gateway_SendCancelPacket(),
       so we save it here */
    shandle->partner_grank = comm_ptr->lrank_to_grank[dest];
      
    MPIR_REMEMBER_SEND( shandle, router_msg[req_id], size, MPI_BYTE, dest, MPIR_MPIMSG_TAG, comm_ptr);
      
    if (dest == MPI_PROC_NULL)
    {
      shandle->is_complete = 1;
    }
    else
    {
      DBG("Going to tunnel the msg..");
      MPID_IsendDatatype( comm_ptr, router_msg[req_id], size, dtype_ptr, 
			  comm_ptr->local_rank, MPIR_MPIMSG_TAG, 
			  comm_ptr->send_context, 
			  comm_ptr->lrank_to_grank[dest], 
			  snd_request[req_id], &mpi_errno, 0 );
      DBG("Msg tunneld!");
    }
  }

  /* wait for completion of pending sends */
  DBG("Waiting for pending sends...");
  if (!Qempty(pendingQ))
  {
    for (i = Qfirst(pendingQ); i >= 0; i = Qnext(pendingQ))
    {
      MPI_Test(&snd_request[i], &flag, &snd_status[i]);
      if (flag)
      {
	/* message has been sent */
	Qput (availQ, i);
	Qremove (pendingQ, i);
      }
    }
  }

  DBG("Leaving Send_tunnel");
  return 0;
}
Пример #12
0
void PdParamGetter::getFromPdCanvas(t_canvas * x,int guiIdx) {
    {

        Rectangle<int> patchRect = guiSizes[guiIdx];
        //        Rectangle<int> region( x->gl_xmargin,x->gl_ymargin,x->gl_xmargin+ x->gl_pixwidth, x->gl_ymargin + x->gl_pixheight);//guiSizes[guiIdx];



        t_gobj * y = x->gl_list;
        for(t_gobj * y2 = y ; y2 ; y2 = y2->g_next) {


            PulpParameterDesc * p = new PulpParameterDesc ;
            p->guiNum = guiIdx;
            p->elements.clear();

            String objName = y2->g_pd->c_name->s_name;
//            DBG(objName);
            int split = objName.indexOfWholeWord("/");
            if(split>0) {
                objName = objName.substring(split, objName.length() - split);
//                DBG(objName);
            }
            bool found = true;
            if(objName=="canvas" ) {
                _glist * gl;
                if((gl = pd_checkglist(&y2->g_pd))) {
                    if(gl->gl_isgraph) {
                        //                        DBGN(gl->gl_env->ce_dir->s_name)
                        //                        DBG2("/",gl->gl_list);
                        getFromPdCanvas(gl, guiIdx);
                    }
                }
                found = false;
            }
            else if(y2->g_pd->c_gobj) {
                if(objName== "hsl") {
                    p->type = PulpParameterDesc::HSL;
                    t_hslider *hsl = (t_hslider *)y2;
                    found = fillIemObj(&hsl->x_gui,y2, p);
                    p->min = hsl->x_min;
                    p->max = hsl->x_max;
                    if(hsl->x_gui.x_isa.x_loadinit) {
                        p->defaultV = (hsl->x_val/100)*hsl->x_k + p->min;
                    }
                }
                else if(objName=="vsl") {
                    p->type = PulpParameterDesc::VSL;
                    t_vslider *vsl = (t_vslider *)y2;
                    found = fillIemObj(&vsl->x_gui,y2, p);
                    p->min = vsl->x_min;
                    p->max = vsl->x_max;
                    if(vsl->x_gui.x_isa.x_loadinit) {
                        p->defaultV = (vsl->x_val/100)*vsl->x_k + p->min;
                    }
                }

                else if(objName== "tgl") {
                    p->type = PulpParameterDesc::TOGGLE;
                    t_toggle *tgl = (t_toggle *)y2;
                    found = fillIemObj(&tgl->x_gui,y2, p);
                    p->min = 0;
                    p->max = 1;
                }
                else if(objName== "bng") {
                    p->type = PulpParameterDesc::BANG;
                    t_bng *tgl = (t_bng *)y2;
                    found = fillIemObj(&tgl->x_gui,y2, p);
                    p->min = 0;
                    p->max = 1;
                }
                else if(objName== "vradio") {
                    p->type = PulpParameterDesc::VRADIO;
                    t_vradio *tgl = (t_vradio *)y2;
                    found = fillIemObj(&tgl->x_gui,y2, p);
                    p->min = 0;
                    p->max = tgl->x_number-1;
                    for(int i = 0 ; i < tgl->x_number ; i++) {
                        p->elements.add(String(i));
                    }
                }
                else if(objName== "hradio") {
                    p->type = PulpParameterDesc::HRADIO;
                    t_hradio *tgl = (t_hradio *)y2;
                    found = fillIemObj(&tgl->x_gui,y2, p);
                    p->min = 0;
                    p->max = tgl->x_number-1;
                    for(int i = 0 ; i < tgl->x_number ; i++) {
                        p->elements.add(String(i));
                    }
                }
                else if(objName== "cnv") {
                    p->type = PulpParameterDesc::CNV;
                    t_my_canvas * cnv = (t_my_canvas*) y2;
                    found = fillIemObj(&cnv->x_gui,y2, p);
                    p->setSize(cnv->x_vis_w, cnv->x_vis_h);

                }
                else if(objName== "popup") {
                    p->type = PulpParameterDesc::POPUP;
                    t_popup * popup = (t_popup *) y2;
                    int x01,y01,x02,y02;
                    gobj_getrect(&popup->x_obj.te_g, x,&x01,&y01,&x02,&y02);
                    p->sendName = popup->x_name->s_name;
                    p->setBounds(  x01,y01,x02-x01,y02-y01);
                    DBG4(x01,y01,x02 ,y02);
                    found = true;
                    //                    found = fillIemObj(;,y2, p);
                    p->setSize(popup->x_width, popup->x_height);

                    for(int i =0 ; i < popup->x_num_options ; i++) {
                        p->elements.add(popup->x_options[i]->s_name);
                    }
                    p->min = 0;
                    p->max =p->elements.size()-1;

                }
                else if(strcmp(y2->g_pd->c_name->s_name, "knob")==0) {
                    p->type = PulpParameterDesc::KNOB;
                    t_knob *knob = (t_knob *)y2;
                    found = fillIemObj(&knob->x_gui,y2, p);
                    p->min = knob->x_min;
                    p->max = knob->x_max;
                }

                else {
//                    DBG("not found " <<objName);
                    found = false;
                }
            }
            if(found ) {
                p->isAudioParameter = p->sendName.startsWith("param");
                p->setBounds((p->getX() )/patchRect.getWidth(),
                             (p->getY() )/patchRect.getHeight(),
                             p->getWidth()/patchRect.getWidth(),
                             p->getHeight()/patchRect.getHeight());
                p->labelRect.setBounds((p->labelRect.getX())/patchRect.getWidth(),
                                       (p->labelRect.getY())/patchRect.getHeight(),
                                       p->labelRect.getWidth()/patchRect.getWidth(),
                                       p->labelRect.getHeight()/patchRect.getHeight());
                p->sendName = resolveDollarzero(p->sendName);
                p->recieveName = resolveDollarzero(p->recieveName);
//                DBGN(y2->g_pd->c_name->s_name << " : ")
//                DBG("adding p " << p->sendName << "/" << p->recieveName <<  " at "<< ((Rectangle<float>)*p).toString());

                if(p->isAudioParameter) {
                    p->processorIdx = localParamCount;
                    localParamCount++;
                }
                else {
                    p->processorIdx = -1;
                }
                p->pdObjectIdx = localObjectCount;
                localObjectCount++;
                pulpParameterDescs.add(p);

            }

            else {

                delete p;

            }



        }
    }

}