int me_dlock_lock(struct me_dlock *dlock, struct file *filep, int lock, int flags, me_slist_t * slist) { int err = ME_ERRNO_SUCCESS; int i; me_subdevice_t *subdevice; PDEBUG_LOCKS("executed.\n"); spin_lock(&dlock->spin_lock); switch (lock) { case ME_LOCK_RELEASE: if ((dlock->filep == filep) || (dlock->filep == NULL)) { dlock->filep = NULL; /* Unlock all possibly locked subdevices. */ for (i = 0; i < me_slist_get_number_subdevices(slist); i++) { subdevice = me_slist_get_subdevice(slist, i); if (subdevice) err = subdevice-> me_subdevice_lock_subdevice (subdevice, filep, ME_LOCK_RELEASE, flags); else err = ME_ERRNO_INTERNAL; } } break; case ME_LOCK_SET: if (dlock->count) { PERROR("Device is used by another process.\n"); err = ME_ERRNO_USED; } else if ((dlock->filep != NULL) && (dlock->filep != filep)) { PERROR("Device is locked by another process.\n"); err = ME_ERRNO_LOCKED; } else if (dlock->filep == NULL) { /* Check any subdevice is locked by another process. */ for (i = 0; i < me_slist_get_number_subdevices(slist); i++) { subdevice = me_slist_get_subdevice(slist, i); if (subdevice) { if ((err = subdevice-> me_subdevice_lock_subdevice (subdevice, filep, ME_LOCK_CHECK, flags))) { PERROR ("A subdevice is locked by another process.\n"); break; } } else { err = ME_ERRNO_INTERNAL; } } /* If no subdevices are locked by other processes, we can take ownership of the device. Otherwise we jump ahead. */ if (!err) dlock->filep = filep; } break; case ME_LOCK_CHECK: if (dlock->count) { err = ME_ERRNO_USED; } else if ((dlock->filep != NULL) && (dlock->filep != filep)) { err = ME_ERRNO_LOCKED; } else if (dlock->filep == NULL) { for (i = 0; i < me_slist_get_number_subdevices(slist); i++) { subdevice = me_slist_get_subdevice(slist, i); if (subdevice) { if ((err = subdevice-> me_subdevice_lock_subdevice (subdevice, filep, ME_LOCK_CHECK, flags))) { PERROR ("A subdevice is locked by another process.\n"); break; } } else { err = ME_ERRNO_INTERNAL; } } } break; default: PERROR("Invalid lock.\n"); err = ME_ERRNO_INVALID_LOCK; break; } spin_unlock(&dlock->spin_lock); return err; }
static int me1000_config_load(me_device_t *me_device, struct file *filep, me_cfg_device_entry_t *config) { me1000_device_t *me1000_device; me1000_dio_subdevice_t *dio; PDEBUG("executed.\n"); me1000_device = (me1000_device_t *) me_device; if (config->count == 2) { if (me_slist_get_number_subdevices(&me1000_device->base.slist) == 2) { // Nothing to do. } else { // Remove 2 extra subdevices dio = (me1000_dio_subdevice_t *) me_slist_del_subdevice_tail(&me1000_device->base. slist); if (dio) dio->base. me_subdevice_destructor((me_subdevice_t *) dio); dio = (me1000_dio_subdevice_t *) me_slist_del_subdevice_tail(&me1000_device->base. slist); if (dio) dio->base. me_subdevice_destructor((me_subdevice_t *) dio); } } else if (config->count == 4) { //Add 2 subdevices if (me_slist_get_number_subdevices(&me1000_device->base.slist) == 2) { dio = me1000_dio_constructor(me1000_device->base.info.pci. reg_bases[2], 2, &me1000_device->ctrl_lock); if (!dio) { PERROR("Cannot create dio subdevice.\n"); return ME_ERRNO_INTERNAL; } me_slist_add_subdevice_tail(&me1000_device->base.slist, (me_subdevice_t *) dio); dio = me1000_dio_constructor(me1000_device->base.info.pci. reg_bases[2], 3, &me1000_device->ctrl_lock); if (!dio) { dio = (me1000_dio_subdevice_t *) me_slist_del_subdevice_tail(&me1000_device-> base.slist); if (dio) dio->base. me_subdevice_destructor((me_subdevice_t *) dio); PERROR("Cannot create dio subdevice.\n"); return ME_ERRNO_INTERNAL; } me_slist_add_subdevice_tail(&me1000_device->base.slist, (me_subdevice_t *) dio); } else { // Nothing to do. } } else { PERROR("Invalid configuration.\n"); return ME_ERRNO_INTERNAL; } return ME_ERRNO_SUCCESS; }