Beispiel #1
0
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;
}
Beispiel #3
0
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; 
}
Beispiel #5
0
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
}
Beispiel #6
0
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;
}
Beispiel #8
0
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;
}
Beispiel #10
0
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);
}
Beispiel #12
0
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);
}
Beispiel #14
0
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");
}