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