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;
}
Exemple #2
0
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;
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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);
}
Exemple #7
0
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;
}