Ejemplo n.º 1
0
static int rpmsg_recv_single(struct virtproc_info *vrp, struct device *dev,
			     struct rpmsg_hdr *msg, unsigned int len)
{
	struct rpmsg_endpoint *ept;
	struct scatterlist sg;
	int err;

	dev_dbg(dev, "From: 0x%x, To: 0x%x, Len: %d, Flags: %d, Reserved: %d\n",
					msg->src, msg->dst, msg->len,
					msg->flags, msg->reserved);
	print_hex_dump(KERN_DEBUG, "rpmsg_virtio RX: ", DUMP_PREFIX_NONE, 16, 1,
					msg, sizeof(*msg) + msg->len, true);

	/*
	 * We currently use fixed-sized buffers, so trivially sanitize
	 * the reported payload length.
	 */
	if (len > RPMSG_BUF_SIZE ||
		msg->len > (len - sizeof(struct rpmsg_hdr))) {
		dev_warn(dev, "inbound msg too big: (%d, %d)\n", len, msg->len);
		return -EINVAL;
	}

	/* use the dst addr to fetch the callback of the appropriate user */
	mutex_lock(&vrp->endpoints_lock);

	ept = idr_find(&vrp->endpoints, msg->dst);

	/* let's make sure no one deallocates ept while we use it */
	if (ept)
		kref_get(&ept->refcount);

	mutex_unlock(&vrp->endpoints_lock);

	if (ept) {
		/* make sure ept->cb doesn't go away while we use it */
		mutex_lock(&ept->cb_lock);

		if (ept->cb)
			ept->cb(ept->rpdev, msg->data, msg->len, ept->priv,
				msg->src);

		mutex_unlock(&ept->cb_lock);

		/* farewell, ept, we don't need you anymore */
		kref_put(&ept->refcount, __ept_release);
	} else
		dev_warn(dev, "msg received with no recipient\n");

	/* publish the real size of the buffer */
	sg_init_one(&sg, msg, RPMSG_BUF_SIZE);

	/* add the buffer back to the remote processor's virtqueue */
	err = virtqueue_add_inbuf(vrp->rvq, &sg, 1, msg, GFP_KERNEL);
	if (err < 0) {
		dev_err(dev, "failed to add a virtqueue buffer: %d\n", err);
		return err;
	}

	return 0;
}
Ejemplo n.º 2
0
static int irda_fw_update(struct ir_remocon_data *ir_data)
{
	struct ir_remocon_data *data = ir_data;
	struct i2c_client *client = data->client;
	int i, k, ret, ret2, checksum, checksum2;
	u8 buf_ir_test[8];

	data->pdata->ir_vdd_onoff(&client->dev, 0);
	data->pdata->ir_wake_en(data->pdata, 0);
	msleep(100);
	data->pdata->ir_vdd_onoff(&client->dev, 1);
	data->pdata->ir_wake_en(data->pdata,1);
	gpio_tlmm_config(GPIO_CFG(data->pdata->irda_irq_gpio,  0, GPIO_CFG_INPUT,
			GPIO_CFG_PULL_UP, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
	msleep(70);

	ret = i2c_master_recv(client, buf_ir_test, MC96_READ_LENGTH);
	if (ret < 0) {
		printk(KERN_ERR "%s: err %d\n", __func__, ret);
		ret = i2c_master_recv(client, buf_ir_test, MC96_READ_LENGTH);
		if (ret < 0) {
			printk(KERN_INFO "%s: broken FW!\n", __func__);
			retry_count = 1;
			goto err_bootmode;
		}
	}
	
#ifdef DEBUG
	print_hex_dump(KERN_CRIT, "IRDA Master Rx: ", 16, 1,
				DUMP_PREFIX_ADDRESS, buf_ir_test, 8, 1);
#endif
	ret = buf_ir_test[2] << 8 | buf_ir_test[3];

	if (ret == 0x101) {
		data->pdata->ir_wake_en(data->pdata,0);
		data->pdata->ir_vdd_onoff(&client->dev,0);
		data->on_off = 0;
		msleep(100);
		download_pass = 1;
		return 0;
	}
	if ((ret != FW_VERSION) || (retry_count != 0)) {
		printk(KERN_INFO "2. %s: chip : %04x, bin : %04x, need update!\n",
						__func__, ret, FW_VERSION);
		data->pdata->ir_vdd_onoff(&client->dev, 0);
		data->pdata->ir_wake_en(data->pdata, 0);
		msleep(100);
		data->pdata->ir_vdd_onoff(&client->dev,1);
		msleep(70);

		ret = i2c_master_recv(client, buf_ir_test, MC96_READ_LENGTH);
		if (ret < 0)
			printk(KERN_ERR " %s: err %d\n", __func__, ret);

#ifdef DEBUG
		print_hex_dump(KERN_CRIT, "IRDA Master Rx: ", 16, 1,
				DUMP_PREFIX_ADDRESS, buf_ir_test, 8, 1);
#endif

		ret = buf_ir_test[6] << 8 | buf_ir_test[7];

		checksum = 0;

		for (k = 0; k < 6; k++)
			checksum += buf_ir_test[k];

		if (ret == checksum)
			printk(KERN_INFO "%s: boot mode, FW download start! ret=%04x\n",
							__func__, ret);
		else {
			printk(KERN_ERR "ABOV IC bootcode broken\n");
			goto err_bootmode;
		}

		msleep(30);

		for (i = 0; i < FRAME_COUNT; i++) {
			if (i == FRAME_COUNT-1) {
				ret = i2c_master_send(client,
						&IRDA_binary[i * 70], 6);
				if (ret < 0)
					goto err_update;
			} else {
				ret = i2c_master_send(client,
						&IRDA_binary[i * 70], 70);
				if (ret < 0)
					goto err_update;
			}
			msleep(30);
		}

		ret = i2c_master_recv(client, buf_ir_test, MC96_READ_LENGTH);
		if (ret < 0)
			printk(KERN_ERR "5. %s: err %d\n", __func__, ret);

#ifdef DEBUG
		print_hex_dump(KERN_CRIT, "IRDA Master Rx: ", 16, 1,
				DUMP_PREFIX_ADDRESS, buf_ir_test, 8, 1);
#endif

		ret = buf_ir_test[6] << 8 | buf_ir_test[7];
		checksum = 0;
		for (k = 0; k < 6; k++)
			checksum += buf_ir_test[k];

		msleep(20);

		ret2 = i2c_master_recv(client, buf_ir_test, MC96_READ_LENGTH);
	
		if (ret2 < 0)
			printk(KERN_ERR "6. %s: err %d\n", __func__, ret2);

		ret2 = buf_ir_test[6] << 8 | buf_ir_test[7];
		for (k = 0; k < 6; k++)
			checksum2 += buf_ir_test[k];

		if (ret == checksum) {
			printk(KERN_INFO "1. %s: boot down complete\n",
				__func__);
			download_pass = 1;
		} else if (ret2 == checksum2) {
			printk(KERN_INFO "2. %s: boot down complete\n",
				__func__);
			download_pass = 1;
		} else {
			retry_count++;
			printk(KERN_ERR "FW Checksum fail. Retry = %d\n",
						retry_count);
			goto err_bootmode;
		}

		data->pdata->ir_vdd_onoff(&client->dev, 0);
		msleep(100);
		data->pdata->ir_vdd_onoff(&client->dev, 1);
		data->pdata->ir_wake_en(data->pdata, 1);
		msleep(70);

		ret = i2c_master_recv(client, buf_ir_test, MC96_READ_LENGTH);
		ret = buf_ir_test[2] << 8 | buf_ir_test[3];
		printk(KERN_INFO "7. %s: user mode : Upgrade FW_version : %04x\n",
						__func__, ret);

#ifdef DEBUG
	print_hex_dump(KERN_CRIT, "IRDA Master Rx: ", 16, 1,
				DUMP_PREFIX_ADDRESS, buf_ir_test, 8, 1);
#endif

		data->pdata->ir_wake_en(data->pdata,0);
		data->pdata->ir_vdd_onoff(&client->dev,0);
		data->on_off = 0;

	} else {
		if (ret != DUMMY)
			printk(KERN_INFO "8. %s: chip : %04x, bin : %04x, latest FW_ver\n",
						__func__, ret, FW_VERSION);
		data->pdata->ir_wake_en(data->pdata,0);
		data->pdata->ir_vdd_onoff(&client->dev,0);
		data->on_off = 0;
		msleep(100);

		if (ret == FW_VERSION)
			download_pass = 1;
	}

	return 0;
err_update:
	printk(KERN_ERR "%s: update fail! count : %x, ret = %x\n",
							__func__, i, ret);
	return ret;
err_bootmode:
	printk(KERN_ERR "%s: update fail, checksum = %x ret = %x\n",
					__func__, checksum, ret);
	data->pdata->ir_wake_en(data->pdata,0);
	data->pdata->ir_vdd_onoff(&client->dev,0);
	data->on_off = 0;
	return ret;
}
Ejemplo n.º 3
0
static void hexdump(unsigned char *buf, unsigned int len)
{
	print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
			16, 1,
			buf, len, false);
}
Ejemplo n.º 4
0
static void data_bridge_process_rx(struct work_struct *work)
{
	int			retval;
	unsigned long		flags;
	struct urb		*rx_idle;
	struct sk_buff		*skb;
	struct timestamp_info	*info;
	struct data_bridge	*dev =
		container_of(work, struct data_bridge, process_rx_w);

	struct bridge		*brdg = dev->brdg;
#if !defined(CONFIG_MDM_HSIC_PM)
	/* if the bridge is open or not, resume to consume mdm request
	 * because this link is not dead, it's alive
	 */
	if (!brdg || !brdg->ops.send_pkt || rx_halted(dev))
		return;
#endif

	while (!rx_throttled(brdg) && (skb = skb_dequeue(&dev->rx_done))) {
#ifdef CONFIG_MDM_HSIC_PM
		/* if the bridge is open or not, resume to consume mdm request
		 * because this link is not dead, it's alive
		 */
		if (!brdg) {
			print_hex_dump(KERN_INFO, "dun:", 0, 1, 1, skb->data,
							skb->len, false);
			dev_kfree_skb_any(skb);
			continue;
		}
#endif
		dev->to_host++;
		info = (struct timestamp_info *)skb->cb;
		info->rx_done_sent = get_timestamp();
		/* hand off sk_buff to client,they'll need to free it */
		retval = brdg->ops.send_pkt(brdg->ctx, skb, skb->len);
		if (retval == -ENOTCONN || retval == -EINVAL) {
			return;
		} else if (retval == -EBUSY) {
			dev->rx_throttled_cnt++;
			break;
		}
	}

	spin_lock_irqsave(&dev->rx_done.lock, flags);
	while (!list_empty(&dev->rx_idle)) {
		if (dev->rx_done.qlen > stop_submit_urb_limit)
			break;

		rx_idle = list_first_entry(&dev->rx_idle, struct urb, urb_list);
		list_del(&rx_idle->urb_list);
		spin_unlock_irqrestore(&dev->rx_done.lock, flags);
		retval = submit_rx_urb(dev, rx_idle, GFP_KERNEL);
		spin_lock_irqsave(&dev->rx_done.lock, flags);
		if (retval) {
			list_add_tail(&rx_idle->urb_list, &dev->rx_idle);
			break;
		}
	}
	spin_unlock_irqrestore(&dev->rx_done.lock, flags);
}
Ejemplo n.º 5
0
void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
			  const void *buf, size_t len)
{
	print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, 16, 1,
		       buf, len, true);
}
Ejemplo n.º 6
0
void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
			  const void *buf, size_t len)
{
	print_hex_dump(prefix_str, prefix_type, 16, 1, buf, len, 1);
}
static ftdm_status_t sngisdn_get_frame_info(uint8_t *data, uint32_t data_len, ftdm_trace_dir_t dir, sngisdn_frame_info_t *target)
{
	uint8_t pos = 0;
	uint8_t flag;
	uint16_t ref = 0;
	uint8_t ref_len = 0;
	uint8_t bchan_no = 0;
	uint8_t msgtype;

	/* First octet is protocol discriminator */
	pos++;
	/* Second octet contains length of call reference */
	ref_len = data[pos++] & 0x0F;

	/* third octet is call reference */
	flag = (data[pos] & 0x80) >> 7;
	if (ref_len == 2) {
		ref = (data[pos++] & 0x7F) << 8;
		ref |= (data[pos++] & 0xFF) ;
	} else {
		ref = (data[pos++] & 0x7F);
	}

	/* Next octet is the message type */
	msgtype = data[pos++] & 0x7F;
	
	/*
		ftdm_log(FTDM_LOG_DEBUG, "Raw frame:call_ref:0x%04x flag:%d msgtype:%d\n", ref, flag, msgtype);
	*/
	if (!ref) {
		/* This is not a call specific message (RESTART for example and we do not care about it) */
		return FTDM_FAIL;
	}

	/* Look for the b-channel */
	if (msgtype == PROT_Q931_MSGTYPE_SETUP) {
		/* Try to find the b-channel no*/

		for(; pos < data_len; pos++) {
			uint8_t ie_id = data[pos];
			uint8_t ie_len = data[pos+1];

			switch(ie_id) {
				case PROT_Q931_IE_SENDING_COMPLETE:
					/* Single octet ie's do not have a length */
					ie_len = 0;
					break;
				case PROT_Q931_IE_CHANNEL_ID:
					{
						/* Try to obtain the b-channel */
						uint8_t ie_pos = pos+2;					
						//ifaceIdPresent = get_bits(OCTET(3),7,7);
						if (data[ie_pos] & 0x20) {
							/* Interface type is Primary Rate */
							ie_pos+=2;
							bchan_no = data[ie_pos] & 0x7F;
						} else {
							/* Interface type is Basic Interface */
							/* Get the channel number from info channel selection */
							bchan_no = data[ie_pos] & 0x03;
						}
						ftdm_log(FTDM_LOG_DEBUG, "Found b-channel:%d\n", bchan_no);
						goto parse_ies_done;
					}
					break;
				default:
					pos = pos+ie_len+1;
			}
			//ftdm_log(FTDM_LOG_DEBUG, "Decoded IE:%s\n", get_code_2_str(ie_id, dcodQ931IEIDTable));
		}
		if (!bchan_no) {
			uint32_t tmp_len = 0;
			char tmp[1000];
			print_hex_dump(tmp, &tmp_len, data, 0, data_len);			
			ftdm_log(FTDM_LOG_DEBUG, "Failed to determine b-channel on SETUP message\n%s\n", tmp);
		}
	}

parse_ies_done:

	target->call_ref = ref;
	target->call_ref_flag = flag;
	target->msgtype = msgtype;
	target->bchan_no = bchan_no;
	target->dir = dir;

	return FTDM_SUCCESS;
}
Ejemplo n.º 8
0
void os::print_context(outputStream *st, void *context) {
  if (context == NULL) return;

  ucontext_t* uc = (ucontext_t*)context;
  sigcontext* sc = (sigcontext*)context;
  st->print_cr("Registers:");

  st->print_cr(" G1=" INTPTR_FORMAT " G2=" INTPTR_FORMAT
               " G3=" INTPTR_FORMAT " G4=" INTPTR_FORMAT,
               SIG_REGS(sc).u_regs[CON_G1],
               SIG_REGS(sc).u_regs[CON_G2],
               SIG_REGS(sc).u_regs[CON_G3],
               SIG_REGS(sc).u_regs[CON_G4]);
  st->print_cr(" G5=" INTPTR_FORMAT " G6=" INTPTR_FORMAT
               " G7=" INTPTR_FORMAT " Y=" INTPTR_FORMAT,
               SIG_REGS(sc).u_regs[CON_G5],
               SIG_REGS(sc).u_regs[CON_G6],
               SIG_REGS(sc).u_regs[CON_G7],
               SIG_REGS(sc).y);
  st->print_cr(" O0=" INTPTR_FORMAT " O1=" INTPTR_FORMAT
               " O2=" INTPTR_FORMAT " O3=" INTPTR_FORMAT,
               SIG_REGS(sc).u_regs[CON_O0],
               SIG_REGS(sc).u_regs[CON_O1],
               SIG_REGS(sc).u_regs[CON_O2],
               SIG_REGS(sc).u_regs[CON_O3]);
  st->print_cr(" O4=" INTPTR_FORMAT " O5=" INTPTR_FORMAT
               " O6=" INTPTR_FORMAT " O7=" INTPTR_FORMAT,
               SIG_REGS(sc).u_regs[CON_O4],
               SIG_REGS(sc).u_regs[CON_O5],
               SIG_REGS(sc).u_regs[CON_O6],
               SIG_REGS(sc).u_regs[CON_O7]);


  intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc);
  st->print_cr(" L0=" INTPTR_FORMAT " L1=" INTPTR_FORMAT
               " L2=" INTPTR_FORMAT " L3=" INTPTR_FORMAT,
               sp[L0->sp_offset_in_saved_window()],
               sp[L1->sp_offset_in_saved_window()],
               sp[L2->sp_offset_in_saved_window()],
               sp[L3->sp_offset_in_saved_window()]);
  st->print_cr(" L4=" INTPTR_FORMAT " L5=" INTPTR_FORMAT
               " L6=" INTPTR_FORMAT " L7=" INTPTR_FORMAT,
               sp[L4->sp_offset_in_saved_window()],
               sp[L5->sp_offset_in_saved_window()],
               sp[L6->sp_offset_in_saved_window()],
               sp[L7->sp_offset_in_saved_window()]);
  st->print_cr(" I0=" INTPTR_FORMAT " I1=" INTPTR_FORMAT
               " I2=" INTPTR_FORMAT " I3=" INTPTR_FORMAT,
               sp[I0->sp_offset_in_saved_window()],
               sp[I1->sp_offset_in_saved_window()],
               sp[I2->sp_offset_in_saved_window()],
               sp[I3->sp_offset_in_saved_window()]);
  st->print_cr(" I4=" INTPTR_FORMAT " I5=" INTPTR_FORMAT
               " I6=" INTPTR_FORMAT " I7=" INTPTR_FORMAT,
               sp[I4->sp_offset_in_saved_window()],
               sp[I5->sp_offset_in_saved_window()],
               sp[I6->sp_offset_in_saved_window()],
               sp[I7->sp_offset_in_saved_window()]);

  st->print_cr(" PC=" INTPTR_FORMAT " nPC=" INTPTR_FORMAT,
               SIG_PC(sc),
               SIG_NPC(sc));
  st->cr();
  st->cr();

  st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp);
  print_hex_dump(st, (address)sp, (address)(sp + 32), sizeof(intptr_t));
  st->cr();

  // Note: it may be unsafe to inspect memory near pc. For example, pc may
  // point to garbage if entry point in an nmethod is corrupted. Leave
  // this at the end, and hope for the best.
  address pc = os::Linux::ucontext_get_pc(uc);
  st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
  print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
}
void sngisdn_decode_q921(char* str, uint8_t* data, uint32_t data_len)
{
	uint32_t str_len;
	uint32_t i;
	uint8_t sapi, cr, ea, tei, ns, nr, pf, p, cmd;
	uint8_t frame_format = 0;

	str_len = 0;

	if(data_len >= 2) {
		switch ((int)data[2] & 0x03) {
			case 0: case 2:
				frame_format = I_FRAME;
				break;
			case 1: 
				frame_format = S_FRAME;
				break;
			case 3:
				frame_format = U_FRAME;
				break;
		}
	}

	str_len+= sprintf(&str[str_len], "  format: %s\n",
										get_code_2_str(frame_format, dcodQ921FrameFormatTable));
										
	for(i=0; i < data_len; i++) {
		switch(i) {
			case 0: // Octet 2
				sapi = (uint8_t)((data[i]>>2) & 0x3F);
				cr = (uint8_t)((data[i]>>1) & 0x1);
				ea = (uint8_t)(data[i] & 0x1);
				str_len+= sprintf(&str[str_len], "  sapi: %03d  c/r: %01d  ea: %01d\n", sapi, cr, ea);
				break;
			case 1:
				tei = (uint8_t)((data[i]>>1) & 0x7F);
				ea = (uint8_t)(data[i] & 0x1);
				str_len+= sprintf(&str[str_len], "   tei: %03d          ea: %01d\n", tei, ea);
				break;
			case 2:
				switch(frame_format) {
					case I_FRAME:
						ns = (uint8_t)((data[i]>>1) & 0x7F);
						nr = (uint8_t)((data[i+1]>>1) & 0x7F);
						p = (uint8_t)(data[i+1] & 0x01);
						str_len+= sprintf(&str[str_len], "  n(s): %03d\n  n(r): %03d  p: %01d\n", ns, nr, p);
						break;
					case S_FRAME:
						nr = (uint8_t)((data[i+1]>>1) & 0x7F);
						pf = (uint8_t)(data[i+1] & 0x01);
						str_len+= sprintf(&str[str_len], "  n(r): %03d  p/f: %01d\n", nr, pf);

						cmd = (uint8_t)((data[i]>>2) & 0x03);
						str_len+= sprintf(&str[str_len], "   cmd: %s\n", get_code_2_str(cmd, dcodQ921SupervisoryCmdTable));
						
						break;
					case U_FRAME:
						pf = (uint8_t)((data[i]>>4) & 0x01);
						str_len+= sprintf(&str[str_len], "   p/f: %01d\n", pf);

						cmd = (uint8_t)((data[i]>>2) & 0x03);
						cmd |= (uint8_t)((data[i]>>5) & 0x07);
						
						str_len+= sprintf(&str[str_len], "   cmd: %s\n", get_code_2_str(cmd, dcodQ921UnnumberedCmdTable));
						break;
				}
				break;
		}
	}

	print_hex_dump(str, &str_len, (uint8_t*) data, 0, data_len);
	return;
}
uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset, uint8_t *data, uint16_t index_start)
{
	unsigned char* ieData;
	uint8_t ieId;
	uint32_t len = 0;
	int index_end;

	ieData = (unsigned char*) &data[index_start];

	ieId = OCTET(1);
	len = OCTET(2);	
	index_end = index_start+len+1;

	*str_len += sprintf(&str[*str_len], "  %s:", get_code_2_str(data[index_start], dcodQ931IEIDTable));
	switch(ieId) {
		case PROT_Q931_IE_BEARER_CAP:
			{
				uint8_t codingStandard, infTransferCap, infTransferRate, usrL1Prot;
				/*uint8_t transferMode;*/
				
				codingStandard = get_bits(OCTET(3),6,7);
				infTransferCap = get_bits(OCTET(3),1,5);
				/*transferMode = get_bits(OCTET(4),6,7);*/
				infTransferRate = get_bits(OCTET(4),1,5);
				usrL1Prot = get_bits(OCTET(5),1,5);
				
				*str_len+= sprintf(&str[*str_len], "Coding:%s(%d) TransferCap:%s(%d) TransferRate:%s(%d) L1Prot:%s(%d)\n",
															get_code_2_str(codingStandard, dcodQ931BcCodingStandardTable), codingStandard,
															get_code_2_str(infTransferCap, dcodQ931BcInfTransferCapTable), infTransferCap,
															get_code_2_str(infTransferRate, dcodQ931BcInfTransferRateTable), infTransferRate,
															get_code_2_str(usrL1Prot, dcodQ931BcusrL1ProtTable), usrL1Prot);
			}
			break;
		case PROT_Q931_IE_CAUSE:
			{
				uint8_t codingStandard, location, cause,diagOct = 5;
				codingStandard = get_bits(OCTET(3),6,7);
				location = get_bits(OCTET(3),1,4);
				
				cause = get_bits(OCTET(4),1,7);

				*str_len+= sprintf(&str[*str_len], "coding:%s(%d) location:%s(%d) val:%s(%d)\n",
											get_code_2_str(codingStandard, dcodQ931BcCodingStandardTable), codingStandard,
											get_code_2_str(location,dcodQ931IelocationTable), location,
											get_code_2_str(cause, dcodQ931CauseCodeTable),
											cause);
				switch(cause) {
					case PROT_Q931_RELEASE_CAUSE_IE_NOT_EXIST:
						while(diagOct++ < len) {
							*str_len+= sprintf(&str[*str_len], "  %d:IE %s(0x%02x)\n",
															diagOct,
															get_code_2_str(OCTET(diagOct), dcodQ931IEIDTable),
															OCTET(diagOct));
						}
						break;
					case PROT_Q931_RELEASE_CAUSE_WRONG_CALL_STATE:
						while(diagOct++ < len) {
							*str_len+= sprintf(&str[*str_len], "  %d:Message %s(0x%02x)\n",
															diagOct,
															get_code_2_str(OCTET(diagOct), dcodQ931MsgTypeTable),
															OCTET(diagOct));
						}
						break;
					case PROT_Q931_RECOVERY_ON_TIMER_EXPIRE:
						*str_len+= sprintf(&str[*str_len], "  Timer T\n");
						while(diagOct++ < len) {
							if(OCTET(diagOct) >= ' ' && OCTET(diagOct) < 0x7f) {
								*str_len+= sprintf(&str[*str_len], "%c", OCTET(diagOct));
							} else {
								*str_len+= sprintf(&str[*str_len], ".");
							}
						}
						break;
					default:
						while(diagOct++ < len) {
							*str_len+= sprintf(&str[*str_len], " %d: 0x%02x\n",
																	diagOct,
																	OCTET(diagOct));
						}
						break;
				}
			}		
			break;		
		case PROT_Q931_IE_CHANNEL_ID:
			{
				uint8_t infoChannelSelection=0;
				uint8_t prefExclusive=0;
				uint8_t ifaceIdPresent=0;
				/* uint8_t ifaceIdentifier = 0; */ /* octet_3_1 */
				uint8_t chanType=0, numberMap=0;
				/* uint8_t codingStandard=0; */
				uint8_t channelNo = 0;
				
				infoChannelSelection = get_bits(OCTET(3),1,2);
				prefExclusive = get_bits(OCTET(3),4,4);
				ifaceIdPresent = get_bits(OCTET(3),7,7);
	
				if (ifaceIdPresent) {
					/*ifaceIdentifier= get_bits(OCTET(4),1,7);*/
					chanType = get_bits(OCTET(5),1,4);
					numberMap = get_bits(OCTET(5),5,5);
					/*codingStandard = get_bits(OCTET(5),6,7);*/
					channelNo = get_bits(OCTET(6),1,7);
				} else {
					chanType = get_bits(OCTET(4),1,4);
					numberMap = get_bits(OCTET(4),5,5);
					/*codingStandard = get_bits(OCTET(4),6,7);*/
					channelNo = get_bits(OCTET(5),1,7);
				}
				
				if (numberMap) {
					*str_len+= sprintf(&str[*str_len], " MAP:%s ", get_code_2_str(infoChannelSelection, dcodQ931InfoChannelSelTable));
				} else {
					*str_len+= sprintf(&str[*str_len], "No:%d ", channelNo);
				}
	
				*str_len+= sprintf(&str[*str_len], "Type:%s(%d) %s ", get_code_2_str(chanType,dcodQ931ChanTypeTable), chanType, (numberMap)? "Map":"");
				*str_len+= sprintf(&str[*str_len], "%s/%s \n",
									(prefExclusive)? "Exclusive":"Preferred", 
									(ifaceIdPresent)? "Explicit":"Implicit");
			}
			break;
		case PROT_Q931_IE_CALLING_PARTY_NUMBER:
			{
				uint8_t plan, type, screening = 0, presentation = 0, callingNumOct, j;
				uint8_t screeningEnabled = 0, presentationEnabled = 0;
				char callingNumDigits[32];
				memset(callingNumDigits, 0, sizeof(callingNumDigits));
				
				plan = get_bits(OCTET(3),1,4);
				type = get_bits(OCTET(3),5,7);

				if(!get_bits(OCTET(3),8,8)) {
					screening = get_bits(OCTET(4),1,2);
					presentation = get_bits(OCTET(4),6,7);
					screeningEnabled = 1;
					presentationEnabled = 1;
					callingNumOct = 4;
				} else {
					callingNumOct = 3;
				}
				if(len >= sizeof(callingNumDigits)) {	
					len = sizeof(callingNumDigits)-1;
				}
				j = 0;
				while(callingNumOct++ <= len+1) {
					callingNumDigits[j++]=ia5[get_bits(OCTET(callingNumOct),1,4)][get_bits(OCTET(callingNumOct),5,8)];
				}
				callingNumDigits[j]='\0';
				*str_len+= sprintf(&str[*str_len], "%s(l:%d) plan:%s(%d) type:%s(%d)",
															 
															callingNumDigits, j,
															get_code_2_str(plan, dcodQ931NumberingPlanTable), plan,
															get_code_2_str(type, dcodQ931TypeofNumberTable), type);
															
				if (presentationEnabled||screeningEnabled) {
					*str_len+= sprintf(&str[*str_len], "scr:%s(%d) pres:%s(%d)\n",
														get_code_2_str(screening, dcodQ931ScreeningTable),	screening,
														get_code_2_str(presentation, dcodQ931PresentationTable), presentation);
				} else {
					*str_len+= sprintf(&str[*str_len], "\n");
				}
			}
			break;
		
		case PROT_Q931_IE_CALLED_PARTY_NUMBER:
			{
				uint8_t plan, type, calledNumOct,j;
				char calledNumDigits[32];
				memset(calledNumDigits, 0, sizeof(calledNumDigits));
				plan = get_bits(OCTET(3),1,4);
				type = get_bits(OCTET(3),5,7);

				if(len >= sizeof(calledNumDigits)) {	
					len = sizeof(calledNumDigits)-1;
				}
				calledNumOct = 3;
				j = 0;
				while(calledNumOct++ <= len+1) {
					calledNumDigits[j++]=ia5[get_bits(OCTET(calledNumOct),1,4)][get_bits(OCTET(calledNumOct),5,8)];
				}
				calledNumDigits[j]='\0';
				*str_len+= sprintf(&str[*str_len], "%s(l:%d) plan:%s(%d) type:%s(%d)\n",
														calledNumDigits, j,
														get_code_2_str(plan, dcodQ931NumberingPlanTable), plan,
														get_code_2_str(type, dcodQ931TypeofNumberTable), type);
			}
			break;
		case PROT_Q931_IE_REDIRECTING_NUMBER: //rdnis
			{
				uint8_t plan, type, screening = 0, presentation = 0, reason = 0, rdnisOct,j;
				uint8_t screeningEnabled = 0, presentationEnabled = 0, reasonEnabled = 0;
				char rdnis_string[32];
				memset(rdnis_string, 0, sizeof(rdnis_string));
				rdnisOct = 5;
				plan = get_bits(OCTET(3),1,4);
				type = get_bits(OCTET(3),5,7);
			
				if(!get_bits(OCTET(3),8,8)) { //Oct 3a exists
					rdnisOct++;
					screening = get_bits(OCTET(4),1,2);
					presentation = get_bits(OCTET(4),6,7);
					screeningEnabled = 1;
					presentationEnabled = 1;
					if (!get_bits(OCTET(4),8,8)) { //Oct 3b exists
						rdnisOct++;
						reason = get_bits(OCTET(5),1,4);
						reasonEnabled = 1;
					}
				} 
	
				if(len >= sizeof(rdnis_string)) {	
					len = sizeof(rdnis_string)-1;
				}
				
				j = 0;
				while(rdnisOct++ <= len+1) {
					rdnis_string[j++]=ia5[get_bits(OCTET(rdnisOct),1,4)][get_bits(OCTET(rdnisOct),5,8)];
				}
	
				rdnis_string[j]='\0';	
				*str_len+= sprintf(&str[*str_len], "%s(l:%d) plan:%s(%d) type:%s(%d)",
															rdnis_string, j,
															get_code_2_str(plan, dcodQ931NumberingPlanTable), plan,
															get_code_2_str(type, dcodQ931TypeofNumberTable), type);
															
				if(presentationEnabled || screeningEnabled) {
					*str_len+= sprintf(&str[*str_len], "scr:%s(%d) pres:%s(%d)",
														get_code_2_str(screening, dcodQ931ScreeningTable),	screening,
														get_code_2_str(presentation, dcodQ931PresentationTable), presentation);
				}
	
				if(reasonEnabled) {
					*str_len+= sprintf(&str[*str_len], "reason:%s(%d)",
														get_code_2_str(reason, dcodQ931ReasonTable), reason);
				}
				*str_len+= sprintf(&str[*str_len], "\n");
			}
			break;
		case PROT_Q931_IE_USER_USER:
			{
				uint8_t protDiscr = 0x00, j, uui_stringOct;
				char uui_string[32];
				memset(uui_string, 0, sizeof(uui_string));
				protDiscr = OCTET(3);
				uui_stringOct = 3;
				if (protDiscr != 0x04) { /* Non-IA5 */
					*str_len+= sprintf(&str[*str_len], "%s (0x%02x)\n",
															get_code_2_str(protDiscr, dcodQ931UuiProtDiscrTable), protDiscr);
				} else {
					j = 0;
					
					if(len >= sizeof(uui_string)) {	
						len = sizeof(uui_string)-1;
					}
					while(uui_stringOct++ <= len+1) {
						uui_string[j++]=ia5[get_bits(OCTET(uui_stringOct),1,4)][get_bits(OCTET(uui_stringOct),5,8)];
					}
					uui_string[j]='\0';	
					*str_len+= sprintf(&str[*str_len], "  %s (0x%02x) <%s>\n",
															get_code_2_str(protDiscr, dcodQ931UuiProtDiscrTable), protDiscr,
															uui_string);
				}
			}
			break;
		case PROT_Q931_IE_DISPLAY:
			{
				uint8_t j;
				char displayStr[82];
				uint8_t displayNtEnabled = 0;
				uint8_t displayStrOct = 2;
				uint8_t displayType = 0;
				uint8_t assocInfo = 0;
				
				memset(displayStr, 0, sizeof(displayStr));
				
				if(get_bits(OCTET(3),8,8)) {
					displayType = get_bits(OCTET(3),1,4);
					assocInfo = get_bits(OCTET(3),5,7);

					displayNtEnabled = 1;
					displayStrOct++;
				}
				j = 0;	
				if(len >= sizeof(displayStr)) {	
					len = sizeof(displayStr)-1;
				}
				while(displayStrOct++ <= len+1) {
					displayStr[j++]=ia5[get_bits(OCTET(displayStrOct),1,4)][get_bits(OCTET(displayStrOct),5,8)];
				}
				displayStr[j]='\0';
				if (displayNtEnabled) {
					*str_len+= sprintf(&str[*str_len], "%s(l:%d) type:%s(%d) info:%s(%d)\n",
												displayStr, len,
												get_code_2_str(displayType, dcodQ931DisplayTypeTable), displayType,
												get_code_2_str(assocInfo, dcodQ931AssocInfoTable), assocInfo);
				} else {
					*str_len+= sprintf(&str[*str_len], "%s(l:%d)\n",
															displayStr, len);
				}
			}
			break;
		case PROT_Q931_IE_RESTART_IND:
			{
				uint8_t indClass;
				indClass = get_bits(OCTET(3),1,3);
				*str_len+= sprintf(&str[*str_len], "class:%s(%d)\n",
													get_code_2_str(indClass,dcodQ931RestartIndClassTable), indClass);
			}
			break;
		case PROT_Q931_IE_PROGRESS_IND:
			{
				uint8_t codingStandard, location, progressDescr;
				codingStandard = get_bits(OCTET(3),6,7);
				location = get_bits(OCTET(3),1,4);
				progressDescr = get_bits(OCTET(4),1,7);
				*str_len+= sprintf(&str[*str_len], "coding:%s(%d) location:%s(%d) descr:%s(%d)\n",
													get_code_2_str(codingStandard,dcodQ931BcCodingStandardTable), codingStandard,
													get_code_2_str(location,dcodQ931IelocationTable), location,
													get_code_2_str(progressDescr,dcodQ931IeprogressDescrTable), progressDescr);
			}
			break;
		case PROT_Q931_IE_KEYPAD_FACILITY:
			{
				uint8_t keypadFacilityStrOct = 3, j;
				char keypadFacilityStr[82];
				memset(keypadFacilityStr, 0, sizeof(keypadFacilityStr));
				
				j = 0;	
				if(len >= sizeof(keypadFacilityStr)) {	
					len = sizeof(keypadFacilityStr)-1;
				}
				while(keypadFacilityStrOct++ < len+1) {
					keypadFacilityStr[j++]=ia5[get_bits(OCTET(keypadFacilityStrOct),1,4)][get_bits(OCTET(keypadFacilityStrOct),5,8)];
				}
				keypadFacilityStr[j]='\0';
				*str_len+= sprintf(&str[*str_len], "  digits:%s(l:%d)\n",
														keypadFacilityStr, len);
			}
			break;
		case PROT_Q931_IE_FACILITY:
			{
				uint8_t protProfile;
				protProfile = get_bits(OCTET(3),1,5);
				*str_len+= sprintf(&str[*str_len], "Prot profile:%s(%d)\n",
													get_code_2_str(protProfile,dcodQ931IeFacilityProtProfileTable), protProfile);
			}
			break;
		case PROT_Q931_IE_GENERIC_DIGITS:
			{
				uint8_t encoding,type;
				int value = 0;

				encoding = get_bits(OCTET(3),6,8);
				type = get_bits(OCTET(3),1,5);

				*str_len+= sprintf(&str[*str_len], "encoding:%s(%d) type:%s(%d) ",
													get_code_2_str(encoding,dcodQ931GenDigitsEncodingTable), encoding,
													get_code_2_str(encoding,dcodQ931GenDigitsTypeTable), type);

				if (len > 1) {
					uint32_t j=0;
					
					while(++j < len) {
						switch(encoding) {
							case 0: /* BCD even */
							case 1: /* BCD odd */
								{
									uint8_t byte = OCTET(j+3);
									value = (get_bits(byte,1,4)*10) + get_bits(byte,5,8) + (value*10);
								}
								break;
							case 2:	/* IA 5 */							
								value = value*10 + OCTET(j+3)-'0';
								*str_len+= sprintf(&str[*str_len], "%c", OCTET(j+3));
								break;
							case 3: 
								/* Don't know how to decode binary encoding yet */
								*str_len+= sprintf(&str[*str_len], "Binary encoded");
								break;
						}
					}
					*str_len+= sprintf(&str[*str_len], " ");
					switch(type) {
						case 4: /* info digits */
							*str_len+= sprintf(&str[*str_len], "ani2:%s(%d)", get_code_2_str(value,dcodQ931LineInfoTable), value);
							break;
						case 5: /* Callid */
							*str_len+= sprintf(&str[*str_len], "Caller ID not implemented\n");
							break;
					}
				}
				*str_len+= sprintf(&str[*str_len], "\n");
				print_hex_dump(str, str_len, (uint8_t*) data, index_start, index_end);
			}
			break;
		case PROT_Q931_IE_SENDING_COMPLETE:
			/* No need to decode sending complete IE, as no additional info is available except that sending is done */
			/* This is a single octet IE */
			*str_len+= sprintf(&str[*str_len], "\n");
			return 0;
			break;
		case PROT_Q931_IE_CALLED_PARTY_SUBADDRESS:
			{
				uint8_t type;
				uint8_t currentOct, j=0;
				char calling_subaddr_string[82];
				memset(calling_subaddr_string, 0, sizeof(calling_subaddr_string));
				type = get_bits(OCTET(3),5,7);
				currentOct = 3;
				while(currentOct++ <= len+1) {
						calling_subaddr_string[j++]=ia5[get_bits(OCTET(currentOct),1,4)][get_bits(OCTET(currentOct),5,8)];
				}
				calling_subaddr_string[j++]='\0';
				*str_len += sprintf(&str[*str_len], "%s (l:%d) type:%s(%d) \n",
														calling_subaddr_string, (j-1), get_code_2_str(type, dcodQ931TypeOfSubaddressTable), type);
			}
			break;
		case PROT_Q931_IE_NOTIFICATION_IND:
			{
				uint8_t desc;

				desc = get_bits(OCTET(3),1,7);
				*str_len += sprintf(&str[*str_len], "%s (%d)\n",
														get_code_2_str(desc, dcodQ931NotificationIndTable), desc);
			}
			break;
		case PROT_Q931_IE_REDIRECTION_NUMBER:		
		case PROT_Q931_IE_DATE_TIME:
		case PROT_Q931_IE_INFORMATION_REQUEST:
		case PROT_Q931_IE_SIGNAL:
		case PROT_Q931_IE_SWITCHOOK:
		case PROT_Q931_IE_FEATURE_ACT:
		case PROT_Q931_IE_FEATURE_IND:
		case PROT_Q931_IE_INFORMATION_RATE:
		case PROT_Q931_IE_END_TO_END_TRANSIT_DELAY:
		case PROT_Q931_IE_TRANSIT_DELAY_SELECT_IND:
		case PROT_Q931_IE_PACKET_LAYER_BINARY_PARAMS:
		case PROT_Q931_IE_PACKET_LAYER_WINDOW_SIZE:
		case PROT_Q931_IE_PACKET_LAYER_SIZE:
		case PROT_Q931_IE_TRANSIT_NETWORK_SELECTION:
		case PROT_Q931_IE_LOW_LAYER_COMPAT:
		case PROT_Q931_IE_HIGH_LAYER_COMPAT:
		case PROT_Q931_IE_ESCAPE_FOR_EXTENSION:
		case PROT_Q931_IE_CALL_IDENTITY:
		case PROT_Q931_IE_CALL_STATE:
		case PROT_Q931_IE_SEGMENTED_MESSAGE:
		case PROT_Q931_IE_NETWORK_SPF_FACILITY:
		case PROT_Q931_IE_CALLING_PARTY_SUBADDRESS:
		default:
			{
				*str_len += sprintf(&str[*str_len], "Undecoded");
				print_hex_dump((char*)str, str_len, data, index_start, index_end + 1);
			}
			break;
	}

	return len+1;
}
Ejemplo n.º 11
0
int diag_device_write(void *buf, int data_type, struct diag_request *write_ptr)
{
	int i, err = 0, index;
	index = 0;

	if (driver->logging_mode == MEMORY_DEVICE_MODE) {
		int hsic_updated = 0;
		if (data_type == APPS_DATA) {
			for (i = 0; i < driver->poolsize_write_struct; i++)
				if (driver->buf_tbl[i].length == 0) {
					driver->buf_tbl[i].buf = buf;
					driver->buf_tbl[i].length =
								 driver->used;
#ifdef DIAG_DEBUG
					pr_debug("diag: ENQUEUE buf ptr"
						   " and length is %x , %d\n",
						   (unsigned int)(driver->buf_
				tbl[i].buf), driver->buf_tbl[i].length);
#endif
					break;
				}
		}

#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
		else if (data_type == HSIC_DATA || data_type == HSIC_2_DATA) {
			unsigned long flags;
			int foundIndex = -1;
			hsic_updated = 1;
			index = data_type - HSIC_DATA;
			spin_lock_irqsave(&diag_hsic[index].hsic_spinlock,
									flags);
			for (i = 0; i < diag_hsic[index].poolsize_hsic_write;
									i++) {
				if (diag_hsic[index].hsic_buf_tbl[i].length
									== 0) {
					diag_hsic[index].hsic_buf_tbl[i].buf
									= buf;
					diag_hsic[index].hsic_buf_tbl[i].length
						= diag_bridge[index].write_len;
					diag_hsic[index].
						num_hsic_buf_tbl_entries++;
					foundIndex = i;
					break;
				}
			}
			spin_unlock_irqrestore(&diag_hsic[index].hsic_spinlock,
									flags);
			if (foundIndex == -1)
				err = -1;
			else
				pr_debug("diag: ENQUEUE HSIC buf ptr and length is %x , %d, ch %d\n",
					(unsigned int)buf,
					 diag_bridge[index].write_len, index);
		}
#endif
		for (i = 0; i < driver->num_clients; i++)
			if (driver->client_map[i].pid ==
						 driver->logging_process_id)
				break;
		if (i < driver->num_clients) {
			diag_mem_dev_mode_ready_update(i, hsic_updated);
			pr_debug("diag: wake up logging process\n");
			wake_up_interruptible(&driver->wait_q);
		} else
			return -EINVAL;
	} else if (driver->logging_mode == NO_LOGGING_MODE) {
		if ((data_type >= 0) && (data_type < NUM_SMD_DATA_CHANNELS)) {
			driver->smd_data[data_type].in_busy_1 = 0;
			driver->smd_data[data_type].in_busy_2 = 0;
			queue_work(driver->diag_wq,
				&(driver->smd_data[data_type].
							diag_read_smd_work));
		}
#ifdef CONFIG_DIAG_SDIO_PIPE
		else if (data_type == SDIO_DATA) {
			driver->in_busy_sdio = 0;
			queue_work(driver->diag_sdio_wq,
				&(driver->diag_read_sdio_work));
		}
#endif
#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
		else if (data_type == HSIC_DATA || data_type == HSIC_2_DATA) {
			index = data_type - HSIC_DATA;
			if (diag_hsic[index].hsic_ch)
				queue_work(diag_bridge[index].wq,
					   &(diag_hsic[index].
					     diag_read_hsic_work));
		}
#endif
		err = -1;
	}
#ifdef CONFIG_DIAG_OVER_USB
	else if (driver->logging_mode == USB_MODE) {
		if (data_type == APPS_DATA) {
			driver->write_ptr_svc = (struct diag_request *)
			(diagmem_alloc(driver, sizeof(struct diag_request),
				 POOL_TYPE_WRITE_STRUCT));
			if (driver->write_ptr_svc) {
				driver->write_ptr_svc->length = driver->used;
				driver->write_ptr_svc->buf = buf;
				err = usb_diag_write(driver->legacy_ch,
						driver->write_ptr_svc);
			} else
				err = -1;
		} else if ((data_type >= 0) &&
				(data_type < NUM_SMD_DATA_CHANNELS)) {
			write_ptr->buf = buf;
#ifdef DIAG_DEBUG
			printk(KERN_INFO "writing data to USB,"
				"pkt length %d\n", write_ptr->length);
			print_hex_dump(KERN_DEBUG, "Written Packet Data to"
					   " USB: ", 16, 1, DUMP_PREFIX_ADDRESS,
					    buf, write_ptr->length, 1);
#endif /* DIAG DEBUG */
			err = usb_diag_write(driver->legacy_ch, write_ptr);
		}
#ifdef CONFIG_DIAG_SDIO_PIPE
		else if (data_type == SDIO_DATA) {
			if (machine_is_msm8x60_fusion() ||
					 machine_is_msm8x60_fusn_ffa()) {
				write_ptr->buf = buf;
				err = usb_diag_write(driver->mdm_ch, write_ptr);
			} else
				pr_err("diag: Incorrect sdio data "
						"while USB write\n");
		}
#endif
#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
		else if (data_type == HSIC_DATA || data_type == HSIC_2_DATA) {
			index = data_type - HSIC_DATA;
			if (diag_hsic[index].hsic_device_enabled) {
				struct diag_request *write_ptr_mdm;
				write_ptr_mdm = (struct diag_request *)
						diagmem_alloc(driver,
						sizeof(struct diag_request),
							index +
							POOL_TYPE_HSIC_WRITE);
				if (write_ptr_mdm) {
					write_ptr_mdm->buf = buf;
					write_ptr_mdm->length =
					   diag_bridge[index].write_len;
					write_ptr_mdm->context = (void *)index;
					err = usb_diag_write(
					diag_bridge[index].ch, write_ptr_mdm);
					/* Return to the pool immediately */
					if (err) {
						diagmem_free(driver,
							write_ptr_mdm,
							index +
							POOL_TYPE_HSIC_WRITE);
						pr_err_ratelimited("diag: HSIC write failure, err: %d, ch %d\n",
							err, index);
					}
				} else {
					pr_err("diag: allocate write fail\n");
					err = -1;
				}
			} else {
				pr_err("diag: Incorrect HSIC data "
						"while USB write\n");
				err = -1;
			}
		} else if (data_type == SMUX_DATA) {
				write_ptr->buf = buf;
				write_ptr->context = (void *)SMUX;
				pr_debug("diag: writing SMUX data\n");
				err = usb_diag_write(diag_bridge[SMUX].ch,
								 write_ptr);
		}
#endif
		APPEND_DEBUG('d');
	}
#endif /* DIAG OVER USB */
    return err;
}
Ejemplo n.º 12
0
void diag_process_hdlc(void *data, unsigned len)
{
	struct diag_hdlc_decode_type hdlc;
	int ret, type = 0;
	pr_debug("diag: HDLC decode fn, len of data  %d\n", len);
	hdlc.dest_ptr = driver->hdlc_buf;
	hdlc.dest_size = USB_MAX_OUT_BUF;
	hdlc.src_ptr = data;
	hdlc.src_size = len;
	hdlc.src_idx = 0;
	hdlc.dest_idx = 0;
	hdlc.escaping = 0;

	ret = diag_hdlc_decode(&hdlc);

	if (hdlc.dest_idx < 3) {
		pr_err("diag: Integer underflow in hdlc processing\n");
		return;
	}
	if (ret) {
		type = diag_process_apps_pkt(driver->hdlc_buf,
							  hdlc.dest_idx - 3);
		if (type < 0)
			return;
	} else if (driver->debug_flag) {
		printk(KERN_ERR "Packet dropped due to bad HDLC coding/CRC"
				" errors or partial packet received, packet"
				" length = %d\n", len);
		print_hex_dump(KERN_DEBUG, "Dropped Packet Data: ", 16, 1,
					   DUMP_PREFIX_ADDRESS, data, len, 1);
		driver->debug_flag = 0;
	}
	/* send error responses from APPS for Central Routing */
	if (type == 1 && chk_apps_only()) {
		diag_send_error_rsp(hdlc.dest_idx);
		type = 0;
	}
	/* implies this packet is NOT meant for apps */
	if (!(driver->smd_data[MODEM_DATA].ch) && type == 1) {
		if (chk_apps_only()) {
			diag_send_error_rsp(hdlc.dest_idx);
		} else { /* APQ 8060, Let Q6 respond */
			if (driver->smd_data[LPASS_DATA].ch)
				smd_write(driver->smd_data[LPASS_DATA].ch,
						driver->hdlc_buf,
						hdlc.dest_idx - 3);
		}
		type = 0;
	}

#ifdef DIAG_DEBUG
	pr_debug("diag: hdlc.dest_idx = %d", hdlc.dest_idx);
	for (i = 0; i < hdlc.dest_idx; i++)
		printk(KERN_DEBUG "\t%x", *(((unsigned char *)
							driver->hdlc_buf)+i));
#endif /* DIAG DEBUG */
	/* ignore 2 bytes for CRC, one for 7E and send */
	if ((driver->smd_data[MODEM_DATA].ch) && (ret) && (type) &&
						(hdlc.dest_idx > 3)) {
		APPEND_DEBUG('g');
		smd_write(driver->smd_data[MODEM_DATA].ch,
					driver->hdlc_buf, hdlc.dest_idx - 3);
		APPEND_DEBUG('h');
#ifdef DIAG_DEBUG
		printk(KERN_INFO "writing data to SMD, pkt length %d\n", len);
		print_hex_dump(KERN_DEBUG, "Written Packet Data to SMD: ", 16,
			       1, DUMP_PREFIX_ADDRESS, data, len, 1);
#endif /* DIAG DEBUG */
	}
}
Ejemplo n.º 13
0
/*
 * Debug: dump command.
 */
void ft_cmd_dump(struct scst_cmd *cmd, const char *caller)
{
	static atomic_t serial;
	struct ft_cmd *fcmd;
	struct fc_frame_header *fh;
	char prefix[30];
	char buf[150];

	if (!(ft_debug_logging & FT_DEBUG_IO))
		return;

	fcmd = scst_cmd_get_tgt_priv(cmd);
	fh = fc_frame_header_get(fcmd->req_frame);
	snprintf(prefix, sizeof(prefix), FT_MODULE ": cmd %2x",
		atomic_inc_return(&serial) & 0xff);

	pr_info("%s %s oid %x oxid %x resp_len %u\n",
		prefix, caller, ntoh24(fh->fh_s_id), ntohs(fh->fh_ox_id),
		scst_cmd_get_resp_data_len(cmd));
	pr_info("%s scst_cmd %p wlen %u rlen %u\n",
		prefix, cmd, fcmd->write_data_len, fcmd->read_data_len);
	pr_info("%s exp_dir %x exp_xfer_len %d exp_in_len %d\n",
		prefix, cmd->expected_data_direction,
		cmd->expected_transfer_len_full,
		cmd->expected_out_transfer_len);
	pr_info("%s dir %x data_len %lld bufflen %d out_bufflen %d\n",
		prefix, cmd->data_direction, cmd->data_len,
		cmd->bufflen, cmd->out_bufflen);
	pr_info("%s sg_cnt reg %d in %d tgt %d tgt_in %d\n",
		prefix, cmd->sg_cnt, cmd->out_sg_cnt,
		cmd->tgt_i_sg_cnt, cmd->tgt_out_sg_cnt);

	buf[0] = '\0';
	if (cmd->sent_for_exec)
		ft_cmd_flag(buf, sizeof(buf), "sent");
	if (cmd->completed)
		ft_cmd_flag(buf, sizeof(buf), "comp");
	if (cmd->ua_ignore)
		ft_cmd_flag(buf, sizeof(buf), "ua_ign");
	if (cmd->atomic)
		ft_cmd_flag(buf, sizeof(buf), "atom");
	if (cmd->double_ua_possible)
		ft_cmd_flag(buf, sizeof(buf), "dbl_ua_poss");
	if (cmd->is_send_status)
		ft_cmd_flag(buf, sizeof(buf), "send_stat");
	if (cmd->retry)
		ft_cmd_flag(buf, sizeof(buf), "retry");
	if (cmd->internal)
		ft_cmd_flag(buf, sizeof(buf), "internal");
	if (cmd->unblock_dev)
		ft_cmd_flag(buf, sizeof(buf), "unblock_dev");
	if (cmd->cmd_hw_pending)
		ft_cmd_flag(buf, sizeof(buf), "hw_pend");
	if (cmd->tgt_need_alloc_data_buf)
		ft_cmd_flag(buf, sizeof(buf), "tgt_need_alloc");
	if (cmd->tgt_i_data_buf_alloced)
		ft_cmd_flag(buf, sizeof(buf), "tgt_i_alloced");
	if (cmd->dh_data_buf_alloced)
		ft_cmd_flag(buf, sizeof(buf), "dh_alloced");
	if (cmd->expected_values_set)
		ft_cmd_flag(buf, sizeof(buf), "exp_val");
	if (cmd->sg_buff_modified)
		ft_cmd_flag(buf, sizeof(buf), "sg_buf_mod");
	if (cmd->preprocessing_only)
		ft_cmd_flag(buf, sizeof(buf), "pre_only");
	if (cmd->sn_set)
		ft_cmd_flag(buf, sizeof(buf), "sn_set");
	if (cmd->hq_cmd_inced)
		ft_cmd_flag(buf, sizeof(buf), "hq_cmd_inc");
	if (cmd->set_sn_on_restart_cmd)
		ft_cmd_flag(buf, sizeof(buf), "set_sn_on_restart");
	if (cmd->no_sgv)
		ft_cmd_flag(buf, sizeof(buf), "no_sgv");
	if (cmd->may_need_dma_sync)
		ft_cmd_flag(buf, sizeof(buf), "dma_sync");
	if (cmd->out_of_sn)
		ft_cmd_flag(buf, sizeof(buf), "oo_sn");
	if (cmd->inc_expected_sn_on_done)
		ft_cmd_flag(buf, sizeof(buf), "inc_sn_exp");
	if (cmd->done)
		ft_cmd_flag(buf, sizeof(buf), "done");
	if (cmd->finished)
		ft_cmd_flag(buf, sizeof(buf), "fin");

	pr_info("%s flags %s\n", prefix, buf);
	pr_info("%s lun %lld sn %d tag %lld cmd_flags %lx\n",
		prefix, cmd->lun, cmd->sn, cmd->tag, cmd->cmd_flags);
	pr_info("%s tgt_sn %d op_flags %x op %s\n",
		prefix, cmd->tgt_sn, cmd->op_flags, cmd->op_name);
	pr_info("%s status %x msg_status %x "
		"host_status %x driver_status %x\n",
		prefix, cmd->status, cmd->msg_status,
		cmd->host_status, cmd->driver_status);
	pr_info("%s cdb_len %d\n", prefix, cmd->cdb_len);
	snprintf(buf, sizeof(buf), "%s cdb ", prefix);
	print_hex_dump(KERN_INFO, buf, DUMP_PREFIX_NONE,
		16, 4, cmd->cdb, SCST_MAX_CDB_SIZE, 0);
}
void __diag_smd_send_req(void)
{
	void *buf = NULL;
	int *in_busy_ptr = NULL;
	struct diag_request *write_ptr_modem = NULL;
#if  DIAG_XPST
	int type;
#endif

	if (!driver->in_busy_1) {
		buf = driver->buf_in_1;
		write_ptr_modem = driver->write_ptr_1;
		in_busy_ptr = &(driver->in_busy_1);
	} else if (!driver->in_busy_2) {
		buf = driver->buf_in_2;
		write_ptr_modem = driver->write_ptr_2;
		in_busy_ptr = &(driver->in_busy_2);
	}

	if (driver->ch && buf) {
		int r = smd_read_avail(driver->ch);

		if (r > IN_BUF_SIZE) {
			if (r < MAX_IN_BUF_SIZE) {
				DIAGFWD_INFO("\n diag: SMD sending in "
						   "packets upto %d bytes", r);
				buf = krealloc(buf, r, GFP_KERNEL);
			} else {
				DIAGFWD_ERR("\n diag: SMD sending in "
				"packets more than %d bytes", MAX_IN_BUF_SIZE);
				return;
			}
		}
		if (r > 0) {
			if (!buf)
				DIAGFWD_INFO("Out of diagmem for a9\n");
			else {
				APPEND_DEBUG('i');
				smd_read(driver->ch, buf, r);

				if (diag7k_debug_mask) {
					switch (diag7k_debug_mask) {
					case 1:
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from 7K(first 16 bytes)", 16, 1, DUMP_PREFIX_ADDRESS, buf, 16, 1);
						break;
					case 2:
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from 7K(first 16 bytes)", 16, 1, DUMP_PREFIX_ADDRESS, buf, 16, 1);
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from 7K(last 16 bytes) ", 16, 1, DUMP_PREFIX_ADDRESS, buf+r-16, 16, 1);
						break;
					default:
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from 7K ", 16, 1, DUMP_PREFIX_ADDRESS, buf, r, 1);

					}
				}

#if  DIAG_XPST

		type = checkcmd_modem_epst(buf);
		if (type) {
			modem_to_userspace(buf, r, type, 0);
			return;
		}

#endif


				APPEND_DEBUG('j');
				write_ptr_modem->length = r;
				*in_busy_ptr = 1;
				diag_device_write(buf, MODEM_DATA,
							 write_ptr_modem);
			}
		}
	}
}
Ejemplo n.º 15
0
/*
 * Decode an MDS map
 *
 * Ignore any fields we don't care about (there are quite a few of
 * them).
 */
struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
{
	struct ceph_mdsmap *m;
	const void *start = *p;
	int i, j, n;
	int err = -EINVAL;
	u16 version;

	m = kzalloc(sizeof(*m), GFP_NOFS);
	if (m == NULL)
		return ERR_PTR(-ENOMEM);

	ceph_decode_16_safe(p, end, version, bad);
	if (version > 3) {
		pr_warning("got mdsmap version %d > 3, failing", version);
		goto bad;
	}

	ceph_decode_need(p, end, 8*sizeof(u32) + sizeof(u64), bad);
	m->m_epoch = ceph_decode_32(p);
	m->m_client_epoch = ceph_decode_32(p);
	m->m_last_failure = ceph_decode_32(p);
	m->m_root = ceph_decode_32(p);
	m->m_session_timeout = ceph_decode_32(p);
	m->m_session_autoclose = ceph_decode_32(p);
	m->m_max_file_size = ceph_decode_64(p);
	m->m_max_mds = ceph_decode_32(p);

	m->m_info = kcalloc(m->m_max_mds, sizeof(*m->m_info), GFP_NOFS);
	if (m->m_info == NULL)
		goto badmem;

	/* pick out active nodes from mds_info (state > 0) */
	n = ceph_decode_32(p);
	for (i = 0; i < n; i++) {
		u64 global_id;
		u32 namelen;
		s32 mds, inc, state;
		u64 state_seq;
		u8 infoversion;
		struct ceph_entity_addr addr;
		u32 num_export_targets;
		void *pexport_targets = NULL;
		struct ceph_timespec laggy_since;

		ceph_decode_need(p, end, sizeof(u64)*2 + 1 + sizeof(u32), bad);
		global_id = ceph_decode_64(p);
		infoversion = ceph_decode_8(p);
		*p += sizeof(u64);
		namelen = ceph_decode_32(p);  /* skip mds name */
		*p += namelen;

		ceph_decode_need(p, end,
				 4*sizeof(u32) + sizeof(u64) +
				 sizeof(addr) + sizeof(struct ceph_timespec),
				 bad);
		mds = ceph_decode_32(p);
		inc = ceph_decode_32(p);
		state = ceph_decode_32(p);
		state_seq = ceph_decode_64(p);
		ceph_decode_copy(p, &addr, sizeof(addr));
		ceph_decode_addr(&addr);
		ceph_decode_copy(p, &laggy_since, sizeof(laggy_since));
		*p += sizeof(u32);
		ceph_decode_32_safe(p, end, namelen, bad);
		*p += namelen;
		if (infoversion >= 2) {
			ceph_decode_32_safe(p, end, num_export_targets, bad);
			pexport_targets = *p;
			*p += num_export_targets * sizeof(u32);
		} else {
			num_export_targets = 0;
		}

		dout("mdsmap_decode %d/%d %lld mds%d.%d %s %s\n",
		     i+1, n, global_id, mds, inc,
		     ceph_pr_addr(&addr.in_addr),
		     ceph_mds_state_name(state));
		if (mds >= 0 && mds < m->m_max_mds && state > 0) {
			m->m_info[mds].global_id = global_id;
			m->m_info[mds].state = state;
			m->m_info[mds].addr = addr;
			m->m_info[mds].laggy =
				(laggy_since.tv_sec != 0 ||
				 laggy_since.tv_nsec != 0);
			m->m_info[mds].num_export_targets = num_export_targets;
			if (num_export_targets) {
				m->m_info[mds].export_targets =
					kcalloc(num_export_targets, sizeof(u32),
						GFP_NOFS);
				if (m->m_info[mds].export_targets == NULL)
					goto badmem;
				for (j = 0; j < num_export_targets; j++)
					m->m_info[mds].export_targets[j] =
					       ceph_decode_32(&pexport_targets);
			} else {
				m->m_info[mds].export_targets = NULL;
			}
		}
	}

	/* pg_pools */
	ceph_decode_32_safe(p, end, n, bad);
	m->m_num_data_pg_pools = n;
	m->m_data_pg_pools = kcalloc(n, sizeof(u64), GFP_NOFS);
	if (!m->m_data_pg_pools)
		goto badmem;
	ceph_decode_need(p, end, sizeof(u64)*(n+1), bad);
	for (i = 0; i < n; i++)
		m->m_data_pg_pools[i] = ceph_decode_64(p);
	m->m_cas_pg_pool = ceph_decode_64(p);

	/* ok, we don't care about the rest. */
	dout("mdsmap_decode success epoch %u\n", m->m_epoch);
	return m;

badmem:
	err = -ENOMEM;
bad:
	pr_err("corrupt mdsmap\n");
	print_hex_dump(KERN_DEBUG, "mdsmap: ",
		       DUMP_PREFIX_OFFSET, 16, 1,
		       start, end - start, true);
	ceph_mdsmap_destroy(m);
	return ERR_PTR(err);
}
Ejemplo n.º 16
0
static void ide_scsi_hex_dump(u8 *data, int len)
{
	print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0);
}
Ejemplo n.º 17
0
/**
 * rppc_xlate_buffers - translate argument pointers in the marshalled packet
 * @rpc: rppc instance
 * @func: rppc function packet being acted upon
 * @direction: direction of translation
 *
 * This function translates all the pointers within the function call packet
 * structure, based on the translation descriptor structures. The translation
 * replaces the pointers to the appropriate pointers based on the direction.
 * The function is invoked in preparing the packet to be sent to the remote
 * processor-side and replaces the pointers to the remote processor device
 * address pointers; and in processing the packet back after executing the
 * function and replacing back the remote processor device addresses with
 * the original pointers.
 *
 * Return: 0 on success, or an appropriate failure code otherwise
 */
int rppc_xlate_buffers(struct rppc_instance *rpc, struct rppc_function *func,
		       int direction)
{
	uint8_t *base_ptr = NULL;
	struct dma_buf *dbuf = NULL;
	struct device *dev = rpc->dev;
	uint32_t ptr_idx, pri_offset, sec_offset, offset, pg_offset, size;
	int i, limit, inc = 1;
	virt_addr_t kva, uva, buva;
	dev_addr_t rda;
	int ret = 0, final_ret = 0;
	int xlate_fd;

	limit = func->num_translations;
	if (WARN_ON(!limit))
		return 0;

	dev_dbg(dev, "operating on %d pointers\n", func->num_translations);

	/* sanity check the translation elements */
	for (i = 0; i < limit; i++) {
		ptr_idx = func->translations[i].index;
		pri_offset = func->params[ptr_idx].data -
						func->params[ptr_idx].base;
		sec_offset = func->translations[i].offset;
		size = func->params[ptr_idx].size;

		if (ptr_idx >= RPPC_MAX_PARAMETERS) {
			dev_err(dev, "xlate[%d] - invalid parameter pointer index %u\n",
				i, ptr_idx);
			return -EINVAL;
		}
		if (func->params[ptr_idx].type != RPPC_PARAM_TYPE_PTR) {
			dev_err(dev, "xlate[%d] - parameter index %u is not a pointer (type %u)\n",
				i, ptr_idx, func->params[ptr_idx].type);
			return -EINVAL;
		}
		if (func->params[ptr_idx].data == 0) {
			dev_err(dev, "xlate[%d] - supplied user pointer is NULL!\n",
				i);
			return -EINVAL;
		}
		if (sec_offset > (size - sizeof(virt_addr_t))) {
			dev_err(dev, "xlate[%d] offset is larger than data area! (sec_offset = %u size = %u)\n",
				i, sec_offset, size);
			return -ENOSPC;
		}
	}

	/*
	 * we may have a failure during translation, in which case use the same
	 * loop to unwind the whole operation
	 */
	for (i = 0; i != limit; i += inc) {
		dev_dbg(dev, "starting translation %d of %d by %d\n",
			i, limit, inc);

		ptr_idx = func->translations[i].index;
		pri_offset = func->params[ptr_idx].data -
						func->params[ptr_idx].base;
		sec_offset = func->translations[i].offset;
		offset = pri_offset + sec_offset;
		pg_offset = (offset & (PAGE_SIZE - 1));

		/*
		 * map into kernel the page containing the offset, where the
		 * pointer needs to be translated.
		 */
		ret = rppc_map_page(rpc, func->params[ptr_idx].fd, offset,
				    &base_ptr, &dbuf);
		if (ret) {
			dev_err(dev, "rppc_map_page failed, translation = %d param_index = %d fd = %d ret = %d\n",
				i, ptr_idx, func->params[ptr_idx].fd, ret);
			goto unwind;
		}

		/*
		 * perform the actual translation as per the direction.
		 */
		if (direction == RPPC_UVA_TO_RPA) {
			kva = (virt_addr_t)&base_ptr[pg_offset];
			if (kva & 0x3) {
				dev_err(dev, "kernel virtual address %p is not aligned for translation = %d\n",
					(void *)kva, i);
				ret = -EADDRNOTAVAIL;
				goto unmap;
			}

			uva = *(virt_addr_t *)kva;
			if (!uva) {
				dev_err(dev, "user pointer in the translated offset location is NULL for translation = %d\n",
					i);
				print_hex_dump(KERN_DEBUG, "KMAP: ",
					       DUMP_PREFIX_NONE, 16, 1,
					       base_ptr, PAGE_SIZE, true);
				ret = -EADDRNOTAVAIL;
				goto unmap;
			}

			buva = (virt_addr_t)func->translations[i].base;
			xlate_fd = func->translations[i].fd;

			dev_dbg(dev, "replacing UVA %p at KVA %p prt_idx = %u pg_offset = 0x%x fd = %d\n",
				(void *)uva, (void *)kva, ptr_idx,
				pg_offset, xlate_fd);

			/* compute the corresponding remote device address */
			rda = rppc_buffer_lookup(rpc, uva, buva, xlate_fd);
			if (!rda) {
				ret = -ENODATA;
				goto unmap;
			}

			/*
			 * replace the pointer, save the old value for replacing
			 * it back on the function return path
			 */
			func->translations[i].fd = (int32_t)uva;
			*(phys_addr_t *)kva = rda;
			dev_dbg(dev, "replaced UVA %p with RDA %p at KVA %p\n",
				(void *)uva, (void *)rda, (void *)kva);
		} else if (direction == RPPC_RPA_TO_UVA) {
			kva = (virt_addr_t)&base_ptr[pg_offset];
			if (kva & 0x3) {
				ret = -EADDRNOTAVAIL;
				goto unmap;
			}

			rda = *(phys_addr_t *)kva;
			uva = (virt_addr_t)func->translations[i].fd;
			WARN_ON(!uva);
			*(virt_addr_t *)kva = uva;

			dev_dbg(dev, "replaced RDA %p with UVA %p at KVA %p\n",
				(void *)rda, (void *)uva, (void *)kva);
		}

unmap:
		/*
		 * unmap the page containing the translation from kernel, the
		 * next translation acting on the same fd might be in a
		 * different page altogether from the current one
		 */
		rppc_unmap_page(rpc, offset, base_ptr, dbuf);
		dbuf = NULL;
		base_ptr = NULL;

		if (!ret)
			continue;

unwind:
		/*
		 * unwind all the previous translations if the failure occurs
		 * while sending a message to the remote-side. There's nothing
		 * to do but to continue if the failure occurs during the
		 * processing of a function response.
		 */
		if (direction == RPPC_UVA_TO_RPA) {
			dev_err(dev, "unwinding UVA to RDA translations! translation = %d\n",
				i);
			direction = RPPC_RPA_TO_UVA;
			inc = -1;
			limit = -1;
		} else if (direction == RPPC_RPA_TO_UVA) {
			dev_err(dev, "error during UVA to RDA translations!! current translation = %d\n",
				i);
		}
		/*
		 * store away the return value to return back to caller
		 * in case of an error, record only the first error
		 */
		if (!final_ret)
			final_ret = ret;
	}

	/*
	 * all the in-place pointer replacements are done, release all the
	 * imported buffers during the remote function return path
	 */
	if (direction == RPPC_RPA_TO_UVA) {
		mutex_lock(&rpc->lock);
		idr_for_each(&rpc->dma_idr, rppc_free_auto_dmabuf, rpc);
		mutex_unlock(&rpc->lock);
	}

	return final_ret;
}
Ejemplo n.º 18
0
int diag_device_write(void *buf, int proc_num, struct diag_request *write_ptr)
{
	int i, err = 0;

	if (driver->logging_mode == MEMORY_DEVICE_MODE) {
		if (proc_num == APPS_DATA) {
			for (i = 0; i < driver->poolsize_write_struct; i++)
				if (driver->buf_tbl[i].length == 0) {
					driver->buf_tbl[i].buf = buf;
					driver->buf_tbl[i].length =
								 driver->used;
#ifdef DIAG_DEBUG
					printk(KERN_INFO "\n ENQUEUE buf ptr"
						   " and length is %x , %d\n",
						   (unsigned int)(driver->buf_
				tbl[i].buf), driver->buf_tbl[i].length);
#endif
					break;
				}
		}
		for (i = 0; i < driver->num_clients; i++)
			if (driver->client_map[i].pid ==
						 driver->logging_process_id)
				break;
		if (i < driver->num_clients) {
			driver->data_ready[i] |= MEMORY_DEVICE_LOG_TYPE;
			wake_up_interruptible(&driver->wait_q);
		} else
			return -EINVAL;
	} else if (driver->logging_mode == NO_LOGGING_MODE) {
		if (proc_num == MODEM_DATA) {
			driver->in_busy_1 = 0;
			driver->in_busy_2 = 0;
			queue_work(driver->diag_wq, &(driver->
							diag_read_smd_work));
		} else if (proc_num == QDSP_DATA) {
			driver->in_busy_qdsp_1 = 0;
			driver->in_busy_qdsp_2 = 0;
			queue_work(driver->diag_wq, &(driver->
						diag_read_smd_qdsp_work));
		}
		err = -1;
	}
#ifdef CONFIG_DIAG_OVER_USB
	else if (driver->logging_mode == USB_MODE) {
		if (proc_num == APPS_DATA) {
			driver->write_ptr_svc = (struct diag_request *)
			(diagmem_alloc(driver, sizeof(struct diag_request),
				 POOL_TYPE_WRITE_STRUCT));
			if (driver->write_ptr_svc) {
				driver->write_ptr_svc->length = driver->used;
				driver->write_ptr_svc->buf = buf;
				err = usb_diag_write(driver->legacy_ch,
						driver->write_ptr_svc);
			} else
				err = -1;
		} else if (proc_num == MODEM_DATA) {
			write_ptr->buf = buf;
#ifdef DIAG_DEBUG
			printk(KERN_INFO "writing data to USB,"
				"pkt length %d\n", write_ptr->length);
			print_hex_dump(KERN_DEBUG, "Written Packet Data to"
					   " USB: ", 16, 1, DUMP_PREFIX_ADDRESS,
					    buf, write_ptr->length, 1);
#endif /* DIAG DEBUG */
			err = usb_diag_write(driver->legacy_ch, write_ptr);
		} else if (proc_num == QDSP_DATA) {
			write_ptr->buf = buf;
			err = usb_diag_write(driver->legacy_ch, write_ptr);
		}
		APPEND_DEBUG('k');
	}
#endif /* DIAG OVER USB */
    return err;
}
static irqreturn_t cypress_touchkey_interrupt(int irq, void *dev_id)
{
	struct cypress_touchkey_info *info = dev_id;
	u8 buf[10] = {0,};
	int code;
	int press;
	int ret;

	ret = gpio_get_value(info->pdata->gpio_int);
	if (ret) {
		dev_err(&info->client->dev, "not real interrupt (%d).\n", ret);
		goto out;
	}

	if (info->is_powering_on) {
		dev_err(&info->client->dev, "%s: ignoring spurious boot "
					"interrupt\n", __func__);
		return IRQ_HANDLED;
	}

#if defined(SEC_TOUCHKEY_VERBOSE_DEBUG)
	ret = i2c_smbus_read_i2c_block_data(info->client,
			CYPRESS_GEN, ARRAY_SIZE(buf), buf);
	if (ret != ARRAY_SIZE(buf)) {
		dev_err(&info->client->dev, "interrupt failed with %d.\n", ret);
		goto out;
	}
	print_hex_dump(KERN_DEBUG, "cypress_touchkey: ",
			DUMP_PREFIX_OFFSET, 32, 1, buf, 10, false);
#else
	buf[0] = i2c_smbus_read_byte_data(info->client, CYPRESS_GEN);
	if (buf[0] < 0) {
		dev_err(&info->client->dev, "interrupt failed with %d.\n", ret);
		goto out;
	}
#endif
	press = !(buf[0] & PRESS_BIT_MASK);
	code = (int)(buf[0] & KEYCODE_BIT_MASK) - 1;
	dev_dbg(&info->client->dev,
		"[TouchKey]press=%d, code=%d\n", press, code);

	if (code < 0) {
		dev_err(&info->client->dev,
				"not profer interrupt 0x%2X.\n", buf[0]);
		goto out;
	}

#if defined(SEC_TOUCHKEY_DEBUG)
	TOUCHKEY_LOG(info->keycode[code], press);
#endif

//	if (touch_is_pressed && press) {
//		printk(KERN_ERR "[TouchKey] don't send event because touch is pressed.\n");
//		printk(KERN_ERR "[TouchKey] touch_pressed = %d\n",
//							touch_is_pressed);
//	} else {
		input_report_key(info->input_dev, info->keycode[code], press);
		input_sync(info->input_dev);
//	}

out:
	return IRQ_HANDLED;
}
static void usbip_dump_buffer(char *buff, int bufflen)
{
	print_hex_dump(KERN_DEBUG, "usbip-core", DUMP_PREFIX_OFFSET, 16, 4,
		       buff, bufflen, false);
}
/**
 * When a control packet is received, analyze the
 * "status" and call appropriate response function.
 * Enqueue the control packet for Application.
 * @return None
 */
static VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, struct sk_buff *skb)
{
	PPER_TARANG_DATA pTarang = NULL;
	BOOLEAN HighPriorityMessage = FALSE;
	struct sk_buff *newPacket = NULL;
	CHAR cntrl_msg_mask_bit = 0;
	BOOLEAN drop_pkt_flag = TRUE;
	USHORT usStatus = *(PUSHORT)(skb->data);

	if (netif_msg_pktdata(Adapter))
		print_hex_dump(KERN_DEBUG, PFX "rx control: ", DUMP_PREFIX_NONE,
				16, 1, skb->data, skb->len, 0);

	switch (usStatus) {
	case CM_RESPONSES:               /* 0xA0 */
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
			DBG_LVL_ALL,
			"MAC Version Seems to be Non Multi-Classifier, rejected by Driver");
		HighPriorityMessage = TRUE;
		break;
	case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
		HighPriorityMessage = TRUE;
		if (Adapter->LinkStatus == LINKUP_DONE)
			CmControlResponseMessage(Adapter,
				(skb->data + sizeof(USHORT)));
		break;
	case LINK_CONTROL_RESP:          /* 0xA2 */
	case STATUS_RSP:                 /* 0xA1 */
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
			DBG_LVL_ALL, "LINK_CONTROL_RESP");
		HighPriorityMessage = TRUE;
		LinkControlResponseMessage(Adapter,
			(skb->data + sizeof(USHORT)));
		break;
	case STATS_POINTER_RESP:         /* 0xA6 */
		HighPriorityMessage = TRUE;
		StatisticsResponse(Adapter, (skb->data + sizeof(USHORT)));
		break;
	case IDLE_MODE_STATUS:           /* 0xA3 */
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
			DBG_LVL_ALL,
			"IDLE_MODE_STATUS Type Message Got from F/W");
		InterfaceIdleModeRespond(Adapter, (PUINT)(skb->data +
					sizeof(USHORT)));
		HighPriorityMessage = TRUE;
		break;

	case AUTH_SS_HOST_MSG:
		HighPriorityMessage = TRUE;
		break;

	default:
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
			DBG_LVL_ALL, "Got Default Response");
		/* Let the Application Deal with This Packet */
		break;
	}

	/* Queue The Control Packet to The Application Queues */
	down(&Adapter->RxAppControlQueuelock);

	for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) {
		if (Adapter->device_removed)
			break;

		drop_pkt_flag = TRUE;
		/*
		 * There are cntrl msg from A0 to AC. It has been mapped to 0 to
		 * C bit in the cntrl mask.
		 * Also, by default AD to BF has been masked to the rest of the
		 * bits... which wil be ON by default.
		 * if mask bit is enable to particular pkt status, send it out
		 * to app else stop it.
		 */
		cntrl_msg_mask_bit = (usStatus & 0x1F);
		/*
		 * printk("\ninew  msg  mask bit which is disable in mask:%X",
		 *	cntrl_msg_mask_bit);
		 */
		if (pTarang->RxCntrlMsgBitMask & (1 << cntrl_msg_mask_bit))
			drop_pkt_flag = FALSE;

		if ((drop_pkt_flag == TRUE) ||
				(pTarang->AppCtrlQueueLen > MAX_APP_QUEUE_LEN)
				|| ((pTarang->AppCtrlQueueLen >
					MAX_APP_QUEUE_LEN / 2) &&
				    (HighPriorityMessage == FALSE))) {
			/*
			 * Assumption:-
			 * 1. every tarang manages it own dropped pkt
			 *    statitistics
			 * 2. Total packet dropped per tarang will be equal to
			 *    the sum of all types of dropped pkt by that
			 *    tarang only.
			 */
			switch (*(PUSHORT)skb->data) {
			case CM_RESPONSES:
				pTarang->stDroppedAppCntrlMsgs.cm_responses++;
				break;
			case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
				pTarang->stDroppedAppCntrlMsgs.cm_control_newdsx_multiclassifier_resp++;
				break;
			case LINK_CONTROL_RESP:
				pTarang->stDroppedAppCntrlMsgs.link_control_resp++;
				break;
			case STATUS_RSP:
				pTarang->stDroppedAppCntrlMsgs.status_rsp++;
				break;
			case STATS_POINTER_RESP:
				pTarang->stDroppedAppCntrlMsgs.stats_pointer_resp++;
				break;
			case IDLE_MODE_STATUS:
				pTarang->stDroppedAppCntrlMsgs.idle_mode_status++;
				break;
			case AUTH_SS_HOST_MSG:
				pTarang->stDroppedAppCntrlMsgs.auth_ss_host_msg++;
				break;
			default:
				pTarang->stDroppedAppCntrlMsgs.low_priority_message++;
				break;
			}

			continue;
		}

		newPacket = skb_clone(skb, GFP_KERNEL);
		if (!newPacket)
			break;
		ENQUEUEPACKET(pTarang->RxAppControlHead,
				pTarang->RxAppControlTail, newPacket);
		pTarang->AppCtrlQueueLen++;
	}
	up(&Adapter->RxAppControlQueuelock);
	wake_up(&Adapter->process_read_wait_queue);
	dev_kfree_skb(skb);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,
			"After wake_up_interruptible");
}
static void diag_smd_cntl_send_req(int proc_num)
{
	int data_len = 0, type = -1, count_bytes = 0, j, r, flag = 0;
	struct bindpkt_params_per_process *pkt_params =
		 kzalloc(sizeof(struct bindpkt_params_per_process), GFP_KERNEL);
	struct diag_ctrl_msg *msg;
	struct cmd_code_range *range;
	struct bindpkt_params *temp;
	void *buf = NULL, *dump_buf = NULL;
	smd_channel_t *smd_ch = NULL;

	DIAG_INFO("%s: %s\n", __func__,
		(proc_num == MODEM_PROC)?"MODEM_PROC":
		(proc_num == QDSP_PROC)?"QDSP_PROC":"WCNSS_PROC");

	if (proc_num == MODEM_PROC) {
		buf = driver->buf_in_cntl;
		smd_ch = driver->ch_cntl;
	} else if (proc_num == QDSP_PROC) {
		buf = driver->buf_in_qdsp_cntl;
		smd_ch = driver->chqdsp_cntl;
	} else if (proc_num == WCNSS_PROC) {
		buf = driver->buf_in_wcnss_cntl;
		smd_ch = driver->ch_wcnss_cntl;
	}

	if (!smd_ch || !buf) {
		kfree(pkt_params);
		return;
	}

	r = smd_read_avail(smd_ch);
	if (r > IN_BUF_SIZE) {
		if (r < MAX_IN_BUF_SIZE) {
			pr_err("diag: SMD CNTL sending pkt upto %d bytes", r);
			buf = krealloc(buf, r, GFP_KERNEL);
		} else {
			pr_err("diag: CNTL pkt > %d bytes", MAX_IN_BUF_SIZE);
			kfree(pkt_params);
			return;
		}
	}
	if (buf && r > 0) {
		smd_read(smd_ch, buf, r);
		while (count_bytes + HDR_SIZ <= r) {
			type = *(uint32_t *)(buf);
			data_len = *(uint32_t *)(buf + 4);
			count_bytes = count_bytes+HDR_SIZ+data_len;
			if (type == DIAG_CTRL_MSG_REG && r >= count_bytes) {
				msg = buf+HDR_SIZ;
				if (!msg->count_entries) {
					DIAG_ERR("version: %d, cmd_code: %d,"
						" subsysid: %d, count_entries: %d,"
						" port:%d\n", msg->version,
						msg->cmd_code, msg->subsysid,
						msg->count_entries, msg->port);
					dump_buf = kmalloc(r, GFP_KERNEL);
					memcpy(dump_buf, buf, r);
					continue;
				}
				range = buf+HDR_SIZ+
						sizeof(struct diag_ctrl_msg);
				pkt_params->count = msg->count_entries;
				temp = kzalloc(pkt_params->count * sizeof(struct
						 bindpkt_params), GFP_KERNEL);
				for (j = 0; j < pkt_params->count; j++) {
					temp->cmd_code = msg->cmd_code;
					temp->subsys_id = msg->subsysid;
					temp->client_id = proc_num;
					temp->proc_id = proc_num;
					temp->cmd_code_lo = range->cmd_code_lo;
					temp->cmd_code_hi = range->cmd_code_hi;
					range++;
					temp++;
				}
				temp -= pkt_params->count;
				pkt_params->params = temp;
				flag = 1;
				diagchar_ioctl(NULL, DIAG_IOCTL_COMMAND_REG,
						 (unsigned long)pkt_params);
				kfree(temp);
				buf = buf + HDR_SIZ + data_len;
			}
		}
	}
	if (dump_buf) {
		print_hex_dump(KERN_DEBUG, "diag_debug_buf:",
			16, 1, DUMP_PREFIX_ADDRESS, dump_buf, r, 1);
		kfree(dump_buf);
	}
	kfree(pkt_params);
	if (flag) {
		/* Poll SMD CNTL channels to check for data */
		queue_work(driver->diag_wq, &(driver->diag_read_smd_cntl_work));
		queue_work(driver->diag_wq,
			 &(driver->diag_read_smd_qdsp_cntl_work));
		queue_work(driver->diag_wq,
			 &(driver->diag_read_smd_wcnss_cntl_work));
	}
}
Ejemplo n.º 23
0
void diag_process_hdlc(void *data, unsigned len)
{
	struct diag_hdlc_decode_type hdlc;
	int ret, type = 0;
#if defined(DIAG_DEBUG) || defined(CONFIG_DIAG_OVER_USB)
	int i;
	pr_debug("\n HDLC decode function, len of data  %d\n", len);
#endif
	hdlc.dest_ptr = driver->hdlc_buf;
	hdlc.dest_size = USB_MAX_OUT_BUF;
	hdlc.src_ptr = data;
	hdlc.src_size = len;
	hdlc.src_idx = 0;
	hdlc.dest_idx = 0;
	hdlc.escaping = 0;

	ret = diag_hdlc_decode(&hdlc);

	if (ret)
		type = diag_process_apps_pkt(driver->hdlc_buf,
							  hdlc.dest_idx - 3);
	else if (driver->debug_flag) {
		printk(KERN_ERR "Packet dropped due to bad HDLC coding/CRC"
				" errors or partial packet received, packet"
				" length = %d\n", len);
		print_hex_dump(KERN_DEBUG, "Dropped Packet Data: ", 16, 1,
					   DUMP_PREFIX_ADDRESS, data, len, 1);
		driver->debug_flag = 0;
	}
	/* implies this packet is NOT meant for apps */
	if (!(driver->ch) && type == 1 && chk_config_get_id()) {
		if (chk_config_get_id() == AO8960_TOOLS_ID) {
#if defined(CONFIG_DIAG_OVER_USB)
			driver->apps_rsp_buf[0] = 0x13;
			for (i = 0; i < hdlc.dest_idx; i++)
				driver->apps_rsp_buf[i+1] =
							 *(driver->hdlc_buf+i);
			ENCODE_RSP_AND_SEND(hdlc.dest_idx - 3);
#endif
		} else { /* APQ 8060, Let Q6 respond */
			if (driver->chqdsp)
				smd_write(driver->chqdsp, driver->hdlc_buf,
						  hdlc.dest_idx - 3);
		}
		type = 0;
	}

#ifdef DIAG_DEBUG
	printk(KERN_INFO "\n hdlc.dest_idx = %d", hdlc.dest_idx);
	for (i = 0; i < hdlc.dest_idx; i++)
		printk(KERN_DEBUG "\t%x", *(((unsigned char *)
							driver->hdlc_buf)+i));
#endif /* DIAG DEBUG */
	/* ignore 2 bytes for CRC, one for 7E and send */
	if ((driver->ch) && (ret) && (type) && (hdlc.dest_idx > 3)) {
		APPEND_DEBUG('g');
		smd_write(driver->ch, driver->hdlc_buf, hdlc.dest_idx - 3);
		APPEND_DEBUG('h');
#ifdef DIAG_DEBUG
		printk(KERN_INFO "writing data to SMD, pkt length %d\n", len);
		print_hex_dump(KERN_DEBUG, "Written Packet Data to SMD: ", 16,
			       1, DUMP_PREFIX_ADDRESS, data, len, 1);
#endif /* DIAG DEBUG */
	}
}
Ejemplo n.º 24
0
/* Loopback test RX callback
 * This is called for each received packet during loopback testing.
 */
void efx_loopback_rx_packet(struct efx_nic *efx,
			    const char *buf_ptr, int pkt_len)
{
	struct efx_loopback_state *state = efx->loopback_selftest;
	struct efx_loopback_payload *received;
	struct efx_loopback_payload *payload;

	BUG_ON(!buf_ptr);

	/* If we are just flushing, then drop the packet */
	if ((state == NULL) || state->flush)
		return;

	payload = &state->payload;

	received = (struct efx_loopback_payload *) buf_ptr;
	received->ip.saddr = payload->ip.saddr;
	if (state->offload_csum)
		received->ip.check = payload->ip.check;

	/* Check that header exists */
	if (pkt_len < sizeof(received->header)) {
		EFX_ERR(efx, "saw runt RX packet (length %d) in %s loopback "
			"test\n", pkt_len, LOOPBACK_MODE(efx));
		goto err;
	}

	/* Check that the ethernet header exists */
	if (memcmp(&received->header, &payload->header, ETH_HLEN) != 0) {
		EFX_ERR(efx, "saw non-loopback RX packet in %s loopback test\n",
			LOOPBACK_MODE(efx));
		goto err;
	}

	/* Check packet length */
	if (pkt_len != sizeof(*payload)) {
		EFX_ERR(efx, "saw incorrect RX packet length %d (wanted %d) in "
			"%s loopback test\n", pkt_len, (int)sizeof(*payload),
			LOOPBACK_MODE(efx));
		goto err;
	}

	/* Check that IP header matches */
	if (memcmp(&received->ip, &payload->ip, sizeof(payload->ip)) != 0) {
		EFX_ERR(efx, "saw corrupted IP header in %s loopback test\n",
			LOOPBACK_MODE(efx));
		goto err;
	}

	/* Check that msg and padding matches */
	if (memcmp(&received->msg, &payload->msg, sizeof(received->msg)) != 0) {
		EFX_ERR(efx, "saw corrupted RX packet in %s loopback test\n",
			LOOPBACK_MODE(efx));
		goto err;
	}

	/* Check that iteration matches */
	if (received->iteration != payload->iteration) {
		EFX_ERR(efx, "saw RX packet from iteration %d (wanted %d) in "
			"%s loopback test\n", ntohs(received->iteration),
			ntohs(payload->iteration), LOOPBACK_MODE(efx));
		goto err;
	}

	/* Increase correct RX count */
	EFX_TRACE(efx, "got loopback RX in %s loopback test\n",
		  LOOPBACK_MODE(efx));

	atomic_inc(&state->rx_good);
	return;

 err:
#ifdef EFX_ENABLE_DEBUG
	if (atomic_read(&state->rx_bad) == 0) {
		EFX_ERR(efx, "received packet:\n");
		print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1,
			       buf_ptr, pkt_len, 0);
		EFX_ERR(efx, "expected packet:\n");
		print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1,
			       &state->payload, sizeof(state->payload), 0);
	}
#endif
	atomic_inc(&state->rx_bad);
}
int diag_device_write(void *buf, int proc_num, struct diag_request *write_ptr)
{
	int i, err = 0;

	if (driver->logging_mode == MEMORY_DEVICE_MODE) {
		int data_type = 0;
		if (proc_num == APPS_DATA) {
			data_type = MEMORY_DEVICE_LOG_TYPE;
			for (i = 0; i < driver->poolsize_write_struct; i++)
				if (driver->buf_tbl[i].length == 0) {
					driver->buf_tbl[i].buf = buf;
					driver->buf_tbl[i].length =
								 driver->used;
#ifdef DIAG_DEBUG
					printk(KERN_INFO "\n ENQUEUE buf ptr"
						   " and length is %x , %d\n",
			(unsigned int)(driver->buf_tbl[i].buf), driver->buf_tbl[i].length);
#endif
					break;
				}
#if defined(CONFIG_ARCH_MSM8X60_LTE)
		} else if (proc_num == MODEM_DATA || proc_num == QDSP_DATA || proc_num == SDIO_DATA) {
#else
		} else if (proc_num == MODEM_DATA || proc_num == QDSP_DATA) {
#endif
			data_type = USERMODE_DIAGFWD;
#ifdef DIAG_DEBUG
			pr_info("%s#%d: Modem Data buf=%p, len=%d\n", __func__, __LINE__, buf, write_ptr->length);
#endif
#if defined(CONFIG_ARCH_MSM8X60_LTE)
		if (proc_num == SDIO_DATA) {

			for (i = 0; i < driver->num_mdmclients; i++)
				if (driver->mdmclient_map[i].pid ==
						 driver->logging_process_id)
				break;

			if (i < driver->num_mdmclients) {
				driver->mdmdata_ready[i] |= data_type;
				wake_up_interruptible(&driver->mdmwait_q);

				return err;
			} else
				return -EINVAL;
		}
#endif
		}
#if defined(CONFIG_MACH_MECHA)
		else if (proc_num == SDIO_DATA) {

			for (i = 0; i < driver->num_mdmclients; i++)
				if (driver->mdmclient_map[i].pid ==
						 driver->logging_process_id)
				break;

			if (i <= driver->num_mdmclients) {
				driver->mdmdata_ready[i] |= MEMORY_DEVICE_LOG_TYPE;
				wake_up_interruptible(&driver->mdmwait_q);
				return err;
			} else
				return -EINVAL;
		}
#endif

		for (i = 0; i < driver->num_clients; i++)
			if (driver->client_map[i].pid == driver->logging_process_id)
				break;
		if (i < driver->num_clients) {
			driver->data_ready[i] |= data_type;
			wake_up_interruptible(&driver->wait_q);
		} else
			return -EINVAL;
	} else if (driver->logging_mode == NO_LOGGING_MODE) {
		if (proc_num == MODEM_DATA) {
			driver->in_busy_1 = 0;
			driver->in_busy_2 = 0;
			queue_work(driver->diag_wq, &(driver->
							diag_read_smd_work));
		} else if (proc_num == QDSP_DATA) {
			driver->in_busy_qdsp_1 = 0;
			driver->in_busy_qdsp_2 = 0;
			queue_work(driver->diag_wq, &(driver->
						diag_read_smd_qdsp_work));
		}
		err = -1;
	}
#ifdef CONFIG_DIAG_OVER_USB
	else if (driver->logging_mode == USB_MODE) {
		if (proc_num == APPS_DATA) {
			driver->write_ptr_svc = (struct diag_request *)
			(diagmem_alloc(driver, sizeof(struct diag_request),
				 POOL_TYPE_WRITE_STRUCT));
			if (driver->write_ptr_svc) {
				driver->write_ptr_svc->length = driver->used;
				driver->write_ptr_svc->buf = buf;
				err = usb_diag_write(driver->legacy_ch,
						driver->write_ptr_svc);
			} else
				err = -1;
		} else if (proc_num == MODEM_DATA) {
			write_ptr->buf = buf;
#ifdef DIAG_DEBUG
				printk(KERN_INFO "writing data to USB,"
				"pkt length %d\n", write_ptr->length);
			print_hex_dump(KERN_DEBUG, "Written Packet Data to"
					   " USB: ", 16, 1, DUMP_PREFIX_ADDRESS,
					    buf, write_ptr->length, 1);
#endif /* DIAG DEBUG */
			driver->diag_smd_count += write_ptr->length;
			err = usb_diag_write(driver->legacy_ch, write_ptr);
		} else if (proc_num == QDSP_DATA) {
			write_ptr->buf = buf;
			driver->diag_qdsp_count += write_ptr->length;
			err = usb_diag_write(driver->legacy_ch, write_ptr);
		}
#if defined(CONFIG_ARCH_MSM8X60_LTE)//|| defined(CONFIG_MACH_MECHA)
		else if (proc_num == SDIO_DATA) {
			write_ptr->buf = buf;
			if (diag_ch_sdio) {
			err = usb_diag_write(driver->legacy_ch, write_ptr);
			} else {
			err = usb_diag_write(driver->mdm_ch, write_ptr);
			}
		}
#endif
		APPEND_DEBUG('d');
	}
#endif /* DIAG OVER USB */
   return err;
}
Ejemplo n.º 26
0
/**
 * rpmsg_send_offchannel_raw() - send a message across to the remote processor
 * @rpdev: the rpmsg channel
 * @src: source address
 * @dst: destination address
 * @data: payload of message
 * @len: length of payload
 * @wait: indicates whether caller should block in case no TX buffers available
 *
 * This function is the base implementation for all of the rpmsg sending API.
 *
 * It will send @data of length @len to @dst, and say it's from @src. The
 * message will be sent to the remote processor which the @rpdev channel
 * belongs to.
 *
 * The message is sent using one of the TX buffers that are available for
 * communication with this remote processor.
 *
 * If @wait is true, the caller will be blocked until either a TX buffer is
 * available, or 15 seconds elapses (we don't want callers to
 * sleep indefinitely due to misbehaving remote processors), and in that
 * case -ERESTARTSYS is returned. The number '15' itself was picked
 * arbitrarily; there's little point in asking drivers to provide a timeout
 * value themselves.
 *
 * Otherwise, if @wait is false, and there are no TX buffers available,
 * the function will immediately fail, and -ENOMEM will be returned.
 *
 * Normally drivers shouldn't use this function directly; instead, drivers
 * should use the appropriate rpmsg_{try}send{to, _offchannel} API
 * (see include/linux/rpmsg.h).
 *
 * Returns 0 on success and an appropriate error value on failure.
 */
int rpmsg_send_offchannel_raw(struct rpmsg_channel *rpdev, u32 src, u32 dst,
					void *data, int len, bool wait)
{
	struct virtproc_info *vrp = rpdev->vrp;
	struct device *dev = &rpdev->dev;
	struct scatterlist sg;
	struct rpmsg_hdr *msg;
	int err;

	/* bcasting isn't allowed */
	if (src == RPMSG_ADDR_ANY || dst == RPMSG_ADDR_ANY) {
		dev_err(dev, "invalid addr (src 0x%x, dst 0x%x)\n", src, dst);
		return -EINVAL;
	}

	/*
	 * We currently use fixed-sized buffers, and therefore the payload
	 * length is limited.
	 *
	 * One of the possible improvements here is either to support
	 * user-provided buffers (and then we can also support zero-copy
	 * messaging), or to improve the buffer allocator, to support
	 * variable-length buffer sizes.
	 */
	if (len > RPMSG_BUF_SIZE - sizeof(struct rpmsg_hdr)) {
		dev_err(dev, "message is too big (%d)\n", len);
		return -EMSGSIZE;
	}

	/* grab a buffer */
	msg = get_a_tx_buf(vrp);
	if (!msg && !wait)
		return -ENOMEM;

	/* no free buffer ? wait for one (but bail after 15 seconds) */
	while (!msg) {
		/* enable "tx-complete" interrupts, if not already enabled */
		rpmsg_upref_sleepers(vrp);

		/*
		 * sleep until a free buffer is available or 15 secs elapse.
		 * the timeout period is not configurable because there's
		 * little point in asking drivers to specify that.
		 * if later this happens to be required, it'd be easy to add.
		 */
		err = wait_event_interruptible_timeout(vrp->sendq,
					(msg = get_a_tx_buf(vrp)),
					msecs_to_jiffies(15000));

		/* disable "tx-complete" interrupts if we're the last sleeper */
		rpmsg_downref_sleepers(vrp);

		/* timeout ? */
		if (!err) {
			dev_err(dev, "timeout waiting for a tx buffer\n");
			return -ERESTARTSYS;
		}
	}

	msg->len = len;
	msg->flags = 0;
	msg->src = src;
	msg->dst = dst;
	msg->reserved = 0;
	memcpy(msg->data, data, len);

	dev_dbg(dev, "TX From 0x%x, To 0x%x, Len %d, Flags %d, Reserved %d\n",
					msg->src, msg->dst, msg->len,
					msg->flags, msg->reserved);
	print_hex_dump(KERN_DEBUG, "rpmsg_virtio TX: ", DUMP_PREFIX_NONE, 16, 1,
					msg, sizeof(*msg) + msg->len, true);

	sg_init_one(&sg, msg, sizeof(*msg) + len);

	mutex_lock(&vrp->tx_lock);

	/* add message to the remote processor's virtqueue */
	err = virtqueue_add_outbuf(vrp->svq, &sg, 1, msg, GFP_KERNEL);
	if (err) {
		/*
		 * need to reclaim the buffer here, otherwise it's lost
		 * (memory won't leak, but rpmsg won't use it again for TX).
		 * this will wait for a buffer management overhaul.
		 */
		dev_err(dev, "virtqueue_add_outbuf failed: %d\n", err);
		goto out;
	}

	/* tell the remote processor it has a pending message to read */
	virtqueue_kick(vrp->svq);
out:
	mutex_unlock(&vrp->tx_lock);
	return err;
}
void diag_process_hdlc(void *data, unsigned len)
{
	struct diag_hdlc_decode_type hdlc;
	int ret, type = 0;
#if HPST_FUN
	unsigned char *buf_9k = NULL;
	int path;
#endif
#ifdef DIAG_DEBUG
	int i;
	DIAGFWD_INFO("\n HDLC decode function, len of data  %d\n", len);
#endif
	hdlc.dest_ptr = driver->hdlc_buf;
	hdlc.dest_size = USB_MAX_OUT_BUF;
	hdlc.src_ptr = data;
	hdlc.src_size = len;
	hdlc.src_idx = 0;
	hdlc.dest_idx = 0;
	hdlc.escaping = 0;

	ret = diag_hdlc_decode(&hdlc);

	if (ret)
		type = diag_process_apps_pkt(driver->hdlc_buf,
							  hdlc.dest_idx - 3);
	else if (driver->debug_flag) {
		DIAGFWD_ERR("Packet dropped due to bad HDLC coding/CRC"
				" errors or partial packet received, packet"
				" length = %d\n", len);
		print_hex_dump(KERN_DEBUG, "Dropped Packet Data: ", 16, 1,
					   DUMP_PREFIX_ADDRESS, data, len, 1);
		driver->debug_flag = 0;
	}
#ifdef CONFIG_DIAG_NO_MODEM
	if (type == 1) { /* implies this packet is NOT meant for apps */
		if (driver->chqdsp)
			smd_write(driver->chqdsp, driver->hdlc_buf,
							 hdlc.dest_idx - 3);
		type = 0;
	}
#endif /* NO MODEM present */

#ifdef DIAG_DEBUG
	printk(KERN_INFO "\n hdlc.dest_idx = %d", hdlc.dest_idx);
	for (i = 0; i < hdlc.dest_idx; i++)
		printk(KERN_DEBUG "\t%x", *(((unsigned char *)
							driver->hdlc_buf)+i));
#endif /* DIAG DEBUG */
	/* ignore 2 bytes for CRC, one for 7E and send */
	if ((driver->ch) && (ret) && (type) && (hdlc.dest_idx > 3)) {
		APPEND_DEBUG('g');
#if defined(CONFIG_ARCH_MSM8X60_LTE) || defined(CONFIG_ARCH_MSM8X60)
		smd_write(driver->ch, driver->hdlc_buf, hdlc.dest_idx - 3);
#else //defined(CONFIG_MACH_MECHA)
		smd_write(driver->ch, data, len);
#endif
		if (diag7k_debug_mask)
		print_hex_dump(KERN_DEBUG, "Written Packet Data to SMD: ", 16,
			       1, DUMP_PREFIX_ADDRESS, data, len, 1);
		APPEND_DEBUG('h');
#ifdef DIAG_DEBUG
		printk(KERN_INFO "writing data to SMD, pkt length %d \n", len);
		print_hex_dump(KERN_DEBUG, "Written Packet Data to SMD: ", 16,
			       1, DUMP_PREFIX_ADDRESS, data, len, 1);
#endif /* DIAG DEBUG */
	}

}
Ejemplo n.º 28
0
static void greth_print_rx_packet(void *addr, int len)
{
	print_hex_dump(KERN_DEBUG, "RX: ", DUMP_PREFIX_OFFSET, 16, 1,
			addr, len, true);
}
Ejemplo n.º 29
0
static void smies_dump_registers(struct s5p_smies_device *smies)
{
    dev_dbg(smies->dev, "dumping registers\n");
    print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_ADDRESS, 32, 4, smies->reg_base,
                   0x0200, false);
}