예제 #1
0
static int capi_manufacturer(unsigned int cmd, void *data)
{
	unsigned long flags;
	avmb1_loadandconfigdef ldef;
	avmb1_extcarddef cdef;
	avmb1_resetdef rdef;
	avmb1_getdef gdef;
	avmb1_card *card;
	int rc;

	switch (cmd) {
	case AVMB1_ADDCARD:
	case AVMB1_ADDCARD_WITH_TYPE:
		if (cmd == AVMB1_ADDCARD) {
		   if ((rc = copy_from_user((void *) &cdef, data,
					    sizeof(avmb1_carddef))))
			   return rc;
		   cdef.cardtype = AVM_CARDTYPE_B1;
		} else {
		   if ((rc = copy_from_user((void *) &cdef, data,
					    sizeof(avmb1_extcarddef))))
			   return rc;
		}

		if ((rc = avmb1_probecard(cdef.port, cdef.irq, cdef.cardtype)) != 0)
			return rc;

		return avmb1_addcard(cdef.port, cdef.irq, cdef.cardtype);

	case AVMB1_LOAD:
	case AVMB1_LOAD_AND_CONFIG:

		if (cmd == AVMB1_LOAD) {
			if ((rc = copy_from_user((void *) &ldef, data,
						sizeof(avmb1_loaddef))))
				return rc;
			ldef.t4config.len = 0;
			ldef.t4config.data = 0;
		} else {
			if ((rc = copy_from_user((void *) &ldef, data,
					    	sizeof(avmb1_loadandconfigdef))))
				return rc;
		}
		if (!VALID_CARD(ldef.contr))
			return -ESRCH;

		if (ldef.t4file.len <= 0) {
			if (loaddebug)
				printk(KERN_DEBUG "b1capi: load: invalid parameter length of t4file is %d ?\n", ldef.t4file.len);
			return -EINVAL;
		}

		card = CARD(ldef.contr);
		save_flags(flags);
		cli();
		if (card->cardstate != CARD_DETECTED) {
			restore_flags(flags);
			if (loaddebug)
				printk(KERN_DEBUG "b1capi: load: contr=%d not in detect state\n", ldef.contr);
			return -EBUSY;
		}
		card->cardstate = CARD_LOADING;
		restore_flags(flags);

		if (loaddebug) {
			printk(KERN_DEBUG "b1capi: load: reseting contr %d\n",
				ldef.contr);
		}

		B1_reset(card->port);
		if ((rc = B1_load_t4file(card->port, &ldef.t4file))) {
			B1_reset(card->port);
			printk(KERN_ERR "b1capi: failed to load t4file!!\n");
			card->cardstate = CARD_DETECTED;
			return rc;
		}
		B1_disable_irq(card->port);

		if (ldef.t4config.len > 0) { /* load config */
		        if (loaddebug) {
				printk(KERN_DEBUG "b1capi: loading config to contr %d\n",
				   			ldef.contr);
		   	}
			if ((rc = B1_load_config(card->port, &ldef.t4config))) {
				B1_reset(card->port);
				printk(KERN_ERR "b1capi: failed to load config!!\n");
				card->cardstate = CARD_DETECTED;
				return rc;
			}
		}

		if (loaddebug) {
			printk(KERN_DEBUG "b1capi: load: ready contr %d: checking\n",
				ldef.contr);
		}

		if (!B1_loaded(card->port)) {
			card->cardstate = CARD_DETECTED;
			printk(KERN_ERR "b1capi: failed to load t4file.\n");
			return -EIO;
		}
		/*
		 * enable interrupt
		 */

		card->cardstate = CARD_INITSTATE;
		save_flags(flags);
		cli();
		B1_assign_irq(card->port, card->irq, card->cardtype);
		B1_enable_irq(card->port);
		restore_flags(flags);

		if (loaddebug) {
			printk(KERN_DEBUG "b1capi: load: irq enabled contr %d\n",
				ldef.contr);
		}

		/*
		 * init card
		 */
		B1_send_init(card->port, AVM_NAPPS, AVM_NNCCI, card->cnr - 1);

		if (loaddebug) {
			printk(KERN_DEBUG "b1capi: load: waiting for init reply contr %d\n",
				ldef.contr);
		}

		while (card->cardstate != CARD_RUNNING) {

			current->state = TASK_INTERRUPTIBLE;
			schedule_timeout(HZ/10);	/* 0.1 sec */

			if (signal_pending(current))
				return -EINTR;
		}
		return 0;

	case AVMB1_RESETCARD:
		if ((rc = copy_from_user((void *) &rdef, data,
					 sizeof(avmb1_resetdef))))
			return rc;

		return avmb1_resetcard(rdef.contr);

	case AVMB1_GET_CARDINFO:
		if ((rc = copy_from_user((void *) &gdef, data,
					 sizeof(avmb1_getdef))))
			return rc;

		if (!VALID_CARD(gdef.contr))
			return -ESRCH;

		card = CARD(gdef.contr);

		gdef.cardstate = card->cardstate;
		gdef.cardtype = card->cardtype;

		if ((rc = copy_to_user(data, (void *) &gdef,
					 sizeof(avmb1_getdef))))
			return rc;

		return 0;
	}
	return -EINVAL;
}
예제 #2
0
파일: b1capi.c 프로젝트: rohsaini/mkunity
static int capi_manufacturer(unsigned int cmd, void *data)
{
	unsigned long flags;
	avmb1_loaddef ldef;
	avmb1_carddef cdef;
	avmb1_resetdef rdef;
	avmb1_card *card;
	int rc;

	switch (cmd) {
	case AVMB1_ADDCARD:
		if ((rc = copy_from_user((void *) &cdef, data,
					 sizeof(avmb1_carddef))))
			return rc;
		if (!B1_valid_irq(cdef.irq))
			return -EINVAL;

		if ((rc = avmb1_probecard(cdef.port, cdef.irq)) != 0)
			return rc;

		return avmb1_addcard(cdef.port, cdef.irq);

	case AVMB1_LOAD:

		if ((rc = copy_from_user((void *) &ldef, data,
					 sizeof(avmb1_loaddef))))
			return rc;
		if (!VALID_CARD(ldef.contr) || ldef.t4file.len <= 0) {
			if (loaddebug)
				printk(KERN_DEBUG "b1capi: load: invalid parameter contr=%d len=%d\n", ldef.contr, ldef.t4file.len);
			return -EINVAL;
		}

		card = CARD(ldef.contr);
		save_flags(flags);
		cli();
		if (card->cardstate != CARD_DETECTED) {
			restore_flags(flags);
			if (loaddebug)
				printk(KERN_DEBUG "b1capi: load: contr=%d not in detect state\n", ldef.contr);
			return -EBUSY;
		}
		card->cardstate = CARD_LOADING;
		restore_flags(flags);

		if (loaddebug) {
			printk(KERN_DEBUG "b1capi: load: reseting contr %d\n",
				ldef.contr);
		}

		B1_reset(card->port);
		if ((rc = B1_load_t4file(card->port, &ldef.t4file))) {
			B1_reset(card->port);
			printk(KERN_ERR "b1capi: failed to load t4file!!\n");
			card->cardstate = CARD_DETECTED;
			return rc;
		}
		B1_disable_irq(card->port);
		if (loaddebug) {
			printk(KERN_DEBUG "b1capi: load: ready contr %d: checking\n",
				ldef.contr);
		}

		if (!B1_loaded(card->port)) {
			card->cardstate = CARD_DETECTED;
			printk(KERN_ERR "b1capi: failed to load t4file.\n");
			return -EIO;
		}
		/*
		 * enable interrupt
		 */

		card->cardstate = CARD_INITSTATE;
		save_flags(flags);
		cli();
		B1_assign_irq(card->port, card->irq);
		B1_enable_irq(card->port);
		restore_flags(flags);

		if (loaddebug) {
			printk(KERN_DEBUG "b1capi: load: irq enabled contr %d\n",
				ldef.contr);
		}

		/*
		 * init card
		 */
		B1_send_init(card->port, AVM_NAPPS, AVM_NNCCI, card->cnr - 1);

		if (loaddebug) {
			printk(KERN_DEBUG "b1capi: load: waiting for init reply contr %d\n",
				ldef.contr);
		}

		while (card->cardstate != CARD_RUNNING) {

			current->timeout = jiffies + HZ / 10;	/* 0.1 sec */
			current->state = TASK_INTERRUPTIBLE;
			schedule();

			if (current->signal & ~current->blocked)
				return -EINTR;
		}
		return 0;
	case AVMB1_RESETCARD:
		if ((rc = copy_from_user((void *) &rdef, data,
					 sizeof(avmb1_resetdef))))
			return rc;

		if (!VALID_CARD(rdef.contr))
			return -EINVAL;

		card = CARD(rdef.contr);

		if (card->cardstate == CARD_RUNNING)
			avmb1_card_down(card);

		card->cardstate = CARD_DETECTED;

		B1_reset(card->port);
		B1_reset(card->port);

		return 0;
	}
	return -EINVAL;
}