static void start_softclock(void *dummy) { struct callout_cpu *cc; #ifdef SMP int cpu; #endif cc = CC_CPU(timeout_cpu); if (swi_add(&clk_intr_event, "clock", softclock, cc, SWI_CLOCK, INTR_MPSAFE, &softclock_ih)) panic("died while creating standard software ithreads"); cc->cc_cookie = softclock_ih; #ifdef SMP for (cpu = 0; cpu <= mp_maxid; cpu++) { if (cpu == timeout_cpu) continue; if (CPU_ABSENT(cpu)) continue; cc = CC_CPU(cpu); if (swi_add(NULL, "clock", softclock, cc, SWI_CLOCK, INTR_MPSAFE, &cc->cc_cookie)) panic("died while creating standard software ithreads"); cc->cc_callout = NULL; /* Only cpu0 handles timeout(). */ cc->cc_callwheel = malloc( sizeof(struct callout_tailq) * callwheelsize, M_CALLOUT, M_WAITOK); callout_cpu_init(cc); } #endif }
int zs_attach(device_t dev) { struct device *child[ZS_NCHAN]; struct zs_softc *sc; int i; sc = device_get_softc(dev); sc->sc_dev = dev; for (i = 0; i < ZS_NCHAN; i++) child[i] = device_add_child(dev, "zstty", -1); bus_generic_attach(dev); for (i = 0; i < ZS_NCHAN; i++) sc->sc_child[i] = device_get_softc(child[i]); swi_add(&tty_ithd, "tty:zs", zs_softintr, sc, SWI_TTY, INTR_TYPE_TTY, &sc->sc_softih); ZS_WRITE_REG(sc->sc_child[0], 2, sc->sc_child[0]->sc_creg[2]); ZS_WRITE_REG(sc->sc_child[0], 9, sc->sc_child[0]->sc_creg[9]); if (zstty_cons != NULL) { DELAY(50000); cninit(); } EVENTHANDLER_REGISTER(shutdown_final, zs_shutdown, sc, SHUTDOWN_PRI_DEFAULT); return (0); }
static int sunkbd_attach(struct uart_softc *sc) { /* * Don't attach if we didn't probe the keyboard. Note that * the UART is still marked as a system device in that case. */ if (sunkbd_softc.sc_sysdev == NULL) { device_printf(sc->sc_dev, "keyboard not present\n"); return (0); } if (sc->sc_sysdev != NULL) { sunkbd_softc.sc_uart = sc; #ifdef KBD_INSTALL_CDEV kbd_attach(&sunkbd_softc.sc_kbd); #endif sunkbd_enable(&sunkbd_softc.sc_kbd); swi_add(&tty_intr_event, uart_driver_name, sunkbd_uart_intr, &sunkbd_softc, SWI_TTY, INTR_TYPE_TTY, &sc->sc_softih); sc->sc_opened = 1; KBD_INIT_DONE(&sunkbd_softc.sc_kbd); } return (0); }
void swi_test_error_has_allready_exclusive() { struct intr_event *test_intr_event = NULL; enum arg argument = HANDLER_NOT_VISITED; void *test_ih1 = NULL; void *test_ih2 = NULL; int retval = 0; printf("== Create a thread with a exclusive handler and try to add another handler.\n"); retval = swi_add(&test_intr_event, "swi_test1", swi_test_handler, &argument, SWI_TEST_THREAD_PRIO, INTR_EXCL, &test_ih1); assert(retval == 0); retval = swi_add(&test_intr_event, "swi_test2", swi_test_handler, &argument, SWI_TEST_THREAD_PRIO, 0, &test_ih2); assert(retval == EINVAL); sleep(SWI_SLEEP_TIME); assert(argument == HANDLER_NOT_VISITED); }
void swi_test_error_handler_null() { struct intr_event *test_intr_event = NULL; enum arg argument = HANDLER_NOT_VISITED; void *test_ih = NULL; int retval = 0; printf("== Set handler to NULL.\n"); retval = swi_add(&test_intr_event, "swi_test", NULL, &argument, SWI_TEST_THREAD_PRIO, 0, &test_ih); assert(retval == EINVAL); sleep(SWI_SLEEP_TIME); assert(argument == HANDLER_NOT_VISITED); }
void swi_test_error_intr_entropy_set() { struct intr_event *test_intr_event = NULL; enum arg argument = HANDLER_NOT_VISITED; void *test_ih = NULL; int retval = 0; printf("== Set the INTR_ENTROPY flag.\n"); retval = swi_add(&test_intr_event, "swi_test", swi_test_handler, &argument, SWI_TEST_THREAD_PRIO, INTR_ENTROPY, &test_ih); assert(retval == EINVAL); sleep(SWI_SLEEP_TIME); assert(argument == HANDLER_NOT_VISITED); }
static int sunkbd_attach(struct uart_softc *sc) { if (sc->sc_sysdev != NULL) { sunkbd_softc.sc_uart = sc; kbd_attach(&sunkbd_softc.sc_kbd); sunkbd_enable(&sunkbd_softc.sc_kbd); swi_add(&tty_ithd, uart_driver_name, sunkbd_uart_intr, &sunkbd_softc, SWI_TTY, INTR_TYPE_TTY, &sc->sc_softih); sc->sc_opened = 1; } return (0); }
void swi_test_exclusive_handler() { struct intr_event *test_intr_event = NULL; enum arg argument = HANDLER_NOT_VISITED; void *test_ih = NULL; int retval = 0; printf("== Create a thread with a exclusive handler.\n"); retval = swi_add(&test_intr_event, "swi_test", swi_test_handler, &argument, SWI_TEST_THREAD_PRIO, INTR_EXCL, &test_ih); assert(retval == 0); swi_sched(test_ih, 0); sleep(SWI_SLEEP_TIME); assert(argument == HANDLER_VISITED); }
void swi_test_normal_handler() { struct intr_event *test_intr_event = NULL; enum arg argument = HANDLER_NOT_VISITED; void *test_ih = NULL; int retval = 0; printf("== Create thread and install a functional handler.\n"); retval = swi_add(&test_intr_event, "swi_test", swi_test_handler, &argument, SWI_TEST_THREAD_PRIO, 0, &test_ih); assert(retval == 0); swi_sched(test_ih, 0); sleep(SWI_SLEEP_TIME); assert(argument == HANDLER_VISITED); }
int uart_tty_attach(struct uart_softc *sc) { struct tty *tp; int unit; sc->sc_u.u_tty.tp = tp = tty_alloc(&uart_tty_class, sc); unit = device_get_unit(sc->sc_dev); if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) { sprintf(((struct consdev *)sc->sc_sysdev->cookie)->cn_name, "ttyu%r", unit); tty_init_console(tp, 0); } swi_add(&tty_intr_event, uart_driver_name, uart_tty_intr, sc, SWI_TTY, INTR_TYPE_TTY, &sc->sc_softih); tty_makedev(tp, NULL, "u%r", unit); return (0); }
/** * @brief Main vmbus driver initialization routine. * * Here, we * - initialize the vmbus driver context * - setup various driver entry points * - invoke the vmbus hv main init routine * - get the irq resource * - invoke the vmbus to add the vmbus root device * - setup the vmbus root device * - retrieve the channel offers */ static int vmbus_bus_init(void) { struct ioapic_intsrc { struct intsrc io_intsrc; u_int io_irq; u_int io_intpin:8; u_int io_vector:8; u_int io_cpu:8; u_int io_activehi:1; u_int io_edgetrigger:1; u_int io_masked:1; int io_bus:4; uint32_t io_lowreg; }; int ret; unsigned int vector = 0; struct intsrc *isrc; struct ioapic_intsrc *intpin; if (vmbus_inited) return (0); vmbus_inited = 1; ret = hv_vmbus_init(); if (ret) { if(bootverbose) printf("Error VMBUS: Hypervisor Initialization Failed!\n"); return (ret); } ret = swi_add(&hv_msg_intr_event, "hv_msg", vmbus_msg_swintr, NULL, SWI_CLOCK, 0, &msg_swintr); if (ret) goto cleanup; /* * Message SW interrupt handler checks a per-CPU page and * thus the thread needs to be bound to CPU-0 - which is where * all interrupts are processed. */ ret = intr_event_bind(hv_msg_intr_event, 0); if (ret) goto cleanup1; ret = swi_add(&hv_event_intr_event, "hv_event", hv_vmbus_on_events, NULL, SWI_CLOCK, 0, &event_swintr); if (ret) goto cleanup1; intr_res = bus_alloc_resource(vmbus_devp, SYS_RES_IRQ, &vmbus_rid, vmbus_irq, vmbus_irq, 1, RF_ACTIVE); if (intr_res == NULL) { ret = ENOMEM; /* XXXKYS: Need a better errno */ goto cleanup2; } /* * Setup interrupt filter handler */ ret = bus_setup_intr(vmbus_devp, intr_res, INTR_TYPE_NET | INTR_MPSAFE, hv_vmbus_isr, NULL, NULL, &vmbus_cookiep); if (ret != 0) goto cleanup3; ret = bus_bind_intr(vmbus_devp, intr_res, 0); if (ret != 0) goto cleanup4; isrc = intr_lookup_source(vmbus_irq); if ((isrc == NULL) || (isrc->is_event == NULL)) { ret = EINVAL; goto cleanup4; } /* vector = isrc->is_event->ie_vector; */ intpin = (struct ioapic_intsrc *)isrc; vector = intpin->io_vector; if(bootverbose) printf("VMBUS: irq 0x%x vector 0x%x\n", vmbus_irq, vector); /** * Notify the hypervisor of our irq. */ smp_rendezvous(NULL, hv_vmbus_synic_init, NULL, &vector); /** * Connect to VMBus in the root partition */ ret = hv_vmbus_connect(); if (ret) goto cleanup4; hv_vmbus_request_channel_offers(); return (ret); cleanup4: /* * remove swi, bus and intr resource */ bus_teardown_intr(vmbus_devp, intr_res, vmbus_cookiep); cleanup3: bus_release_resource(vmbus_devp, SYS_RES_IRQ, vmbus_rid, intr_res); cleanup2: swi_remove(event_swintr); cleanup1: swi_remove(msg_swintr); cleanup: hv_vmbus_cleanup(); return (ret); }
/** * @brief Main vmbus driver initialization routine. * * Here, we * - initialize the vmbus driver context * - setup various driver entry points * - invoke the vmbus hv main init routine * - get the irq resource * - invoke the vmbus to add the vmbus root device * - setup the vmbus root device * - retrieve the channel offers */ static int vmbus_bus_init(void) { int i, j, n, ret; if (vmbus_inited) return (0); vmbus_inited = 1; ret = hv_vmbus_init(); if (ret) { if(bootverbose) printf("Error VMBUS: Hypervisor Initialization Failed!\n"); return (ret); } /* * Find a free IDT slot for vmbus callback. */ hv_vmbus_g_context.hv_cb_vector = vmbus_vector_alloc(); if (hv_vmbus_g_context.hv_cb_vector == 0) { if(bootverbose) printf("Error VMBUS: Cannot find free IDT slot for " "vmbus callback!\n"); goto cleanup; } if(bootverbose) printf("VMBUS: vmbus callback vector %d\n", hv_vmbus_g_context.hv_cb_vector); /* * Notify the hypervisor of our vector. */ setup_args.vector = hv_vmbus_g_context.hv_cb_vector; CPU_FOREACH(j) { hv_vmbus_intr_cpu[j] = 0; hv_vmbus_swintr_event_cpu[j] = 0; hv_vmbus_g_context.hv_event_intr_event[j] = NULL; hv_vmbus_g_context.hv_msg_intr_event[j] = NULL; hv_vmbus_g_context.event_swintr[j] = NULL; hv_vmbus_g_context.msg_swintr[j] = NULL; for (i = 0; i < 2; i++) setup_args.page_buffers[2 * j + i] = NULL; } /* * Per cpu setup. */ CPU_FOREACH(j) { /* * Setup software interrupt thread and handler for msg handling. */ ret = swi_add(&hv_vmbus_g_context.hv_msg_intr_event[j], "hv_msg", vmbus_msg_swintr, (void *)(long)j, SWI_CLOCK, 0, &hv_vmbus_g_context.msg_swintr[j]); if (ret) { if(bootverbose) printf("VMBUS: failed to setup msg swi for " "cpu %d\n", j); goto cleanup1; } /* * Bind the swi thread to the cpu. */ ret = intr_event_bind(hv_vmbus_g_context.hv_msg_intr_event[j], j); if (ret) { if(bootverbose) printf("VMBUS: failed to bind msg swi thread " "to cpu %d\n", j); goto cleanup1; } /* * Setup software interrupt thread and handler for * event handling. */ ret = swi_add(&hv_vmbus_g_context.hv_event_intr_event[j], "hv_event", hv_vmbus_on_events, (void *)(long)j, SWI_CLOCK, 0, &hv_vmbus_g_context.event_swintr[j]); if (ret) { if(bootverbose) printf("VMBUS: failed to setup event swi for " "cpu %d\n", j); goto cleanup1; } /* * Prepare the per cpu msg and event pages to be called on each cpu. */ for(i = 0; i < 2; i++) { setup_args.page_buffers[2 * j + i] = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT | M_ZERO); if (setup_args.page_buffers[2 * j + i] == NULL) { KASSERT(setup_args.page_buffers[2 * j + i] != NULL, ("Error VMBUS: malloc failed!")); goto cleanup1; } } } if (bootverbose) printf("VMBUS: Calling smp_rendezvous, smp_started = %d\n", smp_started); smp_rendezvous(NULL, hv_vmbus_synic_init, NULL, &setup_args); /* * Connect to VMBus in the root partition */ ret = hv_vmbus_connect(); if (ret != 0) goto cleanup1; hv_vmbus_request_channel_offers(); return (ret); cleanup1: /* * Free pages alloc'ed */ for (n = 0; n < 2 * MAXCPU; n++) if (setup_args.page_buffers[n] != NULL) free(setup_args.page_buffers[n], M_DEVBUF); /* * remove swi and vmbus callback vector; */ CPU_FOREACH(j) { if (hv_vmbus_g_context.msg_swintr[j] != NULL) swi_remove(hv_vmbus_g_context.msg_swintr[j]); if (hv_vmbus_g_context.event_swintr[j] != NULL) swi_remove(hv_vmbus_g_context.event_swintr[j]); hv_vmbus_g_context.hv_msg_intr_event[j] = NULL; hv_vmbus_g_context.hv_event_intr_event[j] = NULL; } vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector); cleanup: hv_vmbus_cleanup(); return (ret); }
static int bt3c_pccard_attach(device_t dev) { bt3c_softc_p sc = (bt3c_softc_p) device_get_softc(dev); /* Allocate I/O ports */ sc->iobase_rid = 0; sc->iobase = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &sc->iobase_rid, 8, RF_ACTIVE); if (sc->iobase == NULL) { device_printf(dev, "Could not allocate I/O ports\n"); goto bad; } sc->iot = rman_get_bustag(sc->iobase); sc->ioh = rman_get_bushandle(sc->iobase); /* Allocate IRQ */ sc->irq_rid = 0; sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, RF_ACTIVE); if (sc->irq == NULL) { device_printf(dev, "Could not allocate IRQ\n"); goto bad; } sc->irq_cookie = NULL; if (bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, NULL, bt3c_intr, sc, &sc->irq_cookie) != 0) { device_printf(dev, "Could not setup ISR\n"); goto bad; } /* Attach handler to TTY SWI thread */ sc->ith = NULL; if (swi_add(&tty_intr_event, device_get_nameunit(dev), bt3c_swi_intr, sc, SWI_TTY, 0, &sc->ith) < 0) { device_printf(dev, "Could not setup SWI ISR\n"); goto bad; } /* Create Netgraph node */ if (ng_make_node_common(&typestruct, &sc->node) != 0) { device_printf(dev, "Could not create Netgraph node\n"); sc->node = NULL; goto bad; } /* Name Netgraph node */ if (ng_name_node(sc->node, device_get_nameunit(dev)) != 0) { device_printf(dev, "Could not name Netgraph node\n"); NG_NODE_UNREF(sc->node); sc->node = NULL; goto bad; } sc->dev = dev; sc->debug = NG_BT3C_WARN_LEVEL; sc->inq.ifq_maxlen = sc->outq.ifq_maxlen = BT3C_DEFAULTQLEN; mtx_init(&sc->inq.ifq_mtx, "BT3C inq", NULL, MTX_DEF); mtx_init(&sc->outq.ifq_mtx, "BT3C outq", NULL, MTX_DEF); sc->state = NG_BT3C_W4_PKT_IND; sc->want = 1; NG_NODE_SET_PRIVATE(sc->node, sc); return (0); bad: if (sc->ith != NULL) { swi_remove(sc->ith); sc->ith = NULL; } if (sc->irq != NULL) { if (sc->irq_cookie != NULL) bus_teardown_intr(dev, sc->irq, sc->irq_cookie); bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); sc->irq = NULL; sc->irq_rid = 0; } if (sc->iobase != NULL) { bus_release_resource(dev, SYS_RES_IOPORT, sc->iobase_rid, sc->iobase); sc->iobase = NULL; sc->iobase_rid = 0; } return (ENXIO); } /* bt3c_pccacd_attach */