static usbd_status alloc_all_endpoints(struct umidi_softc *sc) { usbd_status err; struct umidi_endpoint *ep; int i; if (UMQ_ISTYPE(sc, UMQ_TYPE_FIXED_EP)) { err = alloc_all_endpoints_fixed_ep(sc); } else if (UMQ_ISTYPE(sc, UMQ_TYPE_YAMAHA)) { err = alloc_all_endpoints_yamaha(sc); } else { err = alloc_all_endpoints_genuine(sc); } if (err!=USBD_NORMAL_COMPLETION) return err; ep = sc->sc_endpoints; for (i=sc->sc_out_num_endpoints+sc->sc_in_num_endpoints; i>0; i--) { err = alloc_pipe(ep++); if (err!=USBD_NORMAL_COMPLETION) { for (; ep!=sc->sc_endpoints; ep--) free_pipe(ep-1); free(sc->sc_endpoints, M_USBDEV); sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL; break; } } return err; }
int Y_Reclaim(int id) { util_t *util = util_rm(id); if(util == NULL) { log_err("Unable to remove util, id %d", id); return ERROR; } int rc = 0; void * data = util->data; switch(util->type) { case LOCK: rc = free_lock((lock_t*)data); break; case CVAR: rc = free_cvar((cvar_t*)data); break; case PIPE: rc = free_pipe((pipe_t*)data); break; default: break; } if(rc) { log_err("Fail to release util %d", id); return ERROR; } return 0; }
static void free_all_endpoints(struct umidi_softc *sc) { int i; for (i=0; i<sc->sc_in_num_endpoints+sc->sc_out_num_endpoints; i++) free_pipe(&sc->sc_endpoints[i]); if (sc->sc_endpoints != NULL) free(sc->sc_endpoints, M_USBDEV); sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL; }
static int free_pipe_list(struct pipe *head, int indent) { int rcode = 0; /* if list has no members */ struct pipe *pi, *next; char *ind = indenter(indent); for (pi = head; pi; pi = next) { final_printf("%s pipe reserved mode %d\n", ind, pi->r_mode); rcode = free_pipe(pi, indent); final_printf("%s pipe followup code %d\n", ind, pi->followup); next = pi->next; pi->next = NULL; free(pi); } return rcode; }
static usbd_status alloc_all_endpoints(struct umidi_softc *sc) { usbd_status err; struct umidi_endpoint *ep; int i; sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0; if (UMQ_ISTYPE(sc, UMQ_TYPE_FIXED_EP)) err = alloc_all_endpoints_fixed_ep(sc); else if (UMQ_ISTYPE(sc, UMQ_TYPE_YAMAHA)) err = alloc_all_endpoints_yamaha(sc); else err = alloc_all_endpoints_genuine(sc); if (err!=USBD_NORMAL_COMPLETION) return err; ep = sc->sc_endpoints; for (i=sc->sc_out_num_endpoints+sc->sc_in_num_endpoints; i>0; i--) { err = alloc_pipe(ep); if (err!=USBD_NORMAL_COMPLETION) { while(ep != sc->sc_endpoints) { ep--; free_pipe(ep); } free(sc->sc_endpoints, M_USBDEV, (sc->sc_out_num_endpoints + sc->sc_in_num_endpoints) * sizeof(*sc->sc_endpoints)); sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL; break; } ep++; } return err; }
static void configure_ehci(void *data) { struct usb_ehci_s *cntl = data; // Allocate ram for schedule storage struct ehci_framelist *fl = memalign_high(sizeof(*fl), sizeof(*fl)); struct ehci_qh *intr_qh = memalign_high(EHCI_QH_ALIGN, sizeof(*intr_qh)); struct ehci_qh *async_qh = memalign_high(EHCI_QH_ALIGN, sizeof(*async_qh)); if (!fl || !intr_qh || !async_qh) { warn_noalloc(); goto fail; } // XXX - check for halted? // Reset the HC u32 cmd = readl(&cntl->regs->usbcmd); writel(&cntl->regs->usbcmd, (cmd & ~(CMD_ASE | CMD_PSE)) | CMD_HCRESET); u64 end = calc_future_tsc(250); for (;;) { cmd = readl(&cntl->regs->usbcmd); if (!(cmd & CMD_HCRESET)) break; if (check_tsc(end)) { warn_timeout(); goto fail; } yield(); } // Disable interrupts (just to be safe). writel(&cntl->regs->usbintr, 0); // Set schedule to point to primary intr queue head memset(intr_qh, 0, sizeof(*intr_qh)); intr_qh->next = EHCI_PTR_TERM; intr_qh->info2 = (0x01 << QH_SMASK_SHIFT); intr_qh->token = QTD_STS_HALT; intr_qh->qtd_next = intr_qh->alt_next = EHCI_PTR_TERM; int i; for (i=0; i<ARRAY_SIZE(fl->links); i++) fl->links[i] = (u32)intr_qh | EHCI_PTR_QH; writel(&cntl->regs->periodiclistbase, (u32)fl); // Set async list to point to primary async queue head memset(async_qh, 0, sizeof(*async_qh)); async_qh->next = (u32)async_qh | EHCI_PTR_QH; async_qh->info1 = QH_HEAD; async_qh->token = QTD_STS_HALT; async_qh->qtd_next = async_qh->alt_next = EHCI_PTR_TERM; cntl->async_qh = async_qh; writel(&cntl->regs->asynclistbase, (u32)async_qh); // Enable queues writel(&cntl->regs->usbcmd, cmd | CMD_ASE | CMD_PSE | CMD_RUN); // Set default of high speed for root hub. writel(&cntl->regs->configflag, 1); cntl->checkports = readl(&cntl->caps->hcsparams) & HCS_N_PORTS_MASK; // Find devices int count = check_ehci_ports(cntl); free_pipe(cntl->usb.defaultpipe); if (count) // Success return; // No devices found - shutdown and free controller. writel(&cntl->regs->usbcmd, cmd & ~CMD_RUN); msleep(4); // 2ms to stop reading memory - XXX fail: free(fl); free(intr_qh); free(async_qh); free(cntl); }
static int test_update(void) { logbuffer_t logbuf = logbuffer_FREE; thread_t * thread = 0; pipe_t pipe = pipe_FREE; uint8_t buffer[1024]; uint8_t readbuffer[1024+1]; // prepare TEST(0 == init_pipe(&pipe)); logbuf = (logbuffer_t) logbuffer_INIT(sizeof(buffer), buffer, pipe.write); // TEST truncate_logbuffer for (unsigned i = 0; i < 32; ++i) { logbuf.logsize = 32; logbuf.addr[i] = 'a'; truncate_logbuffer(&logbuf, i); TEST(logbuf.addr == buffer); TEST(logbuf.size == sizeof(buffer)); TEST(logbuf.io == pipe.write); TEST(logbuf.addr[i] == 0); TEST(logbuf.logsize == i); } // TEST truncate_logbuffer: parameter with bigger or equal size are ignored for (unsigned i = 0; i < 32; ++i) { logbuf.logsize = i; logbuf.addr[i] = 'a'; logbuf.addr[i+1] = 'a'; truncate_logbuffer(&logbuf, i+1); truncate_logbuffer(&logbuf, i); TEST(logbuf.addr == buffer); TEST(logbuf.size == sizeof(buffer)); TEST(logbuf.io == pipe.write); TEST(logbuf.addr[i] == 'a'); TEST(logbuf.addr[i+1] == 'a'); TEST(logbuf.logsize == i); } // TEST write_logbuffer memset(readbuffer, 0, sizeof(readbuffer)); for (unsigned i = 0; i < sizeof(buffer); ++i) { buffer[i] = (uint8_t)i; } logbuf.logsize = logbuf.size; // test TEST( 0 == write_logbuffer(&logbuf)); // check logbuf TEST( logbuf.addr == buffer); TEST( logbuf.size == sizeof(buffer)); TEST( logbuf.logsize == sizeof(buffer)); TEST( logbuf.io == pipe.write); // check content of pipe static_assert(sizeof(readbuffer) > sizeof(buffer), "check that only sizeof(buffer) are written"); TEST(sizeof(buffer) == read(pipe.read, readbuffer, sizeof(readbuffer))); for (unsigned i = 0; i < sizeof(buffer); ++i) { TEST(buffer[i] == readbuffer[i]); } // TEST printheader_logbuffer logbuf.logsize = 0; log_header_t header = log_header_INIT("test_update", "file", 123456); printheader_logbuffer(&logbuf, &header); TEST(0 == compare_header(logbuf.logsize, logbuf.addr, "test_update", "file", 123456)); for (size_t len = logbuf.logsize, i = 1; i < 10; ++i) { printheader_logbuffer(&logbuf, &header); TEST((i+1)*len == logbuf.logsize); TEST(0 == compare_header(len, logbuf.addr + i*len, "test_update", "file", 123456)); } // TEST printheader_logbuffer: other thread TEST(0 == newgeneric_thread(&thread, &thread_printheader, &logbuf)); TEST(0 == join_thread(thread)); TEST(0 == returncode_thread(thread)); TEST(0 == delete_thread(&thread)); // TEST printheader_logbuffer: adds " ..." at end in case of truncated message logbuf.logsize = logbuf.size - 10; logbuf.addr[logbuf.logsize] = 0; printheader_logbuffer(&logbuf, &header); TEST(logbuf.logsize == logbuf.size - 1) TEST(0 == memcmp(logbuf.addr + logbuf.size - 10, "[", 1)); TEST(0 == memcmp(logbuf.addr + logbuf.size - 5, " ...", 5)); // TEST vprintf_logbuffer: append on already stored content for (unsigned i = 0; i < sizeof(buffer)-100; ++i) { memset(buffer, 0, sizeof(buffer)); memset(readbuffer, 0, sizeof(readbuffer)); logbuf.logsize = i; printf_logbuffer(&logbuf, "%d : %s : %c;;", i, "OK!", '0'); snprintf((char*)readbuffer + i, 100, "%d : %s : %c;;", i, "OK!", '0'); TEST(0 == memcmp(buffer, readbuffer, sizeof(buffer))); } // TEST vprintf_logbuffer: different formats logbuf.logsize = 0; printf_logbuffer(&logbuf, "%%%s%%", "str" ); printf_logbuffer(&logbuf, "%"PRIi8";", (int8_t)-1); printf_logbuffer(&logbuf, "%"PRIu8";", (uint8_t)1); printf_logbuffer(&logbuf, "%"PRIi16";", (int16_t)-256); printf_logbuffer(&logbuf, "%"PRIu16";", (uint16_t)256); printf_logbuffer(&logbuf, "%"PRIi32";", (int32_t)-65536); printf_logbuffer(&logbuf, "%"PRIu32";", (uint32_t)65536); printf_logbuffer(&logbuf, "%zd;", (ssize_t)-65536); printf_logbuffer(&logbuf, "%zu;", (size_t)65536); printf_logbuffer(&logbuf, "%g;", 2e100); printf_logbuffer(&logbuf, "%.0f;", (double)1234567); const char * result = "%str%-1;1;-256;256;-65536;65536;-65536;65536;2e+100;1234567;"; TEST(strlen(result) == logbuf.logsize); TEST(0 == memcmp(logbuf.addr, result, logbuf.logsize)); // TEST vprintf_logwriter: adds " ..." at end in case of truncated message char strtoobig[100]; memset(strtoobig, '1', sizeof(strtoobig)); logbuf.logsize = logbuf.size - sizeof(strtoobig); logbuf.addr[logbuf.logsize] = 0; printf_logbuffer(&logbuf, "%.100s", strtoobig); TEST(logbuf.logsize == logbuf.size - 1) TEST(0 == memcmp(logbuf.addr + logbuf.size - sizeof(strtoobig), strtoobig, sizeof(strtoobig)-5)); TEST(0 == memcmp(logbuf.addr + logbuf.size - 5, " ...", 5)); // TEST vprintf_logbuffer: format == 0 logbuf.logsize = 0; printf_logbuffer(&logbuf, 0); // nothing printed TEST(0 == logbuf.logsize); // TEST vprintf_logbuffer: sizefree_logbuffer() == 0 logbuf.logsize = logbuf.size; memset(logbuf.addr, 255, logbuf.size); printf_logbuffer(&logbuf, "%d", 12345); // check logbuf not changed TEST(buffer == logbuf.addr); TEST(sizeof(buffer) == logbuf.size); TEST(sizeof(buffer) == logbuf.logsize); TEST(pipe.write == logbuf.io); // check content of logbuf not changed except for " ..." for (size_t i = 0; i < logbuf.logsize - 5; ++i) { TEST(255 == logbuf.addr[i]); } TEST(0 == memcmp(logbuf.addr + logbuf.logsize - 5, " ...", 4)); TEST(255 == logbuf.addr[logbuf.logsize-1]); // TEST vprintf_logbuffer: logbuffer_t.size <= 5 for (size_t s = 5; s <= 5; --s) { TEST(sizeof(buffer) == logbuf.size); logbuf.size = s; logbuf.logsize = 0; memset(logbuf.addr, 255, s); printf_logbuffer(&logbuf, "%d", 12345); // check logbuf TEST(buffer == logbuf.addr); TEST(s == logbuf.size); TEST((s?s-1:0) == logbuf.logsize); TEST(pipe.write == logbuf.io); // check content of logbuf if (s == 5) { // " ..." TEST(0 == memcmp(logbuf.addr, " ...", 5)); } else { // truncated 12345 for (size_t i = 0; i < logbuf.logsize; ++i) { TEST(i+'1' == logbuf.addr[i]); } TEST(0 == (logbuf.size ? logbuf.addr[logbuf.size-1] : 0)); } // reset logbuf.size = sizeof(buffer); } // unprepare TEST(-1 == read(pipe.read, readbuffer, sizeof(readbuffer))); TEST(0 == free_pipe(&pipe)); return 0; ONERR: delete_thread(&thread); free_pipe(&pipe); return EINVAL; }