//---------------------------------------------------------------------------- // 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; }
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; }
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; }
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; }