static void tcpip_bringup_finished(void *p) { #ifdef CONFIG_SUSPEND tprintk("TCP/IP bringup ends.\n"); #endif up(&tcpip_is_up); }
loff_t test_pci_llseek(struct file *filp, loff_t off, int whence) { loff_t newpos =-1; tprintk("lseek whence:%d\n", whence); switch(whence) { case SEEK_SET: newpos = off; break; case SEEK_CUR: newpos = filp->f_pos + off; break; case SEEK_END: newpos = dev_data->pio_memsize + off; break; default: /* can't happen */ return -EINVAL; } if (newpos < 0) return -EINVAL; filp->f_pos = newpos; return newpos; }
void smp_resume(void) { int cpu; int res; struct thread *idle; cpu = 0; //smp_processor_id(); BUG_ON(cpu != 0); /* get the ipi handler for this cpu */ per_cpu(0, ipi_port) = evtchn_alloc_ipi(ipi_handler, cpu, NULL); for (cpu = 1; cpu < MAX_VIRT_CPUS; cpu++) { res = HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL); if (res >= 0) { if (trace_smp()) tprintk("Bringing up CPU=%d\n", cpu); per_cpu(cpu, cpu_state) = CPU_RESUMING; idle = per_cpu(cpu, idle_thread); if (idle) { /* reinitalize idle thread to restart */ idle->sp = (unsigned long)idle->stack + idle->stack_size; stack_push(idle, (unsigned long) idle_thread_fn); stack_push(idle, (unsigned long) cpu); idle->ip = (unsigned long) idle_thread_starter; } per_cpu(cpu, ipi_port) = evtchn_alloc_ipi(ipi_handler, cpu, NULL); BUG_ON(HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL)); } } }
irqreturn_t test_pci_handler(int irq, void *dev_id) { struct pci_dev *pdev = dev_id; char intmask; tprintk("irq handler called\n"); intmask = inb(dev_data->pio_base + TEST_GET_INTMASK); if(intmask & INT_DO) { // register tasklet tasklet_schedule(&test_tasklet); } if(intmask & INT_CDMA) { } if(intmask & INT_SDMA) { sdma_done = 1; } outb(0, dev_data->pio_base + TEST_SET_INTMASK); // down irq line outl(0, dev_data->pio_base + TEST_DOWN_IRQ); return IRQ_HANDLED; }
void start_networking(void) { struct ip_addr ipaddr = { htonl(IF_IPADDR) }; struct ip_addr netmask = { htonl(IF_NETMASK) }; struct ip_addr gw = { 0 }; char *ip = NULL; #ifdef CONFIG_PRINT tprintk("Waiting for network.\n"); #endif dev = init_netfront(NULL, NULL, rawmac, &ip); if (ip) { ipaddr.addr = inet_addr(ip); if (IN_CLASSA(ntohl(ipaddr.addr))) netmask.addr = htonl(IN_CLASSA_NET); else if (IN_CLASSB(ntohl(ipaddr.addr))) netmask.addr = htonl(IN_CLASSB_NET); else if (IN_CLASSC(ntohl(ipaddr.addr))) netmask.addr = htonl(IN_CLASSC_NET); else tprintk("Strange IP %s, leaving netmask to 0.\n", ip); } tprintk("IP %x netmask %x gateway %x.\n", ntohl(ipaddr.addr), ntohl(netmask.addr), ntohl(gw.addr)); #ifdef CONFIG_PRINT tprintk("TCP/IP bringup begins.\n"); #endif netif = xmalloc(struct netif); tcpip_init(tcpip_bringup_finished, netif); netif_add(netif, &ipaddr, &netmask, &gw, rawmac, netif_netfront_init, ip_input); netif_set_default(netif); netif_set_up(netif); down(&tcpip_is_up); #ifdef CONFIG_FRONT tprintk("Network is ready.\n"); #endif }
void resume_networking(int cancelled) { //struct netif *netif; struct ip_addr ipaddr = { htonl(IF_IPADDR) }; struct ip_addr netmask = { htonl(IF_NETMASK) }; struct ip_addr gw = { htonl(0xc0a87a01) }; char *ip = NULL; #ifdef CONFIG_PRINT tprintk("Waiting for network.\n"); #endif dev = init_netfront(NULL, NULL, rawmac, &ip); if(!cancelled){ if (ip) { ipaddr.addr = inet_addr(ip); if (IN_CLASSA(ntohl(ipaddr.addr))) netmask.addr = htonl(IN_CLASSA_NET); else if (IN_CLASSB(ntohl(ipaddr.addr))) netmask.addr = htonl(IN_CLASSB_NET); else if (IN_CLASSC(ntohl(ipaddr.addr))) netmask.addr = htonl(IN_CLASSC_NET); else tprintk("Strange IP %s, leaving netmask to 0.\n", ip); } tprintk("IP %x netmask %x gateway %x.\n", ntohl(ipaddr.addr), ntohl(netmask.addr), ntohl(gw.addr)); netif = xmalloc(struct netif); netif_add(netif, &ipaddr, &netmask, &gw, rawmac, netif_netfront_init, ip_input); netif_set_default(netif); netif_set_up(netif); down(&tcpip_is_up); } #ifdef CONFIG_SUSPEND tprintk("TCP/IP bringup begins.\n"); #endif }
ssize_t test_pci_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_ops) { int retval; char val; unsigned int write_num = 0; /* unsigned long pio_base; */ tprintk("count %d pos %lld\n", count, *f_ops); while(write_num < count) { tprintk("port io number:%lx\n", dev_data->pio_base+*f_ops); retval = get_user(val, &buf[write_num++]); if(retval) break; // 0 on success outb(val, dev_data->pio_base+*f_ops); (*f_ops)++; } return write_num; }
void init_smp(void) { unsigned int cpu; int res; memset(percpu, 0, sizeof(struct cpu_private) * MAX_VIRT_CPUS); init_cpu_pda(0); /* * Init of CPU0 is completed, smp_init_completed must be set before we * initialise remaining CPUs, because smp_proccessor_id macro will not * work properly */ smp_init_completed = 1; /* * We have now completed the init of cpu0 */ if (trace_smp()) tprintk("Initing SMP cpus.\n"); for (cpu = 1; cpu < MAX_VIRT_CPUS; cpu++) { per_cpu(cpu, cpu_state) = CPU_DOWN; res = HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL); if (res >= 0) { if (trace_smp()) tprintk("Bringing up CPU=%d\n", cpu); cpu_initialize_context(cpu); BUG_ON(HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL)); spin_lock(&cpu_lock); smp_active++; spin_unlock(&cpu_lock); } } if (trace_smp()) { tprintk("SMP: %d CPUs active\n", smp_active); for (cpu = 0; cpu < MAX_VIRT_CPUS; cpu++) { tprintk("SMP: cpu_state %d %d\n", cpu, per_cpu(cpu, cpu_state)); } } if (trace_sched()) ttprintk("SMP %d\n", smp_active); }
// read from port io per 1 byte ssize_t test_pci_read(struct file *filp, char __user *buf, size_t count, loff_t *f_ops) { int retval; char val = 0; unsigned int read_num = 0; tprintk("count %d pos %lld\n", count, *f_ops); // read from ioport while (read_num < count) { tprintk("port io number:%lx\n", dev_data->pio_base+*f_ops); val = inb(dev_data->pio_base + *f_ops); // read 1 byte // printk("val %d\n", val); retval = put_user(val, &buf[read_num++]); if(retval) break; // 0 on success (*f_ops)++; } return read_num; }
void stop_networking(void) { struct netif *_netif = netif; struct netfront_dev *dev; struct netfrontif *nfi; if (!_netif) return; netif = NULL; tprintk("Stopping networking\n"); netif_set_down(_netif); nfi = _netif->state; dev = nfi->dev; netif_remove(_netif); mem_free(nfi); mem_free(_netif); shutdown_netfront(dev); tprintk("Networking stopped\n"); }
static void test_pci_remove(struct pci_dev *pdev) { pci_free_consistent(dev_data->pdev, TEST_CDMA_BUFFER_SIZE, dev_data->cdma_buffer, dev_data->cdma_addr); cdev_del(dev_data->cdev); unregister_chrdev_region(test_pci_devt, test_pci_devs_max); free_irq(dev_data->pdev->irq, dev_data->pdev); iounmap(dev_data->mmio_addr); pci_release_region(dev_data->pdev, BAR_MMIO); pci_release_region(dev_data->pdev, BAR_PIO); pci_disable_device(dev_data->pdev); tprintk("%s driver (major %d) unloaded\n", DRIVER_TEST_NAME, test_pci_major); }
void smp_suspend(void) { int cpu; spin_lock(&cpu_lock); suspend_count = 0; for (cpu = 1; cpu < MAX_VIRT_CPUS; cpu++) { if (per_cpu(cpu, cpu_state) == CPU_UP || per_cpu(cpu, cpu_state) == CPU_SLEEPING) { if (trace_smp()) tprintk("mark CPU %d to go down\n", cpu); ++suspend_count; per_cpu(cpu, cpu_state) = CPU_SUSPENDING; wmb(); smp_signal_cpu(cpu); } } while(suspend_count) { spin_unlock(&cpu_lock); sleep(1); spin_lock(&cpu_lock); } spin_unlock(&cpu_lock); }
static void tcpip_bringup_finished(void *p) { tprintk("TCP/IP bringup ends.\n"); up(&tcpip_is_up); }
void start_networking(void) { struct netfront_dev *dev; struct netif *_netif; struct netif *niret; struct netfrontif *nfi; struct ip_addr ip; struct ip_addr mask; struct ip_addr gw; char *ifip = NULL; ASSERT(netif == NULL); IP4_ADDR(&ip, 192, 168, 1, 128); IP4_ADDR(&mask, 255, 255, 255, 0); IP4_ADDR(&gw, 0, 0, 0, 0); tprintk("Starting networking\n"); /* init netfront */ dev = init_netfront(NULL, NULL, NULL, &ifip); if (!dev) { tprintk("Could not init netfront\n"); goto err_out; } if (ifip) { tprintk("Got IP address %s\n", ifip); ip.addr = inet_addr(ifip); if (IN_CLASSA(ntohl(ip.addr))) { tprintk("Use class A netmask (255.0.0.0)\n"); mask.addr = htonl(IN_CLASSA_NET); } else if (IN_CLASSB(ntohl(ip.addr))) { mask.addr = htonl(IN_CLASSB_NET); tprintk("Use class B netmask (255.255.0.0)\n"); } else if (IN_CLASSC(ntohl(ip.addr))) { mask.addr = htonl(IN_CLASSC_NET); tprintk("Use class C netmask (255.255.255.0)\n"); } else { tprintk("Could not auto-detect IP class for %s," "use class C netmask (255.255.255.0)\n", ifip); } } else { tprintk("Set IP to 192.168.1.128, use class A netmask (255.0.0.0)\n"); } /* allocate netif */ _netif = mem_calloc(1, sizeof(*_netif)); if (!_netif) { tprintk("Could not allocate netif\n"); goto err_shutdown_netfront; } /* allocate netif state data */ nfi = mem_calloc(1, sizeof(*nfi)); if (!nfi) { tprintk("Could not allocate netfrontif\n"); goto err_free_netif; } nfi->dev = dev; /* init lwIP */ #ifdef CONFIG_LWIP_NOTHREADS lwip_init(); niret = netif_add(_netif, &ip, &mask, &gw, nfi, netfrontif_init, ethernet_input); #else tcpip_init(NULL, NULL); niret = netif_add(_netif, &ip, &mask, &gw, nfi, netfrontif_init, tcpip_input); #endif if (!niret) { tprintk("Could not initialize lwIP\n"); goto err_free_nfi; } netif_set_default(_netif); netif_set_up(_netif); netif = _netif; tprintk("Networking started\n"); return; err_free_nfi: mem_free(nfi); err_free_netif: mem_free(_netif); err_shutdown_netfront: shutdown_netfront(dev); err_out: return; }
long test_pci_uioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int data[TEST_MMIO_DATANUM]; test_ioctl_data *d = arg; int n; tprintk("_cmd:%d\n", cmd); switch (cmd) { case TEST_CMD_MEMREAD : /* val = ioread32(mmio_addr); */ // ioread32_rep(mmio_addr, data, TEST_MMIO_DATANUM); memcpy_fromio(data, dev_data->mmio_addr, TEST_MMIO_DATASIZE); copy_to_user(d->mmiodata, data, TEST_MMIO_DATASIZE); break; case TEST_CMD_MEMWRITE : /* iowrite32(val, mmio_addr+TEST_MEM); */ copy_from_user(data, d->mmiodata, TEST_MMIO_DATASIZE); memcpy_toio(dev_data->mmio_addr, data, TEST_MMIO_DATASIZE); break; case TEST_CMD_CDMA_START : copy_from_user(dev_data->cdma_buffer, d->cdmabuf, TEST_CDMA_BUFFER_SIZE); wmb(); outl(CDMA_START, dev_data->pio_base + TEST_CDMA_START); break; case TEST_CMD_GET_CDMA_DATA : n = copy_to_user(d->cdmabuf, dev_data->cdma_buffer, TEST_CDMA_BUFFER_SIZE); if(n != 0){ tprintk("cannot copy all data (%d bytes in %d bytes)\n", n, TEST_CDMA_BUFFER_SIZE); } break; case TEST_CMD_SDMA_START : copy_from_user(dev_data->sdma_buffer, d->sdmabuf, TEST_SDMA_BUFFER_SIZE); dev_data->sdma_addr = pci_map_single(dev_data->pdev, dev_data->sdma_buffer, TEST_SDMA_BUFFER_SIZE, DMA_BIDIRECTIONAL); dev_data->sdma_len = TEST_SDMA_BUFFER_SIZE; wmb(); outl(dev_data->sdma_addr, dev_data->pio_base + TEST_SET_SDMA_ADDR); outl(dev_data->sdma_len, dev_data->pio_base + TEST_SET_SDMA_LEN); wmb(); outl(SDMA_START, dev_data->pio_base + TEST_SDMA_START); break; case TEST_CMD_GET_SDMA_DATA : tprintk("sdma_done %d\n", sdma_done); if(wait_event_interruptible(dev_data->sdma_q, (sdma_done == 1))) { return -ERESTARTSYS; } sdma_done = 0; pci_unmap_single(dev_data->pdev, dev_data->sdma_addr, TEST_SDMA_BUFFER_SIZE, DMA_BIDIRECTIONAL); n = copy_to_user(d->sdmabuf, dev_data->sdma_buffer, TEST_SDMA_BUFFER_SIZE); if(n != 0) { tprintk("cannot copy all data (%d bytes in %d bytes)\n", n, TEST_SDMA_BUFFER_SIZE); } break; case TEST_CMD_DOSOMETHING : outl(0, dev_data->pio_base + TEST_DO); break; default: return -EINVAL; // invalid argument(cmd) } return 0; }
//----------------------------------------------------------------- // pci initialization function // enable pci & register character device static int test_pci_probe (struct pci_dev *pdev, const struct pci_device_id *id) { int err; char irq; int alloc_ret = 0; int cdev_err = 0; short vendor_id, device_id; //----------------------------------------------------------------- // config PCI // enable pci device err = pci_enable_device(pdev); if(err) { printk(KERN_ERR "can't enable pci device\n"); goto error; } tprintk("PCI enabled for %s\n", DRIVER_TEST_NAME); // request PCI region // bar 0 ... MMIO dev_data->mmio_base = pci_resource_start(pdev, BAR_MMIO); dev_data->mmio_length = pci_resource_len(pdev, BAR_MMIO); dev_data->mmio_flags = pci_resource_flags(pdev, BAR_MMIO); tprintk( "mmio_base: %lx, mmio_length: %lx, mmio_flags: %lx\n", dev_data->mmio_base, dev_data->mmio_length, dev_data->mmio_flags); dev_data->mmio_addr = ioremap(dev_data->mmio_base, TEST_PCI_MEMSIZE); if(!(dev_data->mmio_flags & IORESOURCE_MEM)){ printk(KERN_ERR "BAR%d is not for mmio\n", BAR_MMIO); goto error; } err = pci_request_region(pdev, BAR_MMIO, DRIVER_TEST_NAME); if(err) { printk(KERN_ERR "%s :error pci_request_region MMIO\n", __func__); goto error; } // bar 1 ... IO port dev_data->pio_base = pci_resource_start(pdev, BAR_PIO); dev_data->pio_length = pci_resource_len(pdev, BAR_PIO); dev_data->pio_flags = pci_resource_flags(pdev, BAR_PIO); tprintk("pio_base: %lx, pio_length: %lx, pio_flags: %lx\n", dev_data->pio_base, dev_data->pio_length, dev_data->pio_flags); if(!(dev_data->pio_flags & IORESOURCE_IO)){ printk(KERN_ERR "BAR%d is not for pio\n", BAR_PIO); goto error; } err = pci_request_region(pdev, BAR_PIO, DRIVER_TEST_NAME); if(err) { printk(KERN_ERR "%s :error pci_request_region PIO\n", __func__); goto error; } // show PCI configuration data // define at include/uapi/linux/pci_regs.h pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id); pci_read_config_word(pdev, PCI_DEVICE_ID, &device_id); tprintk("PCI Vendor ID:%x, Device ID:%x\n", vendor_id, device_id); dev_data->pdev = pdev; dev_data->pio_memsize = TEST_PIO_DATASIZE; tprintk("sucess allocate i/o region\n"); //----------------------------------------------------------------- // config irq // get irq number irq = pdev->irq; // same as pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &irq); tprintk("device irq: %d\n", irq); err = request_irq(irq, test_pci_handler, 0, DRIVER_TEST_NAME, pdev); if(err){ printk(KERN_ERR "%s :error request irq %d\n", __func__, irq); goto error; } //----------------------------------------------------------------- // register character device // allocate major number alloc_ret = alloc_chrdev_region(&test_pci_devt, test_pci_minor, test_pci_devs_max, DRIVER_TEST_NAME); if(alloc_ret) goto error; test_pci_major = MAJOR(test_pci_devt); dev_data->cdev = (struct cdev*)kmalloc(sizeof(struct cdev), GFP_KERNEL); if(!dev_data->cdev) goto error; cdev_init(dev_data->cdev, &test_pci_fops); dev_data->cdev->owner = THIS_MODULE; cdev_err = cdev_add(dev_data->cdev, test_pci_devt, test_pci_devs_max); if(cdev_err) goto error; tprintk("%s driver(major %d) installed.\n", DRIVER_TEST_NAME, test_pci_major); //----------------------------------------------------------------- // config DMA err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if(err) { printk(KERN_ERR "Cannot set DMA mask\n"); goto error; } pci_set_master(pdev); // allocate consistent DMA dev_data->cdma_buffer = pci_alloc_consistent(pdev, TEST_CDMA_BUFFER_SIZE, &dev_data->cdma_addr); if(dev_data->cdma_buffer == NULL) { printk(KERN_ERR "Cannot allocate consistent DMA buffer\n"); goto error; } dev_data->cdma_len = TEST_CDMA_BUFFER_SIZE; // send consistent DMA info to device outl(dev_data->cdma_addr, dev_data->pio_base + TEST_SET_CDMA_ADDR); outl(dev_data->cdma_len, dev_data->pio_base + TEST_SET_CDMA_LEN); tprintk("cdma_addr : %x\n", dev_data->cdma_addr); // streaming DMA dev_data->sdma_buffer = kmalloc(TEST_SDMA_BUFFER_SIZE, GFP_KERNEL); if(dev_data->sdma_buffer == NULL) { printk(KERN_ERR "Cannot allocate streaming DMA buffer\n"); goto error; } init_waitqueue_head(&(dev_data->sdma_q)); return 0; error: tprintk("PCI load error\n"); if(cdev_err == 0) cdev_del(dev_data->cdev); if(alloc_ret == 0) unregister_chrdev_region(test_pci_devt, test_pci_devs_max); return -1; }
// interrupt handler void test_do_tasklet(unsigned long unused_data) { tprintk("tasklet called\n"); }