struct consfront_dev *xencons_ring_init(void) { int err; struct consfront_dev *dev; if (!start_info.console.domU.evtchn) return 0; dev = bmk_memcalloc(1, sizeof(struct consfront_dev)); dev->nodename = "device/console"; dev->dom = 0; dev->backend = 0; dev->ring_ref = 0; dev->evtchn = start_info.console.domU.evtchn; dev->ring = (struct xencons_interface *) mfn_to_virt(start_info.console.domU.mfn); err = minios_bind_evtchn(dev->evtchn, console_handle_input, dev); if (err <= 0) { minios_printk("XEN console request chn bind failed %i\n", err); bmk_memfree(dev); return NULL; } minios_unmask_evtchn(dev->evtchn); /* In case we have in-flight data after save/restore... */ notify_daemon(dev); return dev; }
void * rumpcomp_pci_irq_establish(unsigned cookie, int (*handler)(void *), void *data) { struct ihandler *ihan; evtchn_port_t prt; int pirq; if (cookie != mycookie) return NULL; pirq = myintr; ihan = bmk_memalloc(sizeof(*ihan), 0, BMK_MEMWHO_WIREDBMK); if (!ihan) return NULL; ihan->i_handler = handler; ihan->i_data = data; prt = minios_bind_pirq(pirq, 1, hyperhandler, ihan); minios_unmask_evtchn(prt); ihan->i_prt = prt; return ihan; }
struct blkfront_dev *blkfront_init(char *_nodename, struct blkfront_info *info) { xenbus_transaction_t xbt; char* err; char* message=NULL; struct blkif_sring *s; int retry=0; char* msg = NULL; char* c; char* nodename = _nodename ? _nodename : "device/vbd/768"; struct blkfront_dev *dev; char path[strlen(nodename) + 1 + 10 + 1]; dev = malloc(sizeof(*dev)); memset(dev, 0, sizeof(*dev)); dev->nodename = strdup(nodename); snprintf(path, sizeof(path), "%s/backend-id", nodename); dev->dom = xenbus_read_integer(path); minios_evtchn_alloc_unbound(dev->dom, blkfront_handler, dev, &dev->evtchn); s = (struct blkif_sring*) minios_alloc_page(); memset(s,0,PAGE_SIZE); SHARED_RING_INIT(s); FRONT_RING_INIT(&dev->ring, s, PAGE_SIZE); dev->ring_ref = gnttab_grant_access(dev->dom,virt_to_mfn(s),0); xenbus_event_queue_init(&dev->events); again: err = xenbus_transaction_start(&xbt); if (err) { minios_printk("starting transaction\n"); free(err); } err = xenbus_printf(xbt, nodename, "ring-ref","%u", dev->ring_ref); if (err) { message = "writing ring-ref"; goto abort_transaction; } err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn); if (err) { message = "writing event-channel"; goto abort_transaction; } err = xenbus_printf(xbt, nodename, "protocol", "%s", XEN_IO_PROTO_ABI_NATIVE); if (err) { message = "writing protocol"; goto abort_transaction; } snprintf(path, sizeof(path), "%s/state", nodename); err = xenbus_switch_state(xbt, path, XenbusStateConnected); if (err) { message = "switching state"; goto abort_transaction; } err = xenbus_transaction_end(xbt, 0, &retry); if (err) free(err); if (retry) { goto again; minios_printk("completing transaction\n"); } goto done; abort_transaction: free(err); err = xenbus_transaction_end(xbt, 1, &retry); minios_printk("Abort transaction %s\n", message); goto error; done: snprintf(path, sizeof(path), "%s/backend", nodename); msg = xenbus_read(XBT_NIL, path, &dev->backend); if (msg) { minios_printk("Error %s when reading the backend path %s\n", msg, path); goto error; } minios_printk("blkfront: node=%s backend=%s\n", nodename, dev->backend); dev->handle = strtoul(strrchr(nodename, '/')+1, NULL, 10); { XenbusState state; char path[strlen(dev->backend) + 1 + 19 + 1]; snprintf(path, sizeof(path), "%s/mode", dev->backend); msg = xenbus_read(XBT_NIL, path, &c); if (msg) { minios_printk("Error %s when reading the mode\n", msg); goto error; } if (*c == 'w') dev->info.mode = O_RDWR; else dev->info.mode = O_RDONLY; free(c); snprintf(path, sizeof(path), "%s/state", dev->backend); xenbus_watch_path_token(XBT_NIL, path, path, &dev->events); msg = NULL; state = xenbus_read_integer(path); while (msg == NULL && state < XenbusStateConnected) msg = xenbus_wait_for_state_change(path, &state, &dev->events); if (msg != NULL || state != XenbusStateConnected) { minios_printk("backend not available, state=%d\n", state); xenbus_unwatch_path_token(XBT_NIL, path, path); goto error; } snprintf(path, sizeof(path), "%s/info", dev->backend); dev->info.info = xenbus_read_integer(path); snprintf(path, sizeof(path), "%s/sectors", dev->backend); // FIXME: read_integer returns an int, so disk size limited to 1TB for now dev->info.sectors = xenbus_read_integer(path); snprintf(path, sizeof(path), "%s/sector-size", dev->backend); dev->info.sector_size = xenbus_read_integer(path); snprintf(path, sizeof(path), "%s/feature-barrier", dev->backend); dev->info.barrier = xenbus_read_integer(path); snprintf(path, sizeof(path), "%s/feature-flush-cache", dev->backend); dev->info.flush = xenbus_read_integer(path); *info = dev->info; } minios_unmask_evtchn(dev->evtchn); minios_printk("blkfront: %u sectors\n", dev->info.sectors); return dev; error: free(msg); free(err); free_blkfront(dev); return NULL; }