Exemplo n.º 1
0
static int  pcan_isa_init(struct pcandev *dev, u32 dwPort, u16 wIrq)
{
  int err = 0;
  
  DPRINTK(KERN_DEBUG "%s: pcan_isa_init(), isa_devices = %d\n", DEVICE_NAME, isa_devices);

  // init process wait queues
  init_waitqueue_head(&dev->read_queue);
  init_waitqueue_head(&dev->write_queue);
  
  // set this before any instructions, fill struct pcandev, part 1  
  dev->wInitStep   = 0;           
  dev->readreg     = pcan_isa_readreg;
  dev->writereg    = pcan_isa_writereg;
  dev->cleanup     = pcan_isa_cleanup;
  dev->req_irq     = pcan_isa_req_irq;
  dev->free_irq    = pcan_isa_free_irq;
  dev->open        = pcan_isa_open;
  dev->release     = pcan_isa_release;
  dev->filter      = pcan_create_filter_chain();
  
  // reject illegal combination
  if ((!dwPort && wIrq) || (dwPort && !wIrq))
    return -EINVAL;

  // a default is requested
  if (!dwPort)
  {
    // there's no default available
    if (isa_devices >= ISA_DEFAULT_COUNT)
      return -ENODEV;
    
    dev->port.isa.dwPort = isa_ports[isa_devices];
    dev->port.isa.wIrq   = isa_irqs[isa_devices];    
  }
  else
  {
    dev->port.isa.dwPort = dwPort;
    dev->port.isa.wIrq   = wIrq;    
  } 
   
  dev->nMajor      = pcan_drv.nMajor;
  dev->nMinor      = PCAN_ISA_MINOR_BASE + isa_devices;
   
  // request address range reservation
  err = ___request_region(dev->port.isa.dwPort, ISA_PORT_SIZE, DEVICE_NAME);
  if (err)
    return err;

  dev->wInitStep = 1;
  
  dev->wInitStep = 2; 
  
  INIT_SAME_IRQ_LIST();
  
  isa_devices++; 
  dev->wInitStep = 3;
  
  printk(KERN_INFO "%s: isa device minor %d expected (io=0x%04x,irq=%d)\n", DEVICE_NAME, dev->nMinor, dev->port.isa.dwPort, dev->port.isa.wIrq);
    
  return 0;
}
Exemplo n.º 2
0
static int pcan_usb_create_dev(struct pcan_usb_interface *usb_if,
                               int ctrl_index)
{
	int err, retry;
	struct pcandev *dev;
	struct usb_device *usb_dev = usb_if->usb_dev;
	USB_PORT *u;
	void *h;

	dev = (struct pcandev *)&usb_if->dev[ctrl_index];

	u = &dev->port.usb;
	u->usb_if = usb_if;
	u->dev_ctrl_index = ctrl_index;

	switch (usb_dev->descriptor.idProduct)
	{

#ifdef HW_USB_PRO
	case PCAN_USBPRO_PRODUCT_ID:

		/* init structure elements to defaults */
		pcan_soft_init(dev, "usbpro", HW_USB_PRO);
		break;
#endif

	case PCAN_USB_PRODUCT_ID:
	default:

		// init structure elements to defaults
		pcan_soft_init(dev, "usb", HW_USB);
		break;
	}

	// override standard device access functions
	dev->device_open = pcan_usb_device_open;
	dev->device_write = pcan_usb_write;
	dev->device_release = pcan_usb_device_release;

	// init process wait queues
	init_waitqueue_head(&dev->read_queue);
	init_waitqueue_head(&dev->write_queue);

	// set this before any instructions, fill struct pcandev, part 1
	dev->readreg     = NULL;
	dev->writereg    = NULL;
	dev->cleanup     = pcan_usb_cleanup;
	dev->req_irq     = pcan_usb_req_irq;
	dev->free_irq    = pcan_usb_free_irq;
	dev->open        = pcan_usb_open;
	dev->release     = pcan_usb_release;
	dev->filter      = pcan_create_filter_chain();
	dev->device_params = pcan_usb_device_params;

	printk(KERN_INFO "%s: usb hardware revision = %d\n", DEVICE_NAME, 
	       usb_if->ucRevision);

	dev->wInitStep = 1;

	// add into list of devices
	list_add_tail(&dev->list, &pcan_drv.devices);  // add this device to the list
	dev->wInitStep = 2;

	// assign the device as plugged in
	dev->ucPhysicallyInstalled = 1;

	pcan_drv.wDeviceCount++;
	usb_devices++;
	dev->wInitStep = 3;

	/* Handle controller list per interface */
	h = usb_get_intfdata(usb_if->usb_intf);

	/* must tell that this interface is not in use for all controllers, */
	/* especially for controllers > 0 (kernel>2.6.26) */
	usb_if->usb_intf->minor = -1;
	if ((err = usb_register_dev(usb_if->usb_intf, &pcan_class)) < 0)
	{
		printk(KERN_ERR "%s: unable to register usb device for CAN#%u (err=%d)\n",
		       DEVICE_NAME, ctrl_index, err);

		usb_set_intfdata(usb_if->usb_intf, h);
		goto reject;
	}

	dev->nMinor = usb_if->usb_intf->minor;
	dev->nMajor = USB_MAJOR;

	// set device in inactive state to prevent violating the bus
	usb_if->device_ctrl_set_bus_off(dev);

	// get serial number early
	usb_if->device_get_snr(usb_if, &usb_if->dwSerialNumber);

	/* Get device number early too */
	/* sometimes, need to retry... */
	for (retry=3; retry; retry--)
	{
		uint32_t device_nr32;
		err = usb_if->device_ctrl_get_dnr(dev, &device_nr32);
		if (!err)
		{
			u->ucHardcodedDevNr = (uint8_t )device_nr32;
			break;
		}
	}

	/* Call hardware supplied own callback to do some private init */
	if (usb_if->device_ctrl_init)
	{
		err = usb_if->device_ctrl_init(dev);
		if (err)
			printk(KERN_ERR "%s: CAN#%u initialization not complete (err=%d)\n",
			       DEVICE_NAME, ctrl_index, err);
	}

#ifdef NETDEV_SUPPORT
	pcan_netdev_register(dev);
#endif

	dev->wInitStep = 4;

	printk(KERN_INFO "%s: usb device minor %d found\n", 
	       DEVICE_NAME, dev->nMinor);

	return 0;

reject:
	pcan_usb_cleanup(dev);

	printk(KERN_ERR "%s: %s() failed! (%d)\n", DEVICE_NAME, __FUNCTION__, err);

	return err;
}
Exemplo n.º 3
0
static int  pcan_dongle_init(struct pcandev *dev, u32 dwPort, u16 wIrq, char *type)
{
  int err;
  
  DPRINTK(KERN_DEBUG "%s: pcan_dongle_init(), dng_devices = %d\n", DEVICE_NAME, dng_devices);
  
  // init process wait queues
  init_waitqueue_head(&dev->read_queue);
  init_waitqueue_head(&dev->write_queue);
  
  // set this before any instructions, fill struct pcandev, part 1 
  dev->wInitStep   = 0;  
  dev->cleanup     = pcan_dongle_cleanup;
  dev->req_irq     = pcan_dongle_req_irq;
  dev->free_irq    = pcan_dongle_free_irq;
  dev->open        = pcan_dongle_open;
  dev->release     = pcan_dongle_release; 
  dev->filter      = pcan_create_filter_chain();

  INIT_LOCK(&dev->port.dng.lock);

  // fill struct pcandev, 1st check if a default is set
  if (!dwPort)
  {
    // there's no default available
    if (dng_devices >= DNG_DEFAULT_COUNT)
      return -ENODEV;
    
    dev->port.dng.dwPort = dng_ports[dng_devices];
  }
  else
    dev->port.dng.dwPort = dwPort;
  
  if (!wIrq)
  {
    if (dng_devices >= DNG_DEFAULT_COUNT)
      return -ENODEV;
    
    dev->port.dng.wIrq   = dng_irqs[dng_devices];    
  }
  else
    dev->port.dng.wIrq   = wIrq;    
  
  dev->nMajor = pcan_drv.nMajor;
  if (dev->wType == HW_DONGLE_SJA)
  {
    dev->nMinor        = PCAN_DNG_SP_MINOR_BASE + sp_devices; 
    dev->readreg       = pcan_dongle_sp_readreg;
    dev->writereg      = pcan_dongle_writereg;
    dev->port.dng.wEcr = 0; // set to anything
  }
  else
  {
    dev->nMinor        = PCAN_DNG_EPP_MINOR_BASE + epp_devices;  
    dev->readreg       = pcan_dongle_epp_readreg;
    dev->writereg      = pcan_dongle_writereg;
    dev->port.dng.wEcr = (u16)dev->port.dng.dwPort + 0x402;
  }
    
  // is the device really available?    
  if ((err = pcan_dongle_probe(dev)) < 0)
  {
    printk(KERN_ERR "%s: failed to claim port 0x%04x\n", DEVICE_NAME, dev->port.dng.dwPort);
    return err;
  }
    
  dev->ucPhysicallyInstalled = 1;

  if (dev->wType == HW_DONGLE_SJA)
    sp_devices++;
  else
    epp_devices++;
    
  dng_devices = sp_devices + epp_devices;
  
  dev->wInitStep = 3;

  printk(KERN_INFO "%s: %s-dongle device minor %d prepared (io=0x%04x,irq=%d)\n", DEVICE_NAME, 
                               dev->type, dev->nMinor, dev->port.dng.dwPort, dev->port.dng.wIrq);
  
  return 0;
}
Exemplo n.º 4
0
static void *pcan_usb_plugin(struct usb_device *usb_dev, unsigned int interface)
#endif
{
	struct pcandev *dev = NULL;
	int    err = 0;
	int    i;
	USB_PORT *u;
	struct usb_interface_descriptor *current_interface_setting;

	DPRINTK(KERN_DEBUG "%s: pcan_usb_plugin(0x%04x, 0x%04x, %d)\n", DEVICE_NAME,
				  usb_dev->descriptor.idVendor, usb_dev->descriptor.idProduct, interface);

	// take the 1st configuration (it's default)
	if (usb_set_configuration (usb_dev, usb_dev->config[0].bConfigurationValue) < 0)
	{
		printk(KERN_ERR "%s: usb_set_configuration() failed!\n", DEVICE_NAME);
		goto reject;
	}

	// only 1 interface is supported
	if (usb_set_interface (usb_dev, 0, 0) < 0)
	{
		printk(KERN_ERR "%s: usb_set_interface() failed!\n", DEVICE_NAME);
		goto reject;
	}

	// allocate memory for my device
	if ((dev = (struct pcandev *)kmalloc(sizeof(struct pcandev), GFP_ATOMIC)) == NULL)
	{
		printk(KERN_ERR "%s: pcan_usb_plugin - memory allocation failed!\n", DEVICE_NAME);
		goto reject;
	}

	dev->wInitStep = 0;

	u   = &dev->port.usb;

	// init structure elements to defaults
	pcan_soft_init(dev, "usb", HW_USB);

	// preset finish flags
	atomic_set(&u->cmd_sync_complete, 0);

	// preset active URB counter
	atomic_set(&u->active_urbs, 0);

	// override standard device access functions
	dev->device_open      = pcan_usb_device_open;
	dev->device_release   = pcan_usb_device_release;
	dev->device_write     = pcan_usb_write;

	// init process wait queues
	init_waitqueue_head(&dev->read_queue);
	init_waitqueue_head(&dev->write_queue);

	// set this before any instructions, fill struct pcandev, part 1
	dev->wInitStep   = 0;
	dev->readreg     = NULL;
	dev->writereg    = NULL;
	dev->cleanup     = pcan_usb_cleanup;
	dev->req_irq     = pcan_usb_req_irq;
	dev->free_irq    = pcan_usb_free_irq;
	dev->open        = pcan_usb_open;
	dev->release     = pcan_usb_release;
	dev->filter      = pcan_create_filter_chain();
	dev->device_params = pcan_usb_device_params;

	if ((err = assignMinorNumber(dev)))
		goto reject;

	// store pointer to kernel supplied usb_dev
	u->usb_dev          = usb_dev;
	u->ucHardcodedDevNr = (uint8_t)(usb_dev->descriptor.bcdDevice & 0xff);
	u->ucRevision       = (uint8_t)(usb_dev->descriptor.bcdDevice >> 8);

	printk(KERN_INFO "%s: usb hardware revision = %d\n", DEVICE_NAME, u->ucRevision);

	// get endpoint addresses (numbers) and associated max data length
	current_interface_setting = &usb_dev->actconfig->interface->altsetting[usb_dev->actconfig->interface->act_altsetting];
	for (i = 0; i < 4; i++)
	{
		u->Endpoint[i].ucNumber = current_interface_setting->endpoint[i].bEndpointAddress;
		u->Endpoint[i].wDataSz  = current_interface_setting->endpoint[i].wMaxPacketSize;
	}

	init_waitqueue_head(&u->usb_wait_queue);

	dev->wInitStep = 1;

	// add into list of devices
	list_add_tail(&dev->list, &pcan_drv.devices);  // add this device to the list
	dev->wInitStep = 2;

	// assign the device as plugged in
	dev->ucPhysicallyInstalled = 1;

	pcan_drv.wDeviceCount++;
	usb_devices++;
	dev->wInitStep = 3;

	if ((err = pcan_usb_allocate_resources(dev)))
		goto reject;

	dev->wInitStep = 4;

	printk(KERN_INFO "%s: usb device minor %d found\n", DEVICE_NAME, dev->nMinor);

#ifdef NETDEV_SUPPORT
	pcan_netdev_register(dev);
#endif

	return (void *)dev;

reject:
	pcan_usb_cleanup(dev);

	printk(KERN_ERR "%s: pcan_usb_plugin() failed! (%d)\n", DEVICE_NAME, err);

	return NULL;
}