Exemple #1
0
int cpdma_chan_stop(struct cpdma_chan *chan)
{
	struct cpdma_ctlr	*ctlr = chan->ctlr;
	struct cpdma_desc_pool	*pool = ctlr->pool;
	unsigned long		flags;
	int			ret;
	unsigned long		timeout;

	spin_lock_irqsave(&chan->lock, flags);
	if (chan->state != CPDMA_STATE_ACTIVE) {
		spin_unlock_irqrestore(&chan->lock, flags);
		return -EINVAL;
	}

	chan->state = CPDMA_STATE_TEARDOWN;
	dma_reg_write(ctlr, chan->int_clear, chan->mask);

	/* trigger teardown */
	dma_reg_write(ctlr, chan->td, chan_linear(chan));

	/* wait for teardown complete */
	timeout = jiffies + HZ/10;	/* 100 msec */
	while (time_before(jiffies, timeout)) {
		u32 cp = chan_read(chan, cp);
		if ((cp & CPDMA_TEARDOWN_VALUE) == CPDMA_TEARDOWN_VALUE)
			break;
		cpu_relax();
	}
	WARN_ON(!time_before(jiffies, timeout));
	chan_write(chan, cp, CPDMA_TEARDOWN_VALUE);

	/* handle completed packets */
	spin_unlock_irqrestore(&chan->lock, flags);
	do {
		ret = __cpdma_chan_process(chan);
		if (ret < 0)
			break;
	} while ((ret & CPDMA_DESC_TD_COMPLETE) == 0);
	spin_lock_irqsave(&chan->lock, flags);

	/* remaining packets haven't been tx/rx'ed, clean them up */
	while (chan->head) {
		struct cpdma_desc __iomem *desc = chan->head;
		dma_addr_t next_dma;

		next_dma = desc_read(desc, hw_next);
		chan->head = desc_from_phys(pool, next_dma);
		chan->count--;
		chan->stats.teardown_dequeue++;

		/* issue callback without locks held */
		spin_unlock_irqrestore(&chan->lock, flags);
		__cpdma_chan_free(chan, desc, 0, -ENOSYS);
		spin_lock_irqsave(&chan->lock, flags);
	}

	chan->state = CPDMA_STATE_IDLE;
	spin_unlock_irqrestore(&chan->lock, flags);
	return 0;
}
Exemple #2
0
int cpdma_chan_dump(struct cpdma_chan *chan)
{
	unsigned long flags;
	struct device *dev = chan->ctlr->dev;

	spin_lock_irqsave(&chan->lock, flags);

	dev_info(dev, "channel %d (%s %d) state %s",
		 chan->chan_num, is_rx_chan(chan) ? "rx" : "tx",
		 chan_linear(chan), cpdma_state_str[chan->state]);
	dev_info(dev, "\thdp: %x\n", chan_read(chan, hdp));
	dev_info(dev, "\tcp: %x\n", chan_read(chan, cp));
	if (chan->rxfree) {
		dev_info(dev, "\trxfree: %x\n",
			 chan_read(chan, rxfree));
	}

	dev_info(dev, "\tstats head_enqueue: %d\n",
		 chan->stats.head_enqueue);
	dev_info(dev, "\tstats tail_enqueue: %d\n",
		 chan->stats.tail_enqueue);
	dev_info(dev, "\tstats pad_enqueue: %d\n",
		 chan->stats.pad_enqueue);
	dev_info(dev, "\tstats misqueued: %d\n",
		 chan->stats.misqueued);
	dev_info(dev, "\tstats desc_alloc_fail: %d\n",
		 chan->stats.desc_alloc_fail);
	dev_info(dev, "\tstats pad_alloc_fail: %d\n",
		 chan->stats.pad_alloc_fail);
	dev_info(dev, "\tstats runt_receive_buff: %d\n",
		 chan->stats.runt_receive_buff);
	dev_info(dev, "\tstats runt_transmit_buff: %d\n",
		 chan->stats.runt_transmit_buff);
	dev_info(dev, "\tstats empty_dequeue: %d\n",
		 chan->stats.empty_dequeue);
	dev_info(dev, "\tstats busy_dequeue: %d\n",
		 chan->stats.busy_dequeue);
	dev_info(dev, "\tstats good_dequeue: %d\n",
		 chan->stats.good_dequeue);
	dev_info(dev, "\tstats requeue: %d\n",
		 chan->stats.requeue);
	dev_info(dev, "\tstats teardown_dequeue: %d\n",
		 chan->stats.teardown_dequeue);

	spin_unlock_irqrestore(&chan->lock, flags);
	return 0;
}
Exemple #3
0
static int cmd_at_cb(int argc,
                     const char *argv[],
                     void *out_p,
                     void *in_p,
                     void *arg_p,
                     void *call_arg_p)
{
    struct chan_list_t list;
    void *chan_p;
    char c;
    char buf[32];

    std_fprintf(out_p, OSTR("type ctrl-d to exit\r\n"));

    /* Wait for data from PC and HC-0X. */
    chan_list_init(&list, buf, sizeof(buf));
    chan_list_add(&list, &uart.chin);
    chan_list_add(&list, in_p);

    /* Pass data between PC and bluetooth device. */
    while (1) {
        chan_p = chan_list_poll(&list, NULL);

        if (chan_p == in_p) {
            chan_read(chan_p, &c, sizeof(c));

            /* break if EOT is found, otherwise write to HC-0X. */
            if (c == EOT) {
                break;
            }

            chan_write(&uart.chout, &c, sizeof(c));
        } else if (chan_p == &uart.chin) {
            /* Write all output from HC-0X to the PC. */
            chan_read(chan_p, &c, sizeof(c));
            chan_write(out_p, &c, sizeof(c));
        } else {
            std_printf(OSTR("bad input channel 0x%02x\r\n"),  (int)chan_p);
        }
    }

    chan_list_destroy(&list);

    return (0);
}
Exemple #4
0
static size_t on_publish(struct mqtt_client_t *client_p,
                         const char *topic_p,
                         void *chin_p,
                         size_t size)
{
    uint8_t buf[32];
    
    chan_read(chin_p, buf, size);
    buf[size] = '\0';
    std_printf(FSTR("on_publish: %s\r\n"), &buf[0]);

    thrd_resume(self_p, 0);

    return (0);
}
Exemple #5
0
static int test_null_channels(struct harness_t *harness_p)
{
    struct chan_t chan;
    char value;

    BTASSERT(chan_init(&chan,
                       chan_read_null,
                       chan_write_null,
                       chan_size_null) == 0);

    BTASSERT(chan_read(&chan, &value, 1) == -1);
    BTASSERT(chan_write(&chan, &value, 1) == 1);
    BTASSERT(chan_size(&chan) == 1);

    return (0);
}
Exemple #6
0
static int storage_init(fat16_read_t *read_p,
                        fat16_write_t *write_p,
                        void **arg_pp)
{
    struct usb_host_device_t *device_p;
    union usb_message_t message;

    std_printf(FSTR("USB storage.\r\n"));

    /* Initialize the USB host driver. */
    usb_host_init(&usb,
                  &usb_device[0],
                  host_devices,
                  membersof(host_devices));

    usb_host_class_mass_storage_init(&mass_storage,
                                     &usb,
                                     mass_storage_devices,
                                     membersof(mass_storage_devices));
    usb_host_class_mass_storage_start(&mass_storage);

    /* Start the USB driver. */
    usb_host_start(&usb);

    chan_read(&usb.control, &message, sizeof(message));

    std_printf(FSTR("The USB control thread read a message of type %d\r\n"),
               message.header.type);

    if (message.header.type != USB_MESSAGE_TYPE_ADD) {
        std_printf(FSTR("bad message type %d\r\n"), message.header.type);
        return (-1);
    }

    device_p = usb_host_device_open(&usb, message.add.device);

    *read_p = read_block;
    *write_p = write_block;
    *arg_pp = device_p;

    return (0);

}
Exemple #7
0
void socket_stub_output(void *buf_p, size_t size)
{
    chan_read(&qoutput, buf_p, size);
}
Exemple #8
0
t_stat cdp_srv(UNIT * uptr)
{
    int                 chan = UNIT_G_CHAN(uptr->flags);
    int                 u = (uptr - cdp_unit);
    int                 pos;
    t_uint64            wd;
    int                 bit;
    t_uint64            mask;
    int                 b;
    int                 col;
    struct _card_data   *data;

    /* Channel has disconnected, abort current card. */
    if (uptr->u5 & CDPSTA_CMD && chan_stat(chan, DEV_DISCO)) {
        if ((uptr->u5 & CDPSTA_POSMASK) != 0) {
            sim_debug(DEBUG_DETAIL, &cdp_dev, "punch card\n");
            sim_punch_card(uptr, NULL);
            uptr->u5 &= ~CDPSTA_PUNCH;
        }
        uptr->u5 &= ~(CDPSTA_WRITE | CDPSTA_CMD | CDPSTA_POSMASK);
        chan_clear(chan, DEV_WEOR | DEV_SEL);
        sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d disconnect\n", u);
    }

    /* Check to see if we have timed out */
    if (uptr->wait != 0) {
        uptr->wait--;
        /* If at end of record and channel is still active, do another read */
        if (
            ((uptr->u5 & (CDPSTA_CMD | CDPSTA_IDLE | CDPSTA_WRITE | CDPSTA_ON))
                  == (CDPSTA_CMD | CDPSTA_IDLE | CDPSTA_ON)) && uptr->wait > 30
                  && chan_test(chan, STA_ACTIVE)) {
            uptr->u5 |= CDPSTA_WRITE;
            uptr->u5 &= ~CDPSTA_IDLE;
            chan_set(chan, DEV_WRITE);
            chan_clear(chan, DEV_WEOR);
            sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d restarting\n", u);
        }
        sim_activate(uptr, us_to_ticks(1000));  /* activate */
        return SCPE_OK;
    }

    /* If no write request, go to idle mode */
    if ((uptr->u5 & CDPSTA_WRITE) == 0) {
        if ((uptr->u5 & (CDPSTA_IDLE | CDPSTA_ON)) ==
            (CDPSTA_IDLE | CDPSTA_ON)) {
            uptr->wait = 85;    /* Delay 85ms */
            uptr->u5 &= ~CDPSTA_IDLE;   /* Not running */
            sim_activate(uptr, us_to_ticks(1000));
        } else {
            uptr->u5 &= ~CDPSTA_ON;     /* Turn motor off */
        }
        return SCPE_OK;
    }

    /* Motor is up to speed now */
    uptr->u5 |= CDPSTA_ON;
    uptr->u5 &= ~CDPSTA_IDLE;   /* Not running */

    if (dev_pulse[chan] & PUNCH_M)
        uptr->u5 |= CDPSTA_PUNCH;

    pos = (uptr->u5 & CDPSTA_POSMASK) >> CDPSTA_POSSHIFT;
    if (pos == 24) {
        if (chan_test(chan, STA_ACTIVE)) {
            sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d set EOR\n", u);
            chan_set(chan, DEV_REOR);
        } else {
            chan_clear(chan, DEV_WEOR | DEV_SEL);
            sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d disconnect\n", u);
        }
        sim_debug(DEBUG_DETAIL, &cdp_dev, "punch card\n");
        sim_punch_card(uptr, NULL);
        uptr->u5 |= CDPSTA_IDLE;
        uptr->u5 &= ~(CDPSTA_WRITE | CDPSTA_POSMASK | CDPSTA_PUNCH);
        uptr->wait = 85;
        sim_activate(uptr, us_to_ticks(1000));
        return SCPE_OK;
    }



    sim_debug(DEBUG_DATA, &cdp_dev, "unit=%d write column %d ", u, pos);
    wd = 0;
    data = (struct _card_data *)uptr->up7;
    switch (chan_read(chan, &wd, 0)) {
    case DATA_OK:
        sim_debug(DEBUG_DATA, &cdp_dev, " %012llo\n", wd);
        /* Bit flip into temp buffer */
        bit = 1 << (pos / 2);
        mask = 1;
        b = (pos & 1)?36:0;

        for (col = 35; col >= 0; mask <<= 1, col--) {
            if (wd & mask)
                data->image[col + b] |= bit;
        }
        pos++;
        uptr->wait = 0;
        uptr->u5 &= ~CDPSTA_POSMASK;
        uptr->u5 |= (pos << CDPSTA_POSSHIFT) & CDPSTA_POSMASK;
        sim_activate(uptr, (pos & 1) ? us_to_ticks(300) : us_to_ticks(8000));
        return SCPE_OK;
    case END_RECORD:
        sim_debug(DEBUG_DATA, &cdp_dev, "eor\n");
        uptr->wait = 8 * (12 - (pos / 2)) /*+ 85*/;
        uptr->u5 &= ~(CDPSTA_POSMASK);
        uptr->u5 |= (24 << CDPSTA_POSSHIFT) & CDPSTA_POSMASK;
        break;
    case TIME_ERROR:
        sim_debug(DEBUG_DATA, &cdp_dev, "no data\n");
        uptr->wait = 8 * (12 - (pos / 2)) /*+ 85*/;
        uptr->u5 &= ~(CDPSTA_POSMASK);
        uptr->u5 |= (24 << CDPSTA_POSSHIFT) & CDPSTA_POSMASK;
        break;
    }

    sim_activate(uptr, us_to_ticks(1000));
    return SCPE_OK;
}