コード例 #1
0
ファイル: serproto.c プロジェクト: muromec/linux-ezxdev
static void serial_close (struct tty_struct *tty, struct file *filp)
{
	unsigned long flags;
	struct serproto_dev *device;
	int uc;

	uc = GET_USE_COUNT (THIS_MODULE);
	dbg_oc (3, "tty #%p file #%p uc=%d", tty, filp, uc);

	if ((device = tty->driver_data) != NULL) {
		write_lock_irqsave (&device->rwlock, flags);
		if (0 >= --device->opencnt) {
			// Last (or extra) close
			dbg_oc (1, "Last: old tty #%p new #%p oc=%d",
				device->tty, tty, device->opencnt);
			tty->driver_data = NULL;
			device->tty = NULL;
			device->opencnt = 0;
		}
		write_unlock_irqrestore (&device->rwlock, flags);
	} else {
		dbg_oc (1, "not presently connected");
	}
	if (uc > 0) {
		// Should really check that uc hasn't changed since start of fn...
		MOD_DEC_USE_COUNT;
		dbg_init (1, "CLOSE uc=%d", GET_USE_COUNT (THIS_MODULE));
	}
	dbg_oc (3, "OK");
	return;
}
コード例 #2
0
/*
 * usbd_pm_callback
 * @dev:
 * @rqst:
 * @unused:
 *
 * Used to signal power management events.
 */
static int bi_pm_event (struct pm_dev *pm_dev, pm_request_t request, void *unused)
{
	struct usb_device_instance *device;

	dbg_pm (0, "request: %d pm_dev: %p data: %p", request, pm_dev, pm_dev->data);

	if (!(device = pm_dev->data)) {
		dbg_pm (0, "DATA NULL, NO DEVICE");
		return 0;
	}

	switch (request) {
#if defined(CONFIG_IRIS)
	case PM_STANDBY:
	case PM_BLANK:
#endif
	case PM_SUSPEND:
		dbg_pm (0, "PM_SUSPEND");
		if (!pm_suspended) {
			pm_suspended = 1;
			dbg_init (1, "MOD_INC_USE_COUNT %d", GET_USE_COUNT (THIS_MODULE));
			udc_disconnect ();	// disable USB pullup if we can
			udc_disable_interrupts (device);	// disable interupts
			udc_disable ();	// disable UDC
			dbg_pm (0, "PM_SUSPEND: finished");
		}
		break;
#if defined(CONFIG_IRIS)
	case PM_UNBLANK:
#endif
	case PM_RESUME:
		dbg_pm (0, "PM_RESUME");
		if (pm_suspended) {
			// probe for device
			if (udc_init ()) {
				dbg_init (0, "udc_init failed");
				//return -EINVAL;
			}
			udc_enable (device);	// enable UDC
			udc_all_interrupts (device);	// enable interrupts
			udc_connect ();	// enable USB pullup if we can
			//udc_set_address(device->address);
			//udc_reset_ep(0);

			pm_suspended = 0;
			dbg_init (1, "MOD_INC_USE_COUNT %d", GET_USE_COUNT (THIS_MODULE));
			dbg_pm (0, "PM_RESUME: finished");
		}
		break;
	}
	return 0;
}
コード例 #3
0
ファイル: serproto.c プロジェクト: muromec/linux-ezxdev
/* *
 * serial_open - open serial device
 * @tty: tty device
 * @filp: file structure
 *
 * Called to open serial device.
 */
static int serial_open (struct tty_struct *tty, struct file *filp)
{
	unsigned long flags;
	int n = 0, rc = 0;
	struct serproto_dev *device = NULL;

	dbg_oc (3, "tty #%p file #%p", tty, filp);

	if (NULL == tty || 0 > (n = MINOR (tty->device) - tty->driver.minor_start) ||
	    n >= serproto_devices || NULL == (device = serproto_device_array[n])) {
		dbg_oc (1, "FAIL ENODEV");
		return -ENODEV;
	}

	MOD_INC_USE_COUNT;
	dbg_init (1, "OPEN uc=%d", GET_USE_COUNT (THIS_MODULE));
	write_lock_irqsave (&device->rwlock, flags);

	if (1 == ++device->opencnt) {
		// First open
		tty->driver_data = device;
		device->tty = tty;
		tty->low_latency = 1;


		/* force low_latency on so that our tty_push actually forces the data through, 
		 * otherwise it is scheduled, and with high data rates (like with OHCI) data
		 * can get lost. 
		 * */
		tty->low_latency = 1;

	} else if (tty->driver_data != device || device->tty != tty) {
		// Second or later open, different tty/device combo
		rc = -EBUSY;
	}
	// XXX Should extract info from somewhere to see if receive is OK
	write_unlock_irqrestore (&device->rwlock, flags);

	if (0 != rc) {
		if (-EBUSY == rc) {
			dbg_oc (1, "2nd, conflict: old dev #%p new #%p, old tty #%p new #%p",
				tty->driver_data, device, device->tty, tty);
		}
		MOD_DEC_USE_COUNT;
		dbg_init (0, "OPEN rc=%d uc=%d", rc, GET_USE_COUNT (THIS_MODULE));
	}
	dbg_oc (3, "->%d n=%d", rc, n);
	return (rc);
}
コード例 #4
0
static int
bi_udc_resume(struct device *dev, u32 level)
{
	int ret = 0;
	struct usb_device_instance *device = device_array[0];

	switch (level) {
	case RESUME_POWER_ON:
		dbg_pm (0, "RESUME_POWER_ON");
		if (udc_init ()) {
			dbg_init (0, "udc_init failed");
		}
		if (device) {
			udc_enable (device);		/* enable UDC */
			udc_all_interrupts (device);	/* enable interrupts */
		}
		udc_connect ();			/* enable USB pullup */

		dbg_init (1, "MOD_INC_USE_COUNT %d", 
			GET_USE_COUNT (THIS_MODULE));
		dbg_pm (0, "RESUME_POWER_ON: finished");
		break;
	}

	return ret;
}
コード例 #5
0
ファイル: capi.c プロジェクト: zipangotes/DSL-G624T_GPL_code
void capiminor_free(struct capiminor *mp)
{
	struct capiminor **pp;

	pp = &minors;
	while (*pp) {
		if (*pp == mp) {
			*pp = (*pp)->next;
			if (mp->ttyskb) kfree_skb(mp->ttyskb);
			mp->ttyskb = 0;
			skb_queue_purge(&mp->recvqueue);
			skb_queue_purge(&mp->inqueue);
			skb_queue_purge(&mp->outqueue);
			capiminor_del_all_ack(mp);
			kmem_cache_free(capiminor_cachep, mp);
			MOD_DEC_USE_COUNT;
#ifdef _DEBUG_REFCOUNT
			printk(KERN_DEBUG "capiminor_free %d\n", GET_USE_COUNT(THIS_MODULE));
#endif
			return;
		} else {
			pp = &(*pp)->next;
		}
	}
}
コード例 #6
0
ファイル: capi.c プロジェクト: zipangotes/DSL-G624T_GPL_code
int capinc_tty_open(struct tty_struct * tty, struct file * file)
{
	struct capiminor *mp;

	if ((mp = capiminor_find(MINOR(file->f_dentry->d_inode->i_rdev))) == 0)
		return -ENXIO;
	if (mp->nccip == 0)
		return -ENXIO;
	if (mp->file)
		return -EBUSY;

	skb_queue_head_init(&mp->recvqueue);
	init_waitqueue_head(&mp->recvwait);
	init_waitqueue_head(&mp->sendwait);
	tty->driver_data = (void *)mp;
#ifdef _DEBUG_REFCOUNT
	printk(KERN_DEBUG "capi_tty_open %d\n", GET_USE_COUNT(THIS_MODULE));
#endif
	if (atomic_read(&mp->ttyopencount) == 0)
		mp->tty = tty;
	atomic_inc(&mp->ttyopencount);
#ifdef _DEBUG_REFCOUNT
	printk(KERN_DEBUG "capinc_tty_open ocount=%d\n", atomic_read(&mp->ttyopencount));
#endif
	handle_minor_recv(mp);
	return 0;
}
コード例 #7
0
ファイル: module.c プロジェクト: liexusong/linux2.0-comment
/*
 * Try to free modules which have been marked for deletion.  Returns nonzero
 * if a module was actually freed.
 */
int
free_modules( void)
{
	struct module *mp;
	struct module **mpp;
	int did_deletion;

	did_deletion = 0;
	freeing_modules = 0;
	mpp = &module_list;
	while ((mp = *mpp) != NULL) {
		if (mp->state != MOD_DELETED) {
			mpp = &mp->next;
		} else {
			if ((GET_USE_COUNT(mp) != 0) || (mp->ref != NULL)) {
				freeing_modules = 1;
				mpp = &mp->next;
			} else {	/* delete it */
				*mpp = mp->next;
				if (mp->symtab) {
					if (mp->symtab->n_refs)
						drop_refs(mp);
					if (mp->symtab->size)
						kfree_s(mp->symtab, mp->symtab->size);
				}
				vfree(mp->addr);
				kfree_s(mp, sizeof(struct module) + MOD_MAX_NAME);
				did_deletion = 1;
			}
		}
	}
	return did_deletion;
}
コード例 #8
0
ファイル: module.c プロジェクト: DreamLiMu/Linux-Kernel-Study
/*
 * Try to free modules which have been marked for deletion.  Returns nonzero
 * if a module was actually freed.
 */
int
free_modules( void)
{
	struct module *mp;
	struct module **mpp;
	int did_deletion;

	did_deletion = 0;
	freeing_modules = 0;
	mpp = &module_list;
	while ((mp = *mpp) != NULL) {
		if (mp->state != MOD_DELETED) {
			mpp = &mp->next;
		} else if (GET_USE_COUNT(mp) != 0) {
			freeing_modules = 1;
			mpp = &mp->next;
		} else {	/* delete it */
			*mpp = mp->next;
			vfree(mp->addr);
			kfree(mp->name);
			kfree_s(mp, sizeof *mp);
			did_deletion = 1;
		}
	}
	return did_deletion;
}
コード例 #9
0
ファイル: capi.c プロジェクト: zipangotes/DSL-G624T_GPL_code
static int
capi_open(struct inode *inode, struct file *file)
{
	if (file->private_data)
		return -EEXIST;

	if ((file->private_data = capidev_alloc(file)) == 0)
		return -ENOMEM;

	MOD_INC_USE_COUNT;
#ifdef _DEBUG_REFCOUNT
	printk(KERN_DEBUG "capi_open %d\n", GET_USE_COUNT(THIS_MODULE));
#endif
	return 0;
}
コード例 #10
0
ファイル: capi.c プロジェクト: zipangotes/DSL-G624T_GPL_code
static int
capi_release(struct inode *inode, struct file *file)
{
	struct capidev *cdev = (struct capidev *)file->private_data;

	lock_kernel();
	capincci_free(cdev, 0xffffffff);
	capidev_free(cdev);
	file->private_data = NULL;
	
	MOD_DEC_USE_COUNT;
#ifdef _DEBUG_REFCOUNT
	printk(KERN_DEBUG "capi_release %d\n", GET_USE_COUNT(THIS_MODULE));
#endif
	unlock_kernel();
	return 0;
}
コード例 #11
0
ファイル: capi.c プロジェクト: zipangotes/DSL-G624T_GPL_code
static int
capinc_raw_release(struct inode *inode, struct file *file)
{
	struct capiminor *mp = (struct capiminor *)file->private_data;

	if (mp) {
		lock_kernel();
		mp->file = 0;
		if (mp->nccip == 0) {
			capiminor_free(mp);
			file->private_data = NULL;
		}
		unlock_kernel();
	}

#ifdef _DEBUG_REFCOUNT
	printk(KERN_DEBUG "capinc_raw_release %d\n", GET_USE_COUNT(THIS_MODULE));
#endif
	return 0;
}
コード例 #12
0
static int
bi_udc_suspend(struct device *dev, u32 state, u32 level)
{
	struct usb_device_instance *device = device_array[0];

	switch (level) {
	case SUSPEND_POWER_DOWN:
		dbg_pm (0, "SUSPEND_POWER_DOWN");
		dbg_init (1, "MOD_INC_USE_COUNT %d", 
			GET_USE_COUNT (THIS_MODULE));
		udc_disconnect ();		/* disable USB pullup */
		if (device)
			udc_disable_interrupts (device);	/* disable interrupts */
		udc_disable ();			/* disable UDC */
		dbg_pm (0, "SUSPEND_POWER_DOWN: finished");
		break;
	}

	return 0;
}
コード例 #13
0
ファイル: capi.c プロジェクト: zipangotes/DSL-G624T_GPL_code
struct capiminor *capiminor_alloc(__u16 applid, __u32 ncci)
{
	struct capiminor *mp, **pp;
        unsigned int minor = 0;

	MOD_INC_USE_COUNT;
	mp = (struct capiminor *)kmem_cache_alloc(capiminor_cachep, GFP_ATOMIC);
	if (!mp) {
		MOD_DEC_USE_COUNT;
		printk(KERN_ERR "capi: can't alloc capiminor\n");
		return 0;
	}
#ifdef _DEBUG_REFCOUNT
	printk(KERN_DEBUG "capiminor_alloc %d\n", GET_USE_COUNT(THIS_MODULE));
#endif
	memset(mp, 0, sizeof(struct capiminor));
	mp->applid = applid;
	mp->ncci = ncci;
	mp->msgid = 0;
	atomic_set(&mp->ttyopencount,0);

	skb_queue_head_init(&mp->inqueue);
	skb_queue_head_init(&mp->outqueue);

	skb_queue_head_init(&mp->recvqueue);
	init_waitqueue_head(&mp->recvwait);
	init_waitqueue_head(&mp->sendwait);

	for (pp = &minors; *pp; pp = &(*pp)->next) {
		if ((*pp)->minor < minor)
			continue;
		if ((*pp)->minor > minor)
			break;
		minor++;
	}
	mp->minor = minor;
	mp->next = *pp;
	*pp = mp;
	return mp;
}
コード例 #14
0
ファイル: module.c プロジェクト: liexusong/linux2.0-comment
asmlinkage int
sys_delete_module(char *module_name)
{
	struct module *mp;
	char name[MOD_MAX_NAME];
	int error;

	if (!suser())
		return -EPERM;
	/* else */
	if (module_name != NULL) {
		if ((error = get_mod_name(module_name, name)) != 0)
			return error;
		if ((mp = find_module(name)) == NULL)
			return -ENOENT;
		if ((mp->ref != NULL) ||
		    ((GET_USE_COUNT(mp) & ~(MOD_AUTOCLEAN | MOD_VISITED)) != 0))
			return -EBUSY;
		GET_USE_COUNT(mp) &= ~(MOD_AUTOCLEAN | MOD_VISITED);
		if (mp->state == MOD_RUNNING)
			(*mp->cleanup)();
		mp->state = MOD_DELETED;
		free_modules();
	}
	/* for automatic reaping */
	else {
		struct module *mp_next;
		for (mp = module_list; mp != &kernel_module; mp = mp_next) {
			mp_next = mp->next;
			if ((mp->ref == NULL) && (mp->state == MOD_RUNNING) &&
			    ((GET_USE_COUNT(mp) & ~MOD_VISITED) == MOD_AUTOCLEAN)) {
			    	if ((GET_USE_COUNT(mp) & MOD_VISITED)) {
					/* Don't reap until one "cycle" after last _use_ */
			   		GET_USE_COUNT(mp) &= ~MOD_VISITED;
				}
				else {
					GET_USE_COUNT(mp) &= ~(MOD_AUTOCLEAN | MOD_VISITED);
					(*mp->cleanup)();
					mp->state = MOD_DELETED;
					free_modules();
				}
			}
		}
	}
	return 0;
}
コード例 #15
0
ファイル: capi.c プロジェクト: zipangotes/DSL-G624T_GPL_code
static int
capinc_raw_open(struct inode *inode, struct file *file)
{
	struct capiminor *mp;

	if (file->private_data)
		return -EEXIST;
	if ((mp = capiminor_find(MINOR(file->f_dentry->d_inode->i_rdev))) == 0)
		return -ENXIO;
	if (mp->nccip == 0)
		return -ENXIO;
	if (mp->file)
		return -EBUSY;

#ifdef _DEBUG_REFCOUNT
	printk(KERN_DEBUG "capi_raw_open %d\n", GET_USE_COUNT(THIS_MODULE));
#endif

	mp->datahandle = 0;
	mp->file = file;
	file->private_data = (void *)mp;
	handle_minor_recv(mp);
	return 0;
}
コード例 #16
0
ファイル: zftape-init.c プロジェクト: archith/camera_project
/* Called by modules package before trying to unload the module
 */
static int can_unload(void)
{
	return (GET_USE_COUNT(THIS_MODULE)||zft_dirty()||busy_flag)?-EBUSY:0;
}
コード例 #17
0
ファイル: module.c プロジェクト: liexusong/linux2.0-comment
/*
 * Called by the /proc file system to return a current list of modules.
 */
int get_module_list(char *buf)
{
	char *p;
	const char *q;
	int i;
	struct module *mp;
	struct module_ref *ref;
	char size[32];

	p = buf;
	/* Do not show the kernel pseudo module */
	for (mp = module_list ; mp && mp->next; mp = mp->next) {
		if (p - buf > 4096 - 100)
			break;			/* avoid overflowing buffer */
		q = mp->name;
		if (*q == '\0' && mp->size == 0 && mp->ref == NULL)
			continue; /* don't list modules for kernel syms */
		i = 20;
		while (*q) {
			*p++ = *q++;
			i--;
		}
		sprintf(size, "%d", mp->size);
		i -= strlen(size);
		if (i <= 0)
			i = 1;
		while (--i >= 0)
			*p++ = ' ';
		q = size;
		while (*q)
			*p++ = *q++;
		if (mp->state == MOD_UNINITIALIZED)
			q = "  (uninitialized)";
		else if (mp->state == MOD_RUNNING)
			q = "";
		else if (mp->state == MOD_DELETED)
			q = "  (deleted)";
		else
			q = "  (bad state)";
		while (*q)
			*p++ = *q++;

		*p++ = '\t';
		if ((ref = mp->ref) != NULL) {
			*p++ = '[';
			for (; ref; ref = ref->next) {
				q = ref->module->name;
				while (*q)
					*p++ = *q++;
				if (ref->next)
					*p++ = ' ';
			}
			*p++ = ']';
		}
		if (mp->state == MOD_RUNNING) {
			sprintf(size,"\t%ld%s",
				GET_USE_COUNT(mp) & ~(MOD_AUTOCLEAN | MOD_VISITED),
				((GET_USE_COUNT(mp) & MOD_AUTOCLEAN)?
					" (autoclean)":""));
			q = size;
			while (*q)
				*p++ = *q++;
		}
		*p++ = '\n';
	}
	return p - buf;
}
コード例 #18
0
ファイル: module.c プロジェクト: liexusong/linux2.0-comment
/*
 * Initialize a module.
 */
asmlinkage int
sys_init_module(char *module_name, char *code, unsigned codesize,
		struct mod_routines *routines,
		struct symbol_table *symtab)
{
	struct module *mp;
	struct symbol_table *newtab;
	char name[MOD_MAX_NAME];
	int error;
	struct mod_routines rt;

	if (!suser())
		return -EPERM;

#ifdef __i386__
	/* A little bit of protection... we "know" where the user stack is... */

	if (symtab && ((unsigned long)symtab > 0xb0000000)) {
		printk(KERN_WARNING "warning: you are using an old insmod, no symbols will be inserted!\n");
		symtab = NULL;
	}
#endif
	if ((error = get_mod_name(module_name, name)) != 0)
		return error;
	pr_debug("initializing module `%s', %d (0x%x) bytes\n",
		name, codesize, codesize);
	memcpy_fromfs(&rt, routines, sizeof rt);
	if ((mp = find_module(name)) == NULL)
		return -ENOENT;
	if (codesize & MOD_AUTOCLEAN) {
		/*
		 * set autoclean marker from codesize...
		 * set usage count to "zero"
		 */
		codesize &= ~MOD_AUTOCLEAN;
		GET_USE_COUNT(mp) = MOD_AUTOCLEAN;
	}
	if ((codesize + sizeof (long) + PAGE_SIZE - 1) / PAGE_SIZE > mp->size)
		return -EINVAL;
	memcpy_fromfs((char *)mp->addr + sizeof (long), code, codesize);
	memset((char *)mp->addr + sizeof (long) + codesize, 0,
		mp->size * PAGE_SIZE - (codesize + sizeof (long)));
	pr_debug("module init entry = 0x%08lx, cleanup entry = 0x%08lx\n",
		(unsigned long) rt.init, (unsigned long) rt.cleanup);
	mp->cleanup = rt.cleanup;

	/* update kernel symbol table */
	if (symtab) { /* symtab == NULL means no new entries to handle */
		struct internal_symbol *sym;
		struct module_ref *ref;
		int size;
		int i;
		int legal_start;

		if ((error = verify_area(VERIFY_READ, &symtab->size, sizeof(symtab->size))))
			return error;
		size = get_user(&symtab->size);

		if ((newtab = (struct symbol_table*) kmalloc(size, GFP_KERNEL)) == NULL) {
			return -ENOMEM;
		}

		if ((error = verify_area(VERIFY_READ, symtab, size))) {
			kfree_s(newtab, size);
			return error;
		}
		memcpy_fromfs((char *)(newtab), symtab, size);

		/* sanity check */
		legal_start = sizeof(struct symbol_table) +
			newtab->n_symbols * sizeof(struct internal_symbol) +
			newtab->n_refs * sizeof(struct module_ref);

		if ((newtab->n_symbols < 0) || (newtab->n_refs < 0) || (legal_start > size)) {
			printk(KERN_WARNING "Rejecting illegal symbol table (n_symbols=%d,n_refs=%d)\n",
			       newtab->n_symbols, newtab->n_refs);
			kfree_s(newtab, size);
			return -EINVAL;
		}

		/* relocate name pointers, index referred from start of table */
		for (sym = &(newtab->symbol[0]), i = 0; i < newtab->n_symbols; ++sym, ++i) {
			if ((unsigned long)sym->name < legal_start || size <= (unsigned long)sym->name) {
				printk(KERN_WARNING "Rejecting illegal symbol table\n");
				kfree_s(newtab, size);
				return -EINVAL;
			}
			/* else */
			sym->name += (long)newtab;
		}
		mp->symtab = newtab;

		/* Update module references.
		 * On entry, from "insmod", ref->module points to
		 * the referenced module!
		 * Now it will point to the current module instead!
		 * The ref structure becomes the first link in the linked
		 * list of references to the referenced module.
		 * Also, "sym" from above, points to the first ref entry!!!
		 */
		for (ref = (struct module_ref *)sym, i = 0;
			i < newtab->n_refs; ++ref, ++i) {

			/* Check for valid reference */
			struct module *link = module_list;
			while (link && (ref->module != link))
				link = link->next;

			if (link == (struct module *)0) {
				printk(KERN_WARNING "Non-module reference! Rejected!\n");
				return -EINVAL;
			}

			ref->next = ref->module->ref;
			ref->module->ref = ref;
			ref->module = mp;
		}
	}

	GET_USE_COUNT(mp) += 1;
	if ((*rt.init)() != 0) {
		GET_USE_COUNT(mp) = 0;
		return -EBUSY;
	}
	GET_USE_COUNT(mp) -= 1;
	mp->state = MOD_RUNNING;

	return 0;
}