Exemple #1
0
//----------------------------------------------------------------------------
// create all declared isa devices
int pcan_create_isa_devices(char* type, u32 io, u16 irq)
{
  int    result = 0;
  struct pcandev *dev = NULL;

  // create isa devices
  DPRINTK(KERN_DEBUG "%s: pcan_create_isa_devices(0x%x, %d)\n", DEVICE_NAME, io, irq);
  
  if ((dev = (struct pcandev *)kmalloc(sizeof(struct pcandev), GFP_KERNEL)) == NULL)
  {
    result = -ENOMEM;
    goto fail;
  }

  pcan_soft_init(dev, type, HW_ISA_SJA);
  
  dev->device_open    = sja1000_open;
  dev->device_write   = sja1000_write;
  dev->device_release = sja1000_release;

  result = pcan_isa_init(dev, io, irq);
  if (!result)
    result = sja1000_probe(dev);

  if (result)
  {
    dev->cleanup(dev);
    kfree(dev);
    goto fail;
  }
  else
  {
    dev->ucPhysicallyInstalled = 1;
    list_add_tail(&dev->list, &pcan_drv.devices);  // add this device to the list
    pcan_drv.wDeviceCount++;
  }        
  
  fail:
  if (result)
    DPRINTK(KERN_DEBUG "%s: pcan_create_isa_devices() failed!\n", DEVICE_NAME);
  else
    DPRINTK(KERN_DEBUG "%s: pcan_create_isa_devices() is OK\n", DEVICE_NAME);

  return result;
}
Exemple #2
0
int pcan_create_dongle_devices(char *type, u32 io, u16 irq)
{
  int result = 0;
  struct pcandev *dev = NULL;
  
  DPRINTK(KERN_DEBUG "%s: pcan_create_dongle_devices(%s, 0x%x, %d)\n", DEVICE_NAME, type, io, irq);
  
  if ((dev = (struct pcandev *)kmalloc(sizeof(struct pcandev), GFP_KERNEL)) == NULL)
    goto fail;

  pcan_soft_init(dev, type, (!strncmp(type, "sp", 4)) ? HW_DONGLE_SJA : HW_DONGLE_SJA_EPP);
  
  dev->device_open    = sja1000_open;
  dev->device_write   = sja1000_write;
  dev->device_release = sja1000_release;
  
  result = pcan_dongle_init(dev, io, irq, type);
  
  if (result)
  {
    dev->cleanup(dev);
    kfree(dev);
    goto fail;
  }
  else
  {
    list_add_tail(&dev->list, &pcan_drv.devices);  // add this device to the list        
    pcan_drv.wDeviceCount++;
  }

  fail:
  if (result)
    DPRINTK(KERN_DEBUG "%s: pcan_create_dongle_devices() failed!\n", DEVICE_NAME);
  else
    DPRINTK(KERN_DEBUG "%s: pcan_create_dongle_devices() OK!\n", DEVICE_NAME);
    
  return result;
}
Exemple #3
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;
}
Exemple #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;
}