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; }
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; }
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); }
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); }
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); }
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); }
void socket_stub_output(void *buf_p, size_t size) { chan_read(&qoutput, buf_p, size); }
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; }