Пример #1
0
static inline void mon_read_debug(struct mon_msg *monmsg,
                  struct mon_private *monpriv)
{
#ifdef MON_DEBUG
    u8 msg_type[2], mca_type;
    unsigned long records_len;

    records_len = mon_rec_end(monmsg) - mon_rec_start(monmsg) + 1;

    memcpy(msg_type, &monmsg->msg.class, 2);
    EBCASC(msg_type, 2);
    mca_type = mon_mca_type(monmsg, 0);
    EBCASC(&mca_type, 1);

    P_DEBUG("read, mon_read_index = %i, mon_write_index = %i\n",
        monpriv->read_index, monpriv->write_index);
    P_DEBUG("read, pathid = 0x%04X, msgid = 0x%08X, trgcls = 0x%08X\n",
        monpriv->path->pathid, monmsg->msg.id, monmsg->msg.class);
    P_DEBUG("read, msg_type = '%c%c', mca_type = '%c' / 0x%X / 0x%X\n",
        msg_type[0], msg_type[1], mca_type ? mca_type : 'X',
        mon_mca_type(monmsg, 1), mon_mca_type(monmsg, 2));
    P_DEBUG("read, MCA: start = 0x%lX, end = 0x%lX\n",
        mon_mca_start(monmsg), mon_mca_end(monmsg));
    P_DEBUG("read, REC: start = 0x%X, end = 0x%X, len = %lu\n\n",
        mon_rec_start(monmsg), mon_rec_end(monmsg), records_len);
    if (mon_mca_size(monmsg) > 12)
        P_DEBUG("READ, MORE THAN ONE MCA\n\n");
#endif
}
Пример #2
0
static void
smsg_message_pending(iucv_MessagePending *eib, void *pgm_data)
{
	struct smsg_callback *cb;
	unsigned char *msg;
	unsigned short len;
	int rc;

	len = eib->ln1msg2.ipbfln1f;
	msg = kmalloc(len + 1, GFP_ATOMIC|GFP_DMA);
	if (!msg) {
		iucv_reject(eib->ippathid, eib->ipmsgid, eib->iptrgcls);
		return;
	}
	rc = iucv_receive(eib->ippathid, eib->ipmsgid, eib->iptrgcls,
			  msg, len, 0, 0, 0);
	if (rc == 0) {
		msg[len] = 0;
		EBCASC(msg, len);
		spin_lock(&smsg_list_lock);
		list_for_each_entry(cb, &smsg_list, list)
			if (strncmp(msg + 8, cb->prefix, cb->len) == 0) {
				cb->callback(msg + 8);
				break;
			}
		spin_unlock(&smsg_list_lock);
	}
Пример #3
0
static void smsg_message_pending(struct iucv_path *path,
				 struct iucv_message *msg)
{
	struct smsg_callback *cb;
	unsigned char *buffer;
	unsigned char sender[9];
	int rc, i;

	buffer = kmalloc(msg->length + 1, GFP_ATOMIC | GFP_DMA);
	if (!buffer) {
		iucv_message_reject(path, msg);
		return;
	}
	rc = iucv_message_receive(path, msg, 0, buffer, msg->length, NULL);
	if (rc == 0) {
		buffer[msg->length] = 0;
		EBCASC(buffer, msg->length);
		memcpy(sender, buffer, 8);
		sender[8] = 0;
		/* Remove trailing whitespace from the sender name. */
		for (i = 7; i >= 0; i--) {
			if (sender[i] != ' ' && sender[i] != '\t')
				break;
			sender[i] = 0;
		}
		spin_lock(&smsg_list_lock);
		list_for_each_entry(cb, &smsg_list, list)
			if (strncmp(buffer + 8, cb->prefix, cb->len) == 0) {
				cb->callback(sender, buffer + 8);
				break;
			}
		spin_unlock(&smsg_list_lock);
	}
Пример #4
0
static void sclp_ocf_handler(struct evbuf_header *evbuf)
{
	struct gds_vector *v;
	struct gds_subvector *sv, *netid, *cpc;
	size_t size;

	/*                        */
	v = sclp_find_gds_vector(evbuf + 1, (void *) evbuf + evbuf->length,
				 0x9f00);
	if (!v)
		return;
	/*                                                */
	v = sclp_find_gds_vector(v + 1, (void *) v + v->length, 0x9f22);
	if (!v)
		return;
	/*                                              */
	sv = sclp_find_gds_subvector(v + 1, (void *) v + v->length, 0x81);
	if (!sv)
		return;
	/*                                            */
	netid = sclp_find_gds_subvector(sv + 1, (void *) sv + sv->length, 1);
	/*                                            */
	cpc = sclp_find_gds_subvector(sv + 1, (void *) sv + sv->length, 2);
	/*                                 */
	spin_lock(&sclp_ocf_lock);
	if (netid) {
		size = min(OCF_LENGTH_HMC_NETWORK, (size_t) netid->length);
		memcpy(hmc_network, netid + 1, size);
		EBCASC(hmc_network, size);
		hmc_network[size] = 0;
	}
	if (cpc) {
		size = min(OCF_LENGTH_CPC_NAME, (size_t) cpc->length);
		memcpy(cpc_name, cpc + 1, size);
		EBCASC(cpc_name, size);
		cpc_name[size] = 0;
	}
	spin_unlock(&sclp_ocf_lock);
	schedule_work(&sclp_ocf_change_work);
}
static inline void part_hdr__part_name(enum diag204_format type, void *hdr,
				       char *name)
{
	if (type == DIAG204_INFO_SIMPLE)
		memcpy(name, ((struct diag204_part_hdr *)hdr)->part_name,
		       DIAG204_LPAR_NAME_LEN);
	else /* DIAG204_INFO_EXT */
		memcpy(name, ((struct diag204_x_part_hdr *)hdr)->part_name,
		       DIAG204_LPAR_NAME_LEN);
	EBCASC(name, DIAG204_LPAR_NAME_LEN);
	name[DIAG204_LPAR_NAME_LEN] = 0;
	strim(name);
}
static int diag224_get_name_table(void)
{
	/* memory must be below 2GB */
	diag224_cpu_names = (char *) __get_free_page(GFP_KERNEL | GFP_DMA);
	if (!diag224_cpu_names)
		return -ENOMEM;
	if (diag224(diag224_cpu_names)) {
		free_page((unsigned long) diag224_cpu_names);
		return -EOPNOTSUPP;
	}
	EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16);
	return 0;
}
Пример #7
0
static void int_to_ext_kekl(struct tape3592_kekl *in,
			    struct tape390_kekl *out)
{
	memset(out, 0, sizeof(*out));
	if(in->flags & 0x40)
		out->type = TAPE390_KEKL_TYPE_HASH;
	else
		out->type = TAPE390_KEKL_TYPE_LABEL;
	if(in->flags & 0x80)
		out->type_on_tape = TAPE390_KEKL_TYPE_HASH;
	else
		out->type_on_tape = TAPE390_KEKL_TYPE_LABEL;
	memcpy(out->label, in->label, sizeof(in->label));
	EBCASC(out->label, sizeof(in->label));
	strim(out->label);
}
Пример #8
0
static ssize_t qeth_dev_portname_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct qeth_card *card = dev_get_drvdata(dev);
	char portname[9] = {0, };

	if (!card)
		return -EINVAL;

	if (card->info.portname_required) {
		memcpy(portname, card->info.portname + 1, 8);
		EBCASC(portname, 8);
		return sprintf(buf, "%s\n", portname);
	} else
		return sprintf(buf, "no portname required\n");
}
Пример #9
0
/*
 * prints debug data in ebcdic format
 */
static int
ebcdic_format_fn(debug_info_t * id, debug_view_t *view,
		 char *out_buf, const char *in_buf)
{
	int i, rc = 0;

	if (out_buf == NULL || in_buf == NULL) {
		rc = id->buf_size + 1;
		goto out;
	}
	for (i = 0; i < id->buf_size; i++) {
		char c = in_buf[i];
		EBCASC(&c, 1);
		if (!isprint(c))
			rc += sprintf(out_buf + rc, ".");
		else
			rc += sprintf(out_buf + rc, "%c", c);
	}
	rc += sprintf(out_buf + rc, "\n");
      out:
	return rc;
}
Пример #10
0
/*
 * Interrupt routine, called from common io layer
 */
static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
			struct irb *irb)
{
	struct raw3215_info *raw;
	struct raw3215_req *req;
	struct tty_struct *tty;
	int cstat, dstat;
	int count;

	raw = dev_get_drvdata(&cdev->dev);
	req = (struct raw3215_req *) intparm;
	tty = tty_port_tty_get(&raw->port);
	cstat = irb->scsw.cmd.cstat;
	dstat = irb->scsw.cmd.dstat;
	if (cstat != 0)
		raw3215_next_io(raw, tty);
	if (dstat & 0x01) { /* we got a unit exception */
		dstat &= ~0x01;	 /* we can ignore it */
	}
	switch (dstat) {
	case 0x80:
		if (cstat != 0)
			break;
		/* Attention interrupt, someone hit the enter key */
		raw3215_mk_read_req(raw);
		raw3215_next_io(raw, tty);
		break;
	case 0x08:
	case 0x0C:
		/* Channel end interrupt. */
		if ((raw = req->info) == NULL)
			goto put_tty;	     /* That shouldn't happen ... */
		if (req->type == RAW3215_READ) {
			/* store residual count, then wait for device end */
			req->residual = irb->scsw.cmd.count;
		}
		if (dstat == 0x08)
			break;
	case 0x04:
		/* Device end interrupt. */
		if ((raw = req->info) == NULL)
			goto put_tty;	     /* That shouldn't happen ... */
		if (req->type == RAW3215_READ && tty != NULL) {
			unsigned int cchar;

			count = 160 - req->residual;
			EBCASC(raw->inbuf, count);
			cchar = ctrlchar_handle(raw->inbuf, count, tty);
			switch (cchar & CTRLCHAR_MASK) {
			case CTRLCHAR_SYSRQ:
				break;

			case CTRLCHAR_CTRL:
				tty_insert_flip_char(&raw->port, cchar,
						TTY_NORMAL);
				tty_flip_buffer_push(&raw->port);
				break;

			case CTRLCHAR_NONE:
				if (count < 2 ||
				    (strncmp(raw->inbuf+count-2, "\252n", 2) &&
				     strncmp(raw->inbuf+count-2, "^n", 2)) ) {
					/* add the auto \n */
					raw->inbuf[count] = '\n';
					count++;
				} else
					count -= 2;
				tty_insert_flip_string(&raw->port, raw->inbuf,
						count);
				tty_flip_buffer_push(&raw->port);
				break;
			}
		} else if (req->type == RAW3215_WRITE) {
			raw->count -= req->len;
			raw->written -= req->len;
		}
		raw->flags &= ~RAW3215_WORKING;
		raw3215_free_req(req);
		/* check for empty wait */
		if (waitqueue_active(&raw->empty_wait) &&
		    raw->queued_write == NULL &&
		    raw->queued_read == NULL) {
			wake_up_interruptible(&raw->empty_wait);
		}
		raw3215_next_io(raw, tty);
		break;
	default:
		/* Strange interrupt, I'll do my best to clean up */
		if (req != NULL && req->type != RAW3215_FREE) {
			if (req->type == RAW3215_WRITE) {
				raw->count -= req->len;
				raw->written -= req->len;
			}
			raw->flags &= ~RAW3215_WORKING;
			raw3215_free_req(req);
		}
		raw3215_next_io(raw, tty);
	}
put_tty:
	tty_kref_put(tty);
}
Пример #11
0
/*
 * Interrupt routine, called from Ingo's I/O layer
 */
static void raw3215_irq(int irq, void *int_parm, struct pt_regs *regs)
{
	raw3215_info *raw;
	raw3215_req *req;
	struct tty_struct *tty;
	devstat_t *stat;
        int cstat, dstat;
	int count, slen;

	stat = (devstat_t *) int_parm;
	req = (raw3215_req *) stat->intparm;
	cstat = stat->cstat;
	dstat = stat->dstat;
	if (cstat != 0) {
		raw = raw3215_find_info(irq);
		if (raw != NULL) {
			raw->message = KERN_WARNING
				"Got nonzero channel status in raw3215_irq "
				"(dev %i, dev sts 0x%2x, sch sts 0x%2x)";
			raw->msg_dstat = dstat;
			raw->msg_cstat = cstat;
                        raw3215_sched_bh(raw);
		}
	}
        if (dstat & 0x01) { /* we got a unit exception */
		dstat &= ~0x01;  /* we can ignore it */
        }
	switch (dstat) {
	case 0x80:
		if (cstat != 0)
			break;
		/* Attention interrupt, someone hit the enter key */
		if ((raw = raw3215_find_info(irq)) == NULL)
			return;              /* That shouldn't happen ... */
		/* Setup a read request */
		raw3215_mk_read_req(raw);
                if (MACHINE_IS_P390)
                        memset(raw->inbuf, 0, RAW3215_INBUF_SIZE);
                raw3215_sched_bh(raw);
		break;
	case 0x08:
	case 0x0C:
		/* Channel end interrupt. */
		if ((raw = req->info) == NULL)
                        return;              /* That shouldn't happen ... */
		if (req->type == RAW3215_READ) {
			/* store residual count, then wait for device end */
			req->residual = stat->rescnt;
		}
		if (dstat == 0x08)
			break;
	case 0x04:
		/* Device end interrupt. */
                if ((raw = req->info) == NULL)
                        return;              /* That shouldn't happen ... */
		if (req->type == RAW3215_READ && raw->tty != NULL) {
			unsigned int cchar;

			tty = raw->tty;
			count = 160 - req->residual;
			if (MACHINE_IS_P390) {
				slen = strnlen(raw->inbuf, RAW3215_INBUF_SIZE);
				if (count > slen)
					count = slen;
			} else
			if (count >= TTY_FLIPBUF_SIZE - tty->flip.count)
				count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
			EBCASC(raw->inbuf, count);
			cchar = ctrlchar_handle(raw->inbuf, count, tty);
			switch (cchar & CTRLCHAR_MASK) {
			case CTRLCHAR_SYSRQ:
				break;

			case CTRLCHAR_CTRL:
				tty->flip.count++;
				*tty->flip.flag_buf_ptr++ = TTY_NORMAL;
				*tty->flip.char_buf_ptr++ = cchar;
				tty_flip_buffer_push(raw->tty);
				break;

			case CTRLCHAR_NONE:
				memcpy(tty->flip.char_buf_ptr,
				       raw->inbuf, count);
				if (count < 2 ||
				    (strncmp(raw->inbuf+count-2, "^n", 2) && 
				    strncmp(raw->inbuf+count-2, "\252n", 2)) ) {
					/* don't add the auto \n */
					tty->flip.char_buf_ptr[count] = '\n';
					memset(tty->flip.flag_buf_ptr,
					       TTY_NORMAL, count + 1);
					count++;
				} else
					count-=2;
				tty->flip.char_buf_ptr += count;
				tty->flip.flag_buf_ptr += count;
				tty->flip.count += count;
				tty_flip_buffer_push(raw->tty);
				break;
			}
		} else if (req->type == RAW3215_WRITE) {
			raw->count -= req->len;
                        raw->written -= req->len;
		} 
		raw->flags &= ~RAW3215_WORKING;
		raw3215_free_req(req);
		/* check for empty wait */
		if (waitqueue_active(&raw->empty_wait) &&
		    raw->queued_write == NULL &&
		    raw->queued_read == NULL) {
			wake_up_interruptible(&raw->empty_wait);
		}
                raw3215_sched_bh(raw);
		break;
	default:
		/* Strange interrupt, I'll do my best to clean up */
                if ((raw = raw3215_find_info(irq)) == NULL)
                        return;              /* That shouldn't happen ... */
                if (raw == NULL) break;
		if (req != NULL && req->type != RAW3215_FREE) {
		        if (req->type == RAW3215_WRITE) {
			        raw->count -= req->len;
                                raw->written -= req->len;
                        }
                        raw->flags &= ~RAW3215_WORKING;
                        raw3215_free_req(req);
		}
		raw->message = KERN_WARNING
			"Spurious interrupt in in raw3215_irq "
			"(dev %i, dev sts 0x%2x, sch sts 0x%2x)";
		raw->msg_dstat = dstat;
		raw->msg_cstat = cstat;
                raw3215_sched_bh(raw);
	}
	return;
}
Пример #12
0
/*
 * Interrupt routine, called from common io layer
 */
static void
raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
{
	struct raw3215_info *raw;
	struct raw3215_req *req;
	struct tty_struct *tty;
	int cstat, dstat;
	int count, slen;

	raw = cdev->dev.driver_data;
	req = (struct raw3215_req *) intparm;
	cstat = irb->scsw.cstat;
	dstat = irb->scsw.dstat;
	if (cstat != 0) {
		raw->message = KERN_WARNING
			"Got nonzero channel status in raw3215_irq "
			"(dev sts 0x%2x, sch sts 0x%2x)";
		raw->msg_dstat = dstat;
		raw->msg_cstat = cstat;
		tasklet_schedule(&raw->tasklet);
	}
	if (dstat & 0x01) { /* we got a unit exception */
		dstat &= ~0x01;	 /* we can ignore it */
	}
	switch (dstat) {
	case 0x80:
		if (cstat != 0)
			break;
		/* Attention interrupt, someone hit the enter key */
		raw3215_mk_read_req(raw);
		if (MACHINE_IS_P390)
			memset(raw->inbuf, 0, RAW3215_INBUF_SIZE);
		tasklet_schedule(&raw->tasklet);
		break;
	case 0x08:
	case 0x0C:
		/* Channel end interrupt. */
		if ((raw = req->info) == NULL)
			return;		     /* That shouldn't happen ... */
		if (req->type == RAW3215_READ) {
			/* store residual count, then wait for device end */
			req->residual = irb->scsw.count;
		}
		if (dstat == 0x08)
			break;
	case 0x04:
		/* Device end interrupt. */
		if ((raw = req->info) == NULL)
			return;		     /* That shouldn't happen ... */
		if (req->type == RAW3215_READ && raw->tty != NULL) {
			unsigned int cchar;

			tty = raw->tty;
			count = 160 - req->residual;
			if (MACHINE_IS_P390) {
				slen = strnlen(raw->inbuf, RAW3215_INBUF_SIZE);
				if (count > slen)
					count = slen;
			} else
			EBCASC(raw->inbuf, count);
			cchar = ctrlchar_handle(raw->inbuf, count, tty);
			switch (cchar & CTRLCHAR_MASK) {
			case CTRLCHAR_SYSRQ:
				break;

			case CTRLCHAR_CTRL:
				tty_insert_flip_char(tty, cchar, TTY_NORMAL);
				tty_flip_buffer_push(raw->tty);
				break;

			case CTRLCHAR_NONE:
				if (count < 2 ||
				    (strncmp(raw->inbuf+count-2, "\252n", 2) &&
				     strncmp(raw->inbuf+count-2, "^n", 2)) ) {
					/* add the auto \n */
					raw->inbuf[count] = '\n';
					count++;
				} else
					count -= 2;
				tty_insert_flip_string(tty, raw->inbuf, count);
				tty_flip_buffer_push(raw->tty);
				break;
			}
		} else if (req->type == RAW3215_WRITE) {
			raw->count -= req->len;
			raw->written -= req->len;
		}
		raw->flags &= ~RAW3215_WORKING;
		raw3215_free_req(req);
		/* check for empty wait */
		if (waitqueue_active(&raw->empty_wait) &&
		    raw->queued_write == NULL &&
		    raw->queued_read == NULL) {
			wake_up_interruptible(&raw->empty_wait);
		}
		tasklet_schedule(&raw->tasklet);
		break;
	default:
		/* Strange interrupt, I'll do my best to clean up */
		if (req != NULL && req->type != RAW3215_FREE) {
			if (req->type == RAW3215_WRITE) {
				raw->count -= req->len;
				raw->written -= req->len;
			}
			raw->flags &= ~RAW3215_WORKING;
			raw3215_free_req(req);
		}
		raw->message = KERN_WARNING
			"Spurious interrupt in in raw3215_irq "
			"(dev sts 0x%2x, sch sts 0x%2x)";
		raw->msg_dstat = dstat;
		raw->msg_cstat = cstat;
		tasklet_schedule(&raw->tasklet);
	}
	return;
}