Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}