int main(int argc, char ** argv) { struct sched_param sp; /* Priorytet procesu */ /* Zainicjuj obiekty. Ponieważ jest to pierwsze użycie - wykonają sie wszystkie funcje malloc i pliki zostaną otwarte */ struct controller_t * c = new_controller(); struct msg_t * msg = new_msg(); struct io_t * io = new_io(); /* Ustawianie parametrów planisty */ sp.sched_priority = MY_PRIORITY; if (sched_setscheduler(0, SCHED_FIFO, &sp) == -1) { log("sched_setscheduler() failed"); } /* Blokowanie pamięci procesu */ if (mlockall( MCL_CURRENT|MCL_FUTURE ) == -1) { log("mlockall() failed"); } while (1) { /* Wykonaj krok automatu */ do_fsm_step(); } return 0; }
hci_t * ehci_init (pcidev_t addr) { int i; hci_t *controller = new_controller (); if (!controller) usb_fatal("Could not create USB controller instance.\n"); controller->instance = malloc (sizeof (ehci_t)); if(!controller->instance) usb_fatal("Not enough memory creating USB controller instance.\n"); #define PCI_COMMAND 4 #define PCI_COMMAND_IO 1 #define PCI_COMMAND_MEMORY 2 #define PCI_COMMAND_MASTER 4 u32 pci_command = pci_read_config32(addr, PCI_COMMAND); pci_command = (pci_command | PCI_COMMAND_MEMORY) & ~PCI_COMMAND_IO ; pci_write_config32(addr, PCI_COMMAND, pci_command); controller->start = ehci_start; controller->stop = ehci_stop; controller->reset = ehci_reset; controller->shutdown = ehci_shutdown; controller->bulk = ehci_bulk; controller->control = ehci_control; controller->create_intr_queue = ehci_create_intr_queue; controller->destroy_intr_queue = ehci_destroy_intr_queue; controller->poll_intr_queue = ehci_poll_intr_queue; for (i = 0; i < 128; i++) { controller->devices[i] = 0; } init_device_entry (controller, 0); EHCI_INST(controller)->capabilities = phys_to_virt(pci_read_config32(addr, USBBASE)); EHCI_INST(controller)->operation = (hc_op_t *)(phys_to_virt(pci_read_config32(addr, USBBASE)) + EHCI_INST(controller)->capabilities->caplength); /* default value for frame length adjust */ pci_write_config8(addr, FLADJ, FLADJ_framelength(60000)); /* Enable operation of controller */ controller->start(controller); /* take over all ports. USB1 should be blind now */ EHCI_INST(controller)->operation->configflag = 1; /* TODO lots of stuff missing */ controller->devices[0]->controller = controller; controller->devices[0]->init = ehci_rh_init; controller->devices[0]->init (controller->devices[0]); return controller; }
static int controller_add_exec(bContext *C, wmOperator *op) { Object *ob; bController *cont; PointerRNA cont_ptr; PropertyRNA *prop; const char *cont_name; int bit; char name[MAX_NAME]; int type = RNA_enum_get(op->ptr, "type"); ob = edit_object_property_get(C, op); if (!ob) return OPERATOR_CANCELLED; cont = new_controller(type); BLI_addtail(&(ob->controllers), cont); /* set the controller name based on rna type enum */ RNA_pointer_create((ID *)ob, &RNA_Controller, cont, &cont_ptr); prop = RNA_struct_find_property(&cont_ptr, "type"); RNA_string_get(op->ptr, "name", name); if (*name) { BLI_strncpy(cont->name, name, sizeof(cont->name)); } else { RNA_property_enum_name(C, &cont_ptr, prop, RNA_property_enum_get(&cont_ptr, prop), &cont_name); BLI_strncpy(cont->name, cont_name, sizeof(cont->name)); } BLI_uniquename(&ob->controllers, cont, DATA_("Controller"), '.', offsetof(bController, name), sizeof(cont->name)); /* set the controller state mask from the current object state. * A controller is always in a single state, so select the lowest bit set * from the object state */ for (bit = 0; bit < OB_MAX_STATES; bit++) { if (ob->state & (1 << bit)) break; } cont->state_mask = (1 << bit); if (cont->state_mask == 0) { /* shouldn't happen, object state is never 0 */ cont->state_mask = 1; } ob->scaflag |= OB_SHOWCONT; WM_event_add_notifier(C, NC_LOGIC, NULL); return OPERATOR_FINISHED; }
hci_t * uhci_init (pcidev_t addr) { int i; u16 reg16; hci_t *controller = new_controller (); if (!controller) fatal("Could not create USB controller instance.\n"); controller->instance = malloc (sizeof (uhci_t)); if(!controller->instance) fatal("Not enough memory creating USB controller instance.\n"); controller->type = UHCI; controller->start = uhci_start; controller->stop = uhci_stop; controller->reset = uhci_reset; controller->init = uhci_reinit; controller->shutdown = uhci_shutdown; controller->bulk = uhci_bulk; controller->control = uhci_control; controller->set_address = generic_set_address; controller->finish_device_config = NULL; controller->destroy_device = NULL; controller->create_intr_queue = uhci_create_intr_queue; controller->destroy_intr_queue = uhci_destroy_intr_queue; controller->poll_intr_queue = uhci_poll_intr_queue; for (i = 0; i < 128; i++) { controller->devices[i] = 0; } init_device_entry (controller, 0); UHCI_INST (controller)->roothub = controller->devices[0]; controller->bus_address = addr; controller->reg_base = pci_read_config32 (controller->bus_address, 0x20) & ~1; /* ~1 clears the register type indicator that is set to 1 for IO space */ /* kill legacy support handler */ uhci_stop (controller); mdelay (1); uhci_reg_write16 (controller, USBSTS, 0x3f); reg16 = pci_read_config16(controller->bus_address, 0xc0); reg16 &= 0xdf80; pci_write_config16 (controller->bus_address, 0xc0, reg16); UHCI_INST (controller)->framelistptr = memalign (0x1000, 1024 * sizeof (flistp_t)); /* 4kb aligned to 4kb */ if (! UHCI_INST (controller)->framelistptr) fatal("Not enough memory for USB frame list pointer.\n"); memset (UHCI_INST (controller)->framelistptr, 0, 1024 * sizeof (flistp_t)); /* According to the *BSD UHCI code, this one is needed on some PIIX chips, because otherwise they misbehave. It must be added to the last chain. FIXME: this leaks, if the driver should ever be reinited for some reason. Not a problem now. */ td_t *antiberserk = memalign(16, sizeof(td_t)); if (!antiberserk) fatal("Not enough memory for chipset workaround.\n"); memset(antiberserk, 0, sizeof(td_t)); UHCI_INST (controller)->qh_prei = memalign (16, sizeof (qh_t)); UHCI_INST (controller)->qh_intr = memalign (16, sizeof (qh_t)); UHCI_INST (controller)->qh_data = memalign (16, sizeof (qh_t)); UHCI_INST (controller)->qh_last = memalign (16, sizeof (qh_t)); if (! UHCI_INST (controller)->qh_prei || ! UHCI_INST (controller)->qh_intr || ! UHCI_INST (controller)->qh_data || ! UHCI_INST (controller)->qh_last) fatal("Not enough memory for USB controller queues.\n"); UHCI_INST (controller)->qh_prei->headlinkptr = virt_to_phys (UHCI_INST (controller)->qh_intr) | FLISTP_QH; UHCI_INST (controller)->qh_prei->elementlinkptr = 0 | FLISTP_TERMINATE; UHCI_INST (controller)->qh_intr->headlinkptr = virt_to_phys (UHCI_INST (controller)->qh_data) | FLISTP_QH; UHCI_INST (controller)->qh_intr->elementlinkptr = 0 | FLISTP_TERMINATE; UHCI_INST (controller)->qh_data->headlinkptr = virt_to_phys (UHCI_INST (controller)->qh_last) | FLISTP_QH; UHCI_INST (controller)->qh_data->elementlinkptr = 0 | FLISTP_TERMINATE; UHCI_INST (controller)->qh_last->headlinkptr = virt_to_phys (UHCI_INST (controller)->qh_data) | FLISTP_TERMINATE; UHCI_INST (controller)->qh_last->elementlinkptr = virt_to_phys (antiberserk) | FLISTP_TERMINATE; for (i = 0; i < 1024; i++) { UHCI_INST (controller)->framelistptr[i] = virt_to_phys (UHCI_INST (controller)->qh_prei) | FLISTP_QH; } controller->devices[0]->controller = controller; controller->devices[0]->init = uhci_rh_init; controller->devices[0]->init (controller->devices[0]); uhci_reset (controller); uhci_reinit (controller); return controller; }
hci_t * xhci_init (unsigned long physical_bar) { int i; /* First, allocate and initialize static controller structures */ hci_t *const controller = new_controller(); if (!controller) { xhci_debug("Could not create USB controller instance\n"); return controller; } controller->type = XHCI; controller->start = xhci_start; controller->stop = xhci_stop; controller->reset = xhci_reset; controller->init = xhci_reinit; controller->shutdown = xhci_shutdown; controller->bulk = xhci_bulk; controller->control = xhci_control; controller->set_address = xhci_set_address; controller->finish_device_config= xhci_finish_device_config; controller->destroy_device = xhci_destroy_dev; controller->create_intr_queue = xhci_create_intr_queue; controller->destroy_intr_queue = xhci_destroy_intr_queue; controller->poll_intr_queue = xhci_poll_intr_queue; controller->pcidev = 0; for (i = 0; i < 128; ++i) { controller->devices[i] = NULL; } controller->instance = malloc(sizeof(xhci_t)); if (!controller->instance) { xhci_debug("Out of memory creating xHCI controller instance\n"); goto _free_controller; } xhci_t *const xhci = (xhci_t *)controller->instance; memset(xhci, 0x00, sizeof(*xhci)); init_device_entry(controller, 0); xhci->roothub = controller->devices[0]; xhci->cr.ring = xhci_align(64, COMMAND_RING_SIZE * sizeof(trb_t)); xhci->er.ring = xhci_align(64, EVENT_RING_SIZE * sizeof(trb_t)); xhci->ev_ring_table = xhci_align(64, sizeof(erst_entry_t)); if (!xhci->roothub || !xhci->cr.ring || !xhci->er.ring || !xhci->ev_ring_table) { xhci_debug("Out of memory\n"); goto _free_xhci; } xhci->capreg = phys_to_virt(physical_bar); xhci->opreg = ((void *)xhci->capreg) + xhci->capreg->caplength; xhci->hcrreg = ((void *)xhci->capreg) + xhci->capreg->rtsoff; xhci->dbreg = ((void *)xhci->capreg) + xhci->capreg->dboff; xhci_debug("regbase: 0x%"PRIx32"\n", physical_bar); xhci_debug("caplen: 0x%"PRIx32"\n", xhci->capreg->caplength); xhci_debug("rtsoff: 0x%"PRIx32"\n", xhci->capreg->rtsoff); xhci_debug("dboff: 0x%"PRIx32"\n", xhci->capreg->dboff); xhci_debug("hciversion: %"PRIx8".%"PRIx8"\n", xhci->capreg->hciver_hi, xhci->capreg->hciver_lo); if ((xhci->capreg->hciversion < 0x96) || (xhci->capreg->hciversion > 0x100)) { xhci_debug("Unsupported xHCI version\n"); goto _free_xhci; } xhci_debug("context size: %dB\n", CTXSIZE(xhci)); xhci_debug("maxslots: 0x%02lx\n", xhci->capreg->MaxSlots); xhci_debug("maxports: 0x%02lx\n", xhci->capreg->MaxPorts); const unsigned pagesize = xhci->opreg->pagesize << 12; xhci_debug("pagesize: 0x%04x\n", pagesize); /* * We haven't touched the hardware yet. So we allocate all dynamic * structures at first and can still chicken out easily if we run out * of memory. */ xhci->max_slots_en = xhci->capreg->MaxSlots & CONFIG_LP_MASK_MaxSlotsEn; xhci->dcbaa = xhci_align(64, (xhci->max_slots_en + 1) * sizeof(u64)); xhci->dev = malloc((xhci->max_slots_en + 1) * sizeof(*xhci->dev)); if (!xhci->dcbaa || !xhci->dev) { xhci_debug("Out of memory\n"); goto _free_xhci; } memset(xhci->dcbaa, 0x00, (xhci->max_slots_en + 1) * sizeof(u64)); memset(xhci->dev, 0x00, (xhci->max_slots_en + 1) * sizeof(*xhci->dev)); /* * Let dcbaa[0] point to another array of pointers, sp_ptrs. * The pointers therein point to scratchpad buffers (pages). */ const size_t max_sp_bufs = xhci->capreg->Max_Scratchpad_Bufs; xhci_debug("max scratchpad bufs: 0x%zx\n", max_sp_bufs); if (max_sp_bufs) { const size_t sp_ptrs_size = max_sp_bufs * sizeof(u64); xhci->sp_ptrs = xhci_align(64, sp_ptrs_size); if (!xhci->sp_ptrs) { xhci_debug("Out of memory\n"); goto _free_xhci_structs; } memset(xhci->sp_ptrs, 0x00, sp_ptrs_size); for (i = 0; i < max_sp_bufs; ++i) { /* Could use mmap() here if we had it. Maybe there is another way. */ void *const page = memalign(pagesize, pagesize); if (!page) { xhci_debug("Out of memory\n"); goto _free_xhci_structs; } xhci->sp_ptrs[i] = virt_to_phys(page); } xhci->dcbaa[0] = virt_to_phys(xhci->sp_ptrs); } if (dma_initialized()) { xhci->dma_buffer = dma_memalign(64 * 1024, DMA_SIZE); if (!xhci->dma_buffer) { xhci_debug("Not enough memory for DMA bounce buffer\n"); goto _free_xhci_structs; } } /* Now start working on the hardware */ if (xhci_wait_ready(xhci)) goto _free_xhci_structs; /* TODO: Check if BIOS claims ownership (and hand over) */ xhci_reset(controller); xhci_reinit(controller); xhci->roothub->controller = controller; xhci->roothub->init = xhci_rh_init; xhci->roothub->init(xhci->roothub); return controller; _free_xhci_structs: if (xhci->sp_ptrs) { for (i = 0; i < max_sp_bufs; ++i) { if (xhci->sp_ptrs[i]) free(phys_to_virt(xhci->sp_ptrs[i])); } } free(xhci->sp_ptrs); free(xhci->dcbaa); _free_xhci: free((void *)xhci->ev_ring_table); free((void *)xhci->er.ring); free((void *)xhci->cr.ring); free(xhci->roothub); free(xhci->dev); free(xhci); _free_controller: detach_controller(controller); free(controller); return NULL; }
hci_t * ohci_init (pcidev_t addr) { int i; hci_t *controller = new_controller (); if (!controller) fatal("Could not create USB controller instance.\n"); controller->instance = malloc (sizeof (ohci_t)); if(!controller->instance) fatal("Not enough memory creating USB controller instance.\n"); controller->start = ohci_start; controller->stop = ohci_stop; controller->reset = ohci_reset; controller->shutdown = ohci_shutdown; controller->bulk = ohci_bulk; controller->control = ohci_control; controller->create_intr_queue = ohci_create_intr_queue; controller->destroy_intr_queue = ohci_destroy_intr_queue; controller->poll_intr_queue = ohci_poll_intr_queue; for (i = 0; i < 128; i++) { controller->devices[i] = 0; } init_device_entry (controller, 0); OHCI_INST (controller)->roothub = controller->devices[0]; controller->bus_address = addr; controller->reg_base = pci_read_config32 (controller->bus_address, 0x10); // OHCI mandates MMIO, so bit 0 is clear OHCI_INST (controller)->opreg = (opreg_t*)phys_to_virt(controller->reg_base); printf("OHCI Version %x.%x\n", (OHCI_INST (controller)->opreg->HcRevision >> 4) & 0xf, OHCI_INST (controller)->opreg->HcRevision & 0xf); if ((OHCI_INST (controller)->opreg->HcControl & HostControllerFunctionalStateMask) == USBReset) { /* cold boot */ OHCI_INST (controller)->opreg->HcControl &= ~RemoteWakeupConnected; OHCI_INST (controller)->opreg->HcFmInterval = (11999 * FrameInterval) | ((((11999 - 210)*6)/7) * FSLargestDataPacket); /* TODO: right value for PowerOnToPowerGoodTime ? */ OHCI_INST (controller)->opreg->HcRhDescriptorA = NoPowerSwitching | NoOverCurrentProtection | (10 * PowerOnToPowerGoodTime); OHCI_INST (controller)->opreg->HcRhDescriptorB = (0 * DeviceRemovable); udelay(100); /* TODO: reset asserting according to USB spec */ } else if ((OHCI_INST (controller)->opreg->HcControl & HostControllerFunctionalStateMask) != USBOperational) { OHCI_INST (controller)->opreg->HcControl = (OHCI_INST (controller)->opreg->HcControl & ~HostControllerFunctionalStateMask) | USBResume; udelay(100); /* TODO: resume time according to USB spec */ } int interval = OHCI_INST (controller)->opreg->HcFmInterval; td_t *periodic_td = memalign(sizeof(*periodic_td), sizeof(*periodic_td)); memset((void*)periodic_td, 0, sizeof(*periodic_td)); for (i=0; i<32; i++) OHCI_INST (controller)->hcca->HccaInterruptTable[i] = virt_to_phys(periodic_td); /* TODO: build HCCA data structures */ OHCI_INST (controller)->opreg->HcCommandStatus = HostControllerReset; udelay (10); /* at most 10us for reset to complete. State must be set to Operational within 2ms (5.1.1.4) */ OHCI_INST (controller)->opreg->HcFmInterval = interval; OHCI_INST (controller)->hcca = memalign(256, 256); memset((void*)OHCI_INST (controller)->hcca, 0, 256); OHCI_INST (controller)->opreg->HcHCCA = virt_to_phys(OHCI_INST (controller)->hcca); OHCI_INST (controller)->opreg->HcControl &= ~IsochronousEnable; // unused by this driver // disable everything, contrary to what OHCI spec says in 5.1.1.4, as we don't need IRQs OHCI_INST (controller)->opreg->HcInterruptEnable = 1<<31; OHCI_INST (controller)->opreg->HcInterruptDisable = ~(1<<31); OHCI_INST (controller)->opreg->HcInterruptStatus = ~0; OHCI_INST (controller)->opreg->HcPeriodicStart = (((OHCI_INST (controller)->opreg->HcFmInterval & FrameIntervalMask) / 10) * 9); OHCI_INST (controller)->opreg->HcControl = (OHCI_INST (controller)->opreg->HcControl & ~HostControllerFunctionalStateMask) | USBOperational; mdelay(100); controller->devices[0]->controller = controller; controller->devices[0]->init = ohci_rh_init; controller->devices[0]->init (controller->devices[0]); ohci_reset (controller); return controller; }