Exemple #1
0
static int
hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
{
	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
	struct hfcsusb		*hw = dch->hw;
	int			ret = -EINVAL;
	u_long			flags;

	switch (hh->prim) {
	case PH_DATA_REQ:
		if (debug & DBG_HFC_CALL_TRACE)
			printk(KERN_DEBUG "%s: %s: PH_DATA_REQ\n",
				hw->name, __func__);

		spin_lock_irqsave(&hw->lock, flags);
		ret = dchannel_senddata(dch, skb);
		spin_unlock_irqrestore(&hw->lock, flags);
		if (ret > 0) {
			ret = 0;
			queue_ch_frame(ch, PH_DATA_CNF, hh->id, NULL);
		}
		break;

	case PH_ACTIVATE_REQ:
		if (debug & DBG_HFC_CALL_TRACE)
			printk(KERN_DEBUG "%s: %s: PH_ACTIVATE_REQ %s\n",
				hw->name, __func__,
				(hw->protocol == ISDN_P_NT_S0) ? "NT" : "TE");

		if (hw->protocol == ISDN_P_NT_S0) {
			ret = 0;
			if (test_bit(FLG_ACTIVE, &dch->Flags)) {
				_queue_data(&dch->dev.D,
					PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
					NULL, GFP_ATOMIC);
			} else {
				hfcsusb_ph_command(hw,
					HFC_L1_ACTIVATE_NT);
				test_and_set_bit(FLG_L2_ACTIVATED,
					&dch->Flags);
			}
		} else {
			hfcsusb_ph_command(hw, HFC_L1_ACTIVATE_TE);
			ret = l1_event(dch->l1, hh->prim);
		}
		break;

	case PH_DEACTIVATE_REQ:
		if (debug & DBG_HFC_CALL_TRACE)
			printk(KERN_DEBUG "%s: %s: PH_DEACTIVATE_REQ\n",
				hw->name, __func__);
		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);

		if (hw->protocol == ISDN_P_NT_S0) {
			hfcsusb_ph_command(hw, HFC_L1_DEACTIVATE_NT);
			spin_lock_irqsave(&hw->lock, flags);
			skb_queue_purge(&dch->squeue);
			if (dch->tx_skb) {
				dev_kfree_skb(dch->tx_skb);
				dch->tx_skb = NULL;
			}
			dch->tx_idx = 0;
			if (dch->rx_skb) {
				dev_kfree_skb(dch->rx_skb);
				dch->rx_skb = NULL;
			}
			test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
			spin_unlock_irqrestore(&hw->lock, flags);
#ifdef FIXME
			if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
				dchannel_sched_event(&hc->dch, D_CLEARBUSY);
#endif
			ret = 0;
		} else
			ret = l1_event(dch->l1, hh->prim);
		break;
	case MPH_INFORMATION_REQ:
		hfcsusb_ph_info(hw);
		ret = 0;
		break;
	}

	return ret;
}
/* This is the common part of the URB message submission code
 *
 * All URBs from the usb-storage driver involved in handling a queued scsi
 * command _must_ pass through this function (or something like it) for the
 * abort mechanisms to work properly.
 */
static int usb_stor_msg_common(struct us_data *us, int timeout)
{
	struct completion urb_done;
	long timeleft;
	int status;

	/* don't submit URBs during abort processing */
	if (test_bit(US_FLIDX_ABORTING, &us->dflags))
		return -EIO;

	/* set up data structures for the wakeup system */
	init_completion(&urb_done);

	/* fill the common fields in the URB */
	us->current_urb->context = &urb_done;
	us->current_urb->transfer_flags = 0;

	/* we assume that if transfer_buffer isn't us->iobuf then it
	 * hasn't been mapped for DMA.  Yes, this is clunky, but it's
	 * easier than always having the caller tell us whether the
	 * transfer buffer has already been mapped. */
	if (us->current_urb->transfer_buffer == us->iobuf)
		us->current_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	us->current_urb->transfer_dma = us->iobuf_dma;

	/* submit the URB */
	status = usb_submit_urb(us->current_urb, GFP_NOIO);
	if (status) {
		/* something went wrong */
		return status;
	}

	/* since the URB has been submitted successfully, it's now okay
	 * to cancel it */
	set_bit(US_FLIDX_URB_ACTIVE, &us->dflags);

	/* did an abort occur during the submission? */
	if (test_bit(US_FLIDX_ABORTING, &us->dflags)) {

		/* cancel the URB, if it hasn't been cancelled already */
		if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) {
			US_DEBUGP("-- cancelling URB\n");
			usb_unlink_urb(us->current_urb);
		}
	}
 
	/* wait for the completion of the URB */
	timeleft = wait_for_completion_interruptible_timeout(
			&urb_done, timeout ? : MAX_SCHEDULE_TIMEOUT);
 
	clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags);

	if (timeleft <= 0) {
		US_DEBUGP("%s -- cancelling URB\n",
			  timeleft == 0 ? "Timeout" : "Signal");
		usb_kill_urb(us->current_urb);
	}

	/* return the URB status */
	return us->current_urb->status;
}
static int qlcnic_set_led(struct net_device *dev,
			  enum ethtool_phys_id_state state)
{
	struct qlcnic_adapter *adapter = netdev_priv(dev);
	int max_sds_rings = adapter->max_sds_rings;
	int err = -EIO, active = 1;

	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
		netdev_warn(dev, "LED test not supported for non "
				"privilege function\n");
		return -EOPNOTSUPP;
	}

	switch (state) {
	case ETHTOOL_ID_ACTIVE:
		if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
			return -EBUSY;

		if (test_bit(__QLCNIC_RESETTING, &adapter->state))
			break;

		if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
			if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
				break;
			set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
		}

		if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) {
			err = 0;
			break;
		}

		dev_err(&adapter->pdev->dev,
			"Failed to set LED blink state.\n");
		break;

	case ETHTOOL_ID_INACTIVE:
		active = 0;

		if (test_bit(__QLCNIC_RESETTING, &adapter->state))
			break;

		if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
			if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
				break;
			set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
		}

		if (adapter->nic_ops->config_led(adapter, 0, 0xf))
			dev_err(&adapter->pdev->dev,
				"Failed to reset LED blink state.\n");

		break;

	default:
		return -EINVAL;
	}

	if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
		qlcnic_diag_free_res(dev, max_sds_rings);

	if (!active || err)
		clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);

	return err;
}
Exemple #4
0
/*
 * see if we have space for a number of pages and/or a number of files in the
 * cache
 */
int cachefiles_has_space(struct cachefiles_cache *cache,
			 unsigned fnr, unsigned bnr)
{
	struct kstatfs stats;
	struct path path = {
		.mnt	= cache->mnt,
		.dentry	= cache->mnt->mnt_root,
	};
	int ret;

	//_enter("{%llu,%llu,%llu,%llu,%llu,%llu},%u,%u",
	//       (unsigned long long) cache->frun,
	//       (unsigned long long) cache->fcull,
	//       (unsigned long long) cache->fstop,
	//       (unsigned long long) cache->brun,
	//       (unsigned long long) cache->bcull,
	//       (unsigned long long) cache->bstop,
	//       fnr, bnr);

	/* find out how many pages of blockdev are available */
	memset(&stats, 0, sizeof(stats));

	ret = vfs_statfs(&path, &stats);
	if (ret < 0) {
		if (ret == -EIO)
			cachefiles_io_error(cache, "statfs failed");
		_leave(" = %d", ret);
		return ret;
	}

	stats.f_bavail >>= cache->bshift;

	//_debug("avail %llu,%llu",
	//       (unsigned long long) stats.f_ffree,
	//       (unsigned long long) stats.f_bavail);

	/* see if there is sufficient space */
	if (stats.f_ffree > fnr)
		stats.f_ffree -= fnr;
	else
		stats.f_ffree = 0;

	if (stats.f_bavail > bnr)
		stats.f_bavail -= bnr;
	else
		stats.f_bavail = 0;

	ret = -ENOBUFS;
	if (stats.f_ffree < cache->fstop ||
	    stats.f_bavail < cache->bstop)
		goto begin_cull;

	ret = 0;
	if (stats.f_ffree < cache->fcull ||
	    stats.f_bavail < cache->bcull)
		goto begin_cull;

	if (test_bit(CACHEFILES_CULLING, &cache->flags) &&
	    stats.f_ffree >= cache->frun &&
	    stats.f_bavail >= cache->brun &&
	    test_and_clear_bit(CACHEFILES_CULLING, &cache->flags)
	    ) {
		_debug("cease culling");
		cachefiles_state_changed(cache);
	}

	//_leave(" = 0");
	return 0;

begin_cull:
	if (!test_and_set_bit(CACHEFILES_CULLING, &cache->flags)) {
		_debug("### CULL CACHE ###");
		cachefiles_state_changed(cache);
	}

	_leave(" = %d", ret);
	return ret;
}
Exemple #5
0
Fichier : gc.c Projet : Lyude/linux
/*
 * Garbage collector for unused keys.
 *
 * This is done in process context so that we don't have to disable interrupts
 * all over the place.  key_put() schedules this rather than trying to do the
 * cleanup itself, which means key_put() doesn't have to sleep.
 */
static void key_garbage_collector(struct work_struct *work)
{
	static LIST_HEAD(graveyard);
	static u8 gc_state;		/* Internal persistent state */
#define KEY_GC_REAP_AGAIN	0x01	/* - Need another cycle */
#define KEY_GC_REAPING_LINKS	0x02	/* - We need to reap links */
#define KEY_GC_SET_TIMER	0x04	/* - We need to restart the timer */
#define KEY_GC_REAPING_DEAD_1	0x10	/* - We need to mark dead keys */
#define KEY_GC_REAPING_DEAD_2	0x20	/* - We need to reap dead key links */
#define KEY_GC_REAPING_DEAD_3	0x40	/* - We need to reap dead keys */
#define KEY_GC_FOUND_DEAD_KEY	0x80	/* - We found at least one dead key */

	struct rb_node *cursor;
	struct key *key;
	time64_t new_timer, limit;

	kenter("[%lx,%x]", key_gc_flags, gc_state);

	limit = ktime_get_real_seconds();
	if (limit > key_gc_delay)
		limit -= key_gc_delay;
	else
		limit = key_gc_delay;

	/* Work out what we're going to be doing in this pass */
	gc_state &= KEY_GC_REAPING_DEAD_1 | KEY_GC_REAPING_DEAD_2;
	gc_state <<= 1;
	if (test_and_clear_bit(KEY_GC_KEY_EXPIRED, &key_gc_flags))
		gc_state |= KEY_GC_REAPING_LINKS | KEY_GC_SET_TIMER;

	if (test_and_clear_bit(KEY_GC_REAP_KEYTYPE, &key_gc_flags))
		gc_state |= KEY_GC_REAPING_DEAD_1;
	kdebug("new pass %x", gc_state);

	new_timer = TIME64_MAX;

	/* As only this function is permitted to remove things from the key
	 * serial tree, if cursor is non-NULL then it will always point to a
	 * valid node in the tree - even if lock got dropped.
	 */
	spin_lock(&key_serial_lock);
	cursor = rb_first(&key_serial_tree);

continue_scanning:
	while (cursor) {
		key = rb_entry(cursor, struct key, serial_node);
		cursor = rb_next(cursor);

		if (refcount_read(&key->usage) == 0)
			goto found_unreferenced_key;

		if (unlikely(gc_state & KEY_GC_REAPING_DEAD_1)) {
			if (key->type == key_gc_dead_keytype) {
				gc_state |= KEY_GC_FOUND_DEAD_KEY;
				set_bit(KEY_FLAG_DEAD, &key->flags);
				key->perm = 0;
				goto skip_dead_key;
			} else if (key->type == &key_type_keyring &&
				   key->restrict_link) {
				goto found_restricted_keyring;
			}
		}

		if (gc_state & KEY_GC_SET_TIMER) {
			if (key->expiry > limit && key->expiry < new_timer) {
				kdebug("will expire %x in %lld",
				       key_serial(key), key->expiry - limit);
				new_timer = key->expiry;
			}
		}

		if (unlikely(gc_state & KEY_GC_REAPING_DEAD_2))
			if (key->type == key_gc_dead_keytype)
				gc_state |= KEY_GC_FOUND_DEAD_KEY;

		if ((gc_state & KEY_GC_REAPING_LINKS) ||
		    unlikely(gc_state & KEY_GC_REAPING_DEAD_2)) {
			if (key->type == &key_type_keyring)
				goto found_keyring;
		}

		if (unlikely(gc_state & KEY_GC_REAPING_DEAD_3))
			if (key->type == key_gc_dead_keytype)
				goto destroy_dead_key;

	skip_dead_key:
		if (spin_is_contended(&key_serial_lock) || need_resched())
			goto contended;
	}

contended:
	spin_unlock(&key_serial_lock);

maybe_resched:
	if (cursor) {
		cond_resched();
		spin_lock(&key_serial_lock);
		goto continue_scanning;
	}

	/* We've completed the pass.  Set the timer if we need to and queue a
	 * new cycle if necessary.  We keep executing cycles until we find one
	 * where we didn't reap any keys.
	 */
	kdebug("pass complete");

	if (gc_state & KEY_GC_SET_TIMER && new_timer != (time64_t)TIME64_MAX) {
		new_timer += key_gc_delay;
		key_schedule_gc(new_timer);
	}

	if (unlikely(gc_state & KEY_GC_REAPING_DEAD_2) ||
	    !list_empty(&graveyard)) {
		/* Make sure that all pending keyring payload destructions are
		 * fulfilled and that people aren't now looking at dead or
		 * dying keys that they don't have a reference upon or a link
		 * to.
		 */
		kdebug("gc sync");
		synchronize_rcu();
	}

	if (!list_empty(&graveyard)) {
		kdebug("gc keys");
		key_gc_unused_keys(&graveyard);
	}

	if (unlikely(gc_state & (KEY_GC_REAPING_DEAD_1 |
				 KEY_GC_REAPING_DEAD_2))) {
		if (!(gc_state & KEY_GC_FOUND_DEAD_KEY)) {
			/* No remaining dead keys: short circuit the remaining
			 * keytype reap cycles.
			 */
			kdebug("dead short");
			gc_state &= ~(KEY_GC_REAPING_DEAD_1 | KEY_GC_REAPING_DEAD_2);
			gc_state |= KEY_GC_REAPING_DEAD_3;
		} else {
			gc_state |= KEY_GC_REAP_AGAIN;
		}
	}

	if (unlikely(gc_state & KEY_GC_REAPING_DEAD_3)) {
		kdebug("dead wake");
		smp_mb();
		clear_bit(KEY_GC_REAPING_KEYTYPE, &key_gc_flags);
		wake_up_bit(&key_gc_flags, KEY_GC_REAPING_KEYTYPE);
	}

	if (gc_state & KEY_GC_REAP_AGAIN)
		schedule_work(&key_gc_work);
	kleave(" [end %x]", gc_state);
	return;

	/* We found an unreferenced key - once we've removed it from the tree,
	 * we can safely drop the lock.
	 */
found_unreferenced_key:
	kdebug("unrefd key %d", key->serial);
	rb_erase(&key->serial_node, &key_serial_tree);
	spin_unlock(&key_serial_lock);

	list_add_tail(&key->graveyard_link, &graveyard);
	gc_state |= KEY_GC_REAP_AGAIN;
	goto maybe_resched;

	/* We found a restricted keyring and need to update the restriction if
	 * it is associated with the dead key type.
	 */
found_restricted_keyring:
	spin_unlock(&key_serial_lock);
	keyring_restriction_gc(key, key_gc_dead_keytype);
	goto maybe_resched;

	/* We found a keyring and we need to check the payload for links to
	 * dead or expired keys.  We don't flag another reap immediately as we
	 * have to wait for the old payload to be destroyed by RCU before we
	 * can reap the keys to which it refers.
	 */
found_keyring:
	spin_unlock(&key_serial_lock);
	keyring_gc(key, limit);
	goto maybe_resched;

	/* We found a dead key that is still referenced.  Reset its type and
	 * destroy its payload with its semaphore held.
	 */
destroy_dead_key:
	spin_unlock(&key_serial_lock);
	kdebug("destroy key %d", key->serial);
	down_write(&key->sem);
	key->type = &key_type_dead;
	if (key_gc_dead_keytype->destroy)
		key_gc_dead_keytype->destroy(key);
	memset(&key->payload, KEY_DESTROY, sizeof(key->payload));
	up_write(&key->sem);
	goto maybe_resched;
}
static void
W6692B_interrupt(struct IsdnCardState *cs, u_char bchan)
{
	u_char val;
	u_char r;
	struct BCState *bcs;
	struct sk_buff *skb;
	int count;

	bcs = (cs->bcs->channel == bchan) ? cs->bcs : (cs->bcs+1);
	val = cs->BC_Read_Reg(cs, bchan, W_B_EXIR);
	debugl1(cs, "W6692B chan %d B_EXIR 0x%02X", bchan, val);

	if (!test_bit(BC_FLG_INIT, &bcs->Flag)) {
		debugl1(cs, "W6692B not INIT yet");
		return;
	}
	if (val & W_B_EXI_RME) {	/* RME */
		r = cs->BC_Read_Reg(cs, bchan, W_B_STAR);
		if (r & (W_B_STAR_RDOV | W_B_STAR_CRCE | W_B_STAR_RMB)) {
			if (cs->debug & L1_DEB_WARN)
				debugl1(cs, "W6692 B STAR %x", r);
			if ((r & W_B_STAR_RDOV) && bcs->mode)
				if (cs->debug & L1_DEB_WARN)
					debugl1(cs, "W6692 B RDOV mode=%d",
						bcs->mode);
			if (r & W_B_STAR_CRCE)
				if (cs->debug & L1_DEB_WARN)
					debugl1(cs, "W6692 B CRC error");
			cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RRST | W_B_CMDR_RACT);
		} else {
			count = cs->BC_Read_Reg(cs, bchan, W_B_RBCL) & (W_B_FIFO_THRESH - 1);
			if (count == 0)
				count = W_B_FIFO_THRESH;
			W6692B_empty_fifo(bcs, count);
			if ((count = bcs->hw.w6692.rcvidx) > 0) {
				if (cs->debug & L1_DEB_HSCX_FIFO)
					debugl1(cs, "W6692 Bchan Frame %d", count);
				if (!(skb = dev_alloc_skb(count)))
					printk(KERN_WARNING "W6692: Bchan receive out of memory\n");
				else {
					memcpy(skb_put(skb, count), bcs->hw.w6692.rcvbuf, count);
					skb_queue_tail(&bcs->rqueue, skb);
				}
			}
		}
		bcs->hw.w6692.rcvidx = 0;
		schedule_event(bcs, B_RCVBUFREADY);
	}
	if (val & W_B_EXI_RMR) {	/* RMR */
		W6692B_empty_fifo(bcs, W_B_FIFO_THRESH);
		r = cs->BC_Read_Reg(cs, bchan, W_B_STAR);
		if (r & W_B_STAR_RDOV) {
			if (cs->debug & L1_DEB_WARN)
				debugl1(cs, "W6692 B RDOV(RMR) mode=%d",bcs->mode);
			cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RRST | W_B_CMDR_RACT);
			if (bcs->mode != L1_MODE_TRANS)
				bcs->hw.w6692.rcvidx = 0;
		}
		if (bcs->mode == L1_MODE_TRANS) {
			/* receive audio data */
			if (!(skb = dev_alloc_skb(W_B_FIFO_THRESH)))
				printk(KERN_WARNING "HiSax: receive out of memory\n");
			else {
				memcpy(skb_put(skb, W_B_FIFO_THRESH), bcs->hw.w6692.rcvbuf, W_B_FIFO_THRESH);
				skb_queue_tail(&bcs->rqueue, skb);
			}
			bcs->hw.w6692.rcvidx = 0;
			schedule_event(bcs, B_RCVBUFREADY);
		}
	}
	if (val & W_B_EXI_XDUN) {	/* XDUN */
		cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT);
		if (cs->debug & L1_DEB_WARN)
			debugl1(cs, "W6692 B EXIR %x Lost TX", val);
		if (bcs->mode == 1)
			W6692B_fill_fifo(bcs);
		else {
			/* Here we lost an TX interrupt, so
			   * restart transmitting the whole frame.
			 */
			if (bcs->tx_skb) {
				skb_push(bcs->tx_skb, bcs->hw.w6692.count);
				bcs->tx_cnt += bcs->hw.w6692.count;
				bcs->hw.w6692.count = 0;
			}
		}
		return;
	}
	if (val & W_B_EXI_XFR) {	/* XFR */
		r = cs->BC_Read_Reg(cs, bchan, W_B_STAR);
		if (r & W_B_STAR_XDOW) {
			if (cs->debug & L1_DEB_WARN)
				debugl1(cs, "W6692 B STAR %x XDOW", r);
			cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT);
			if (bcs->tx_skb && (bcs->mode != 1)) {
				skb_push(bcs->tx_skb, bcs->hw.w6692.count);
				bcs->tx_cnt += bcs->hw.w6692.count;
				bcs->hw.w6692.count = 0;
			}
		}
		if (bcs->tx_skb) {
			if (bcs->tx_skb->len) {
				W6692B_fill_fifo(bcs);
				return;
			} else {
				if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
					(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
					u_long	flags;
					spin_lock_irqsave(&bcs->aclock, flags);
					bcs->ackcnt += bcs->hw.w6692.count;
					spin_unlock_irqrestore(&bcs->aclock, flags);
					schedule_event(bcs, B_ACKPENDING);
				}
				dev_kfree_skb_irq(bcs->tx_skb);
				bcs->hw.w6692.count = 0;
				bcs->tx_skb = NULL;
			}
		}
		if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
			bcs->hw.w6692.count = 0;
			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
			W6692B_fill_fifo(bcs);
		} else {
			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
			schedule_event(bcs, B_XMTBUFREADY);
		}
	}
}
static void
W6692_l1hw(struct PStack *st, int pr, void *arg)
{
	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
	struct sk_buff *skb = arg;
	u_long flags;
	int val;

	switch (pr) {
		case (PH_DATA | REQUEST):
			if (cs->debug & DEB_DLOG_HEX)
				LogFrame(cs, skb->data, skb->len);
			if (cs->debug & DEB_DLOG_VERBOSE)
				dlogframe(cs, skb, 0);
			spin_lock_irqsave(&cs->lock, flags);
			if (cs->tx_skb) {
				skb_queue_tail(&cs->sq, skb);
#ifdef L2FRAME_DEBUG		/* psa */
				if (cs->debug & L1_DEB_LAPD)
					Logl2Frame(cs, skb, "PH_DATA Queued", 0);
#endif
			} else {
				cs->tx_skb = skb;
				cs->tx_cnt = 0;
#ifdef L2FRAME_DEBUG		/* psa */
				if (cs->debug & L1_DEB_LAPD)
					Logl2Frame(cs, skb, "PH_DATA", 0);
#endif
				W6692_fill_fifo(cs);
			}
			spin_unlock_irqrestore(&cs->lock, flags);
			break;
		case (PH_PULL | INDICATION):
			spin_lock_irqsave(&cs->lock, flags);
			if (cs->tx_skb) {
				if (cs->debug & L1_DEB_WARN)
					debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
				skb_queue_tail(&cs->sq, skb);
				spin_unlock_irqrestore(&cs->lock, flags);
				break;
			}
			if (cs->debug & DEB_DLOG_HEX)
				LogFrame(cs, skb->data, skb->len);
			if (cs->debug & DEB_DLOG_VERBOSE)
				dlogframe(cs, skb, 0);
			cs->tx_skb = skb;
			cs->tx_cnt = 0;
#ifdef L2FRAME_DEBUG		/* psa */
			if (cs->debug & L1_DEB_LAPD)
				Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
#endif
			W6692_fill_fifo(cs);
			spin_unlock_irqrestore(&cs->lock, flags);
			break;
		case (PH_PULL | REQUEST):
#ifdef L2FRAME_DEBUG		/* psa */
			if (cs->debug & L1_DEB_LAPD)
				debugl1(cs, "-> PH_REQUEST_PULL");
#endif
			if (!cs->tx_skb) {
				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
			} else
				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
			break;
		case (HW_RESET | REQUEST):
			spin_lock_irqsave(&cs->lock, flags);
			if ((cs->dc.w6692.ph_state == W_L1IND_DRD)) {
				ph_command(cs, W_L1CMD_ECK);
				spin_unlock_irqrestore(&cs->lock, flags);
			} else {
				ph_command(cs, W_L1CMD_RST);
				cs->dc.w6692.ph_state = W_L1CMD_RST;
				spin_unlock_irqrestore(&cs->lock, flags);
				W6692_new_ph(cs);
			}
			break;
		case (HW_ENABLE | REQUEST):
			spin_lock_irqsave(&cs->lock, flags);
			ph_command(cs, W_L1CMD_ECK);
			spin_unlock_irqrestore(&cs->lock, flags);
			break;
		case (HW_INFO3 | REQUEST):
			spin_lock_irqsave(&cs->lock, flags);
			ph_command(cs, W_L1CMD_AR8);
			spin_unlock_irqrestore(&cs->lock, flags);
			break;
		case (HW_TESTLOOP | REQUEST):
			val = 0;
			if (1 & (long) arg)
				val |= 0x0c;
			if (2 & (long) arg)
				val |= 0x3;
			/* !!! not implemented yet */
			break;
		case (HW_DEACTIVATE | RESPONSE):
			skb_queue_purge(&cs->rq);
			skb_queue_purge(&cs->sq);
			if (cs->tx_skb) {
				dev_kfree_skb_any(cs->tx_skb);
				cs->tx_skb = NULL;
			}
			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
				del_timer(&cs->dbusytimer);
			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
				schedule_event(cs, D_CLEARBUSY);
			break;
		default:
			if (cs->debug & L1_DEB_WARN)
				debugl1(cs, "W6692_l1hw unknown %04x", pr);
			break;
	}
}
int ivtv_start_capture(struct ivtv_open_id *id)
{
	struct ivtv *itv = id->itv;
	struct ivtv_stream *s = &itv->streams[id->type];
	struct ivtv_stream *s_vbi;

	if (s->type == IVTV_ENC_STREAM_TYPE_RAD ||
	    s->type == IVTV_DEC_STREAM_TYPE_MPG ||
	    s->type == IVTV_DEC_STREAM_TYPE_YUV ||
	    s->type == IVTV_DEC_STREAM_TYPE_VOUT) {
		/* you cannot read from these stream types. */
		return -EINVAL;
	}

	/* Try to claim this stream. */
	if (ivtv_claim_stream(id, s->type))
		return -EBUSY;

	/* This stream does not need to start capturing */
	if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
		set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
		return 0;
	}

	/* If capture is already in progress, then we also have to
	   do nothing extra. */
	if (test_bit(IVTV_F_S_STREAMOFF, &s->s_flags) || test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
		set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
		return 0;
	}

	/* Start VBI capture if required */
	s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
	if (s->type == IVTV_ENC_STREAM_TYPE_MPG &&
	    test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
	    !test_and_set_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) {
		/* Note: the IVTV_ENC_STREAM_TYPE_VBI is claimed
		   automatically when the MPG stream is claimed.
		   We only need to start the VBI capturing. */
		if (ivtv_start_v4l2_encode_stream(s_vbi)) {
			IVTV_DEBUG_WARN("VBI capture start failed\n");

			/* Failure, clean up and return an error */
			clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags);
			clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
			/* also releases the associated VBI stream */
			ivtv_release_stream(s);
			return -EIO;
		}
		IVTV_DEBUG_INFO("VBI insertion started\n");
	}

	/* Tell the card to start capturing */
	if (!ivtv_start_v4l2_encode_stream(s)) {
		/* We're done */
		set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
		/* Resume a possibly paused encoder */
		if (test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
			ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
		return 0;
	}

	/* failure, clean up */
	IVTV_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);

	/* Note: the IVTV_ENC_STREAM_TYPE_VBI is released
	   automatically when the MPG stream is released.
	   We only need to stop the VBI capturing. */
	if (s->type == IVTV_ENC_STREAM_TYPE_MPG &&
	    test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) {
		ivtv_stop_v4l2_encode_stream(s_vbi, 0);
		clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags);
	}
	clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
	ivtv_release_stream(s);
	return -EIO;
}
/*
 * hfs_mdb_commit()
 *
 * Description:
 *   This updates the MDB on disk (look also at hfs_write_super()).
 *   It does not check, if the superblock has been modified, or
 *   if the filesystem has been mounted read-only. It is mainly
 *   called by hfs_write_super() and hfs_btree_extend().
 * Input Variable(s):
 *   struct hfs_mdb *mdb: Pointer to the hfs MDB
 *   int backup;
 * Output Variable(s):
 *   NONE
 * Returns:
 *   void
 * Preconditions:
 *   'mdb' points to a "valid" (struct hfs_mdb).
 * Postconditions:
 *   The HFS MDB and on disk will be updated, by copying the possibly
 *   modified fields from the in memory MDB (in native byte order) to
 *   the disk block buffer.
 *   If 'backup' is non-zero then the alternate MDB is also written
 *   and the function doesn't return until it is actually on disk.
 */
void hfs_mdb_commit(struct super_block *sb)
{
	struct hfs_mdb *mdb = HFS_SB(sb)->mdb;

	if (test_and_clear_bit(HFS_FLG_MDB_DIRTY, &HFS_SB(sb)->flags)) {
		/* These parameters may have been modified, so write them back */
		mdb->drLsMod = hfs_mtime();
		mdb->drFreeBks = cpu_to_be16(HFS_SB(sb)->free_ablocks);
		mdb->drNxtCNID = cpu_to_be32(HFS_SB(sb)->next_id);
		mdb->drNmFls = cpu_to_be16(HFS_SB(sb)->root_files);
		mdb->drNmRtDirs = cpu_to_be16(HFS_SB(sb)->root_dirs);
		mdb->drFilCnt = cpu_to_be32(HFS_SB(sb)->file_count);
		mdb->drDirCnt = cpu_to_be32(HFS_SB(sb)->folder_count);

		/* write MDB to disk */
		mark_buffer_dirty(HFS_SB(sb)->mdb_bh);
	}

	/* write the backup MDB, not returning until it is written.
	 * we only do this when either the catalog or extents overflow
	 * files grow. */
	if (test_and_clear_bit(HFS_FLG_ALT_MDB_DIRTY, &HFS_SB(sb)->flags) &&
	    HFS_SB(sb)->alt_mdb) {
		hfs_inode_write_fork(HFS_SB(sb)->ext_tree->inode, mdb->drXTExtRec,
				     &mdb->drXTFlSize, NULL);
		hfs_inode_write_fork(HFS_SB(sb)->cat_tree->inode, mdb->drCTExtRec,
				     &mdb->drCTFlSize, NULL);
		memcpy(HFS_SB(sb)->alt_mdb, HFS_SB(sb)->mdb, HFS_SECTOR_SIZE);
		HFS_SB(sb)->alt_mdb->drAtrb |= cpu_to_be16(HFS_SB_ATTRIB_UNMNT);
		HFS_SB(sb)->alt_mdb->drAtrb &= cpu_to_be16(~HFS_SB_ATTRIB_INCNSTNT);
		mark_buffer_dirty(HFS_SB(sb)->alt_mdb_bh);
		hfs_buffer_sync(HFS_SB(sb)->alt_mdb_bh);
	}

	if (test_and_clear_bit(HFS_FLG_BITMAP_DIRTY, &HFS_SB(sb)->flags)) {
		struct buffer_head *bh;
		sector_t block;
		char *ptr;
		int off, size, len;

		block = be16_to_cpu(HFS_SB(sb)->mdb->drVBMSt) + HFS_SB(sb)->part_start;
		off = (block << HFS_SECTOR_SIZE_BITS) & (sb->s_blocksize - 1);
		block >>= sb->s_blocksize_bits - HFS_SECTOR_SIZE_BITS;
		size = (HFS_SB(sb)->fs_ablocks + 7) / 8;
		ptr = (u8 *)HFS_SB(sb)->bitmap;
		while (size) {
			bh = sb_bread(sb, block);
			if (!bh) {
				printk(KERN_ERR "hfs: unable to read volume bitmap\n");
				break;
			}
			len = min((int)sb->s_blocksize - off, size);
			memcpy(bh->b_data + off, ptr, len);
			mark_buffer_dirty(bh);
			brelse(bh);
			block++;
			off = 0;
			ptr += len;
			size -= len;
		}
	}
}
Exemple #10
0
static irqreturn_t flite_irq_handler(int irq, void *priv)
{
	struct fimc_lite *fimc = priv;
	struct flite_buffer *vbuf;
	unsigned long flags;
	struct timeval *tv;
	struct timespec ts;
	u32 intsrc;

	spin_lock_irqsave(&fimc->slock, flags);

	intsrc = flite_hw_get_interrupt_source(fimc);
	flite_hw_clear_pending_irq(fimc);

	if (test_and_clear_bit(ST_FLITE_OFF, &fimc->state)) {
		wake_up(&fimc->irq_queue);
		goto done;
	}

	if (intsrc & FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW) {
		clear_bit(ST_FLITE_RUN, &fimc->state);
		fimc->events.data_overflow++;
	}

	if (intsrc & FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND) {
		flite_hw_clear_last_capture_end(fimc);
		clear_bit(ST_FLITE_STREAM, &fimc->state);
		wake_up(&fimc->irq_queue);
	}

	if (fimc->out_path != FIMC_IO_DMA)
		goto done;

	if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART) &&
	    test_bit(ST_FLITE_RUN, &fimc->state) &&
	    !list_empty(&fimc->active_buf_q) &&
	    !list_empty(&fimc->pending_buf_q)) {
		vbuf = fimc_lite_active_queue_pop(fimc);
		ktime_get_ts(&ts);
		tv = &vbuf->vb.v4l2_buf.timestamp;
		tv->tv_sec = ts.tv_sec;
		tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
		vbuf->vb.v4l2_buf.sequence = fimc->frame_count++;
		vb2_buffer_done(&vbuf->vb, VB2_BUF_STATE_DONE);

		vbuf = fimc_lite_pending_queue_pop(fimc);
		flite_hw_set_output_addr(fimc, vbuf->paddr);
		fimc_lite_active_queue_add(fimc, vbuf);
	}

	if (test_bit(ST_FLITE_CONFIG, &fimc->state))
		fimc_lite_config_update(fimc);

	if (list_empty(&fimc->pending_buf_q)) {
		flite_hw_capture_stop(fimc);
		clear_bit(ST_FLITE_STREAM, &fimc->state);
	}
done:
	set_bit(ST_FLITE_RUN, &fimc->state);
	spin_unlock_irqrestore(&fimc->slock, flags);
	return IRQ_HANDLED;
}
Exemple #11
0
static int
check_arcofi(struct IsdnCardState *cs)
{
	int arcofi_present = 0;
	char tmp[40];
	char *t;
	u_char *p;

	if (!cs->dc.isac.mon_tx)
		if (!(cs->dc.isac.mon_tx=kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) {
			if (cs->debug & L1_DEB_WARN)
				debugl1(cs, "ISAC MON TX out of buffers!");
			return(0);
		}
	cs->dc.isac.arcofi_bc = 0;
	arcofi_fsm(cs, ARCOFI_START, &ARCOFI_VERSION);
	interruptible_sleep_on(&cs->dc.isac.arcofi_wait);
	if (!test_and_clear_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags)) {
			debugl1(cs, "Arcofi response received %d bytes", cs->dc.isac.mon_rxp);
			p = cs->dc.isac.mon_rx;
			t = tmp;
			t += sprintf(tmp, "Arcofi data");
			QuickHex(t, p, cs->dc.isac.mon_rxp);
			debugl1(cs, tmp);
			if ((cs->dc.isac.mon_rxp == 2) && (cs->dc.isac.mon_rx[0] == 0xa0)) {
				switch(cs->dc.isac.mon_rx[1]) {
					case 0x80:
						debugl1(cs, "Arcofi 2160 detected");
						arcofi_present = 1;
						break;
					case 0x82:
						debugl1(cs, "Arcofi 2165 detected");
						arcofi_present = 2;
						break;
					case 0x84:
						debugl1(cs, "Arcofi 2163 detected");
						arcofi_present = 3;
						break;
					default:
						debugl1(cs, "unknown Arcofi response");
						break;
				}
			} else
				debugl1(cs, "undefined Monitor response");
			cs->dc.isac.mon_rxp = 0;
	} else if (cs->dc.isac.mon_tx) {
		debugl1(cs, "Arcofi not detected");
	}
	if (arcofi_present) {
		if (cs->subtyp==ELSA_QS1000) {
			cs->subtyp = ELSA_QS3000;
			printk(KERN_INFO
				"Elsa: %s detected modem at 0x%lx\n",
				Elsa_Types[cs->subtyp],
				cs->hw.elsa.base+8);
			release_region(cs->hw.elsa.base, 8);
			if (check_region(cs->hw.elsa.base, 16)) {
				printk(KERN_WARNING
				"HiSax: %s config port %lx-%lx already in use\n",
				Elsa_Types[cs->subtyp],
				cs->hw.elsa.base + 8,
				cs->hw.elsa.base + 16);
			} else
				request_region(cs->hw.elsa.base, 16,
					"elsa isdn modem");
		} else if (cs->subtyp==ELSA_PCC16) {
			cs->subtyp = ELSA_PCF;
			printk(KERN_INFO
				"Elsa: %s detected modem at 0x%lx\n",
				Elsa_Types[cs->subtyp],
				cs->hw.elsa.base+8);
			release_region(cs->hw.elsa.base, 8);
			if (check_region(cs->hw.elsa.base, 16)) {
				printk(KERN_WARNING
				"HiSax: %s config port %lx-%lx already in use\n",
				Elsa_Types[cs->subtyp],
				cs->hw.elsa.base + 8,
				cs->hw.elsa.base + 16);
			} else
				request_region(cs->hw.elsa.base, 16,
					"elsa isdn modem");
		} else
			printk(KERN_INFO
				"Elsa: %s detected modem at 0x%lx\n",
				Elsa_Types[cs->subtyp],
				cs->hw.elsa.base+8);
		arcofi_fsm(cs, ARCOFI_START, &ARCOFI_XOP_0);
		interruptible_sleep_on(&cs->dc.isac.arcofi_wait);
		return(1);
	}
	return(0);
}
static inline int
bitmap_ipmac_do_del(const struct bitmap_ipmac_adt_elem *e,
		    struct bitmap_ipmac *map)
{
	return !test_and_clear_bit(e->id, map->members);
}
static void msg_cleanup(void)
{
	if (test_and_clear_bit(0, &msg_registered))
		usb_composite_unregister(&msg_driver);
}
static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
{
	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
	struct perf_event *event = pcpu->event;
	struct hw_perf_event *hwc = &event->hw;
	struct perf_sample_data data;
	struct perf_raw_record raw;
	struct pt_regs regs;
	struct perf_ibs_data ibs_data;
	int offset, size, check_rip, offset_max, throttle = 0;
	unsigned int msr;
	u64 *buf, *config, period;

	if (!test_bit(IBS_STARTED, pcpu->state)) {
		/*
		 * Catch spurious interrupts after stopping IBS: After
		 * disabling IBS there could be still incoming NMIs
		 * with samples that even have the valid bit cleared.
		 * Mark all this NMIs as handled.
		 */
		return test_and_clear_bit(IBS_STOPPING, pcpu->state) ? 1 : 0;
	}

	msr = hwc->config_base;
	buf = ibs_data.regs;
	rdmsrl(msr, *buf);
	if (!(*buf++ & perf_ibs->valid_mask))
		return 0;

	config = &ibs_data.regs[0];
	perf_ibs_event_update(perf_ibs, event, config);
	perf_sample_data_init(&data, 0, hwc->last_period);
	if (!perf_ibs_set_period(perf_ibs, hwc, &period))
		goto out;	/* no sw counter overflow */

	ibs_data.caps = ibs_caps;
	size = 1;
	offset = 1;
	check_rip = (perf_ibs == &perf_ibs_op && (ibs_caps & IBS_CAPS_RIPINVALIDCHK));
	if (event->attr.sample_type & PERF_SAMPLE_RAW)
		offset_max = perf_ibs->offset_max;
	else if (check_rip)
		offset_max = 2;
	else
		offset_max = 1;
	do {
		rdmsrl(msr + offset, *buf++);
		size++;
		offset = find_next_bit(perf_ibs->offset_mask,
				       perf_ibs->offset_max,
				       offset + 1);
	} while (offset < offset_max);
	ibs_data.size = sizeof(u64) * size;

	regs = *iregs;
	if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) {
		regs.flags &= ~PERF_EFLAGS_EXACT;
	} else {
		set_linear_ip(&regs, ibs_data.regs[1]);
		regs.flags |= PERF_EFLAGS_EXACT;
	}

	if (event->attr.sample_type & PERF_SAMPLE_RAW) {
		raw.size = sizeof(u32) + ibs_data.size;
		raw.data = ibs_data.data;
		data.raw = &raw;
	}

	throttle = perf_event_overflow(event, &data, &regs);
out:
	if (throttle)
		perf_ibs_disable_event(perf_ibs, hwc, *config);
	else
		perf_ibs_enable_event(perf_ibs, hwc, period >> 4);

	perf_event_update_userpage(event);

	return 1;
}
Exemple #15
0
static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
				struct iwl_rx_mem_buffer *rxb)
{
	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
	struct iwl_rxq *rxq = &trans_pcie->rxq;
	struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue];
	unsigned long flags;
	bool page_stolen = false;
	int max_len = PAGE_SIZE << trans_pcie->rx_page_order;
	u32 offset = 0;

	if (WARN_ON(!rxb))
		return;

	dma_unmap_page(trans->dev, rxb->page_dma, max_len, DMA_FROM_DEVICE);

	while (offset + sizeof(u32) + sizeof(struct iwl_cmd_header) < max_len) {
		struct iwl_rx_packet *pkt;
		struct iwl_device_cmd *cmd;
		u16 sequence;
		bool reclaim;
		int index, cmd_index, err, len;
		struct iwl_rx_cmd_buffer rxcb = {
			._offset = offset,
			._rx_page_order = trans_pcie->rx_page_order,
			._page = rxb->page,
			._page_stolen = false,
			.truesize = max_len,
		};

		pkt = rxb_addr(&rxcb);

		if (pkt->len_n_flags == cpu_to_le32(FH_RSCSR_FRAME_INVALID))
			break;

		IWL_DEBUG_RX(trans, "cmd at offset %d: %s (0x%.2x)\n",
			rxcb._offset, get_cmd_string(trans_pcie, pkt->hdr.cmd),
			pkt->hdr.cmd);

		len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
		len += sizeof(u32); /* account for status word */
		trace_iwlwifi_dev_rx(trans->dev, trans, pkt, len);
		trace_iwlwifi_dev_rx_data(trans->dev, trans, pkt, len);

		/* Reclaim a command buffer only if this packet is a response
		 *   to a (driver-originated) command.
		 * If the packet (e.g. Rx frame) originated from uCode,
		 *   there is no command buffer to reclaim.
		 * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
		 *   but apparently a few don't get set; catch them here. */
		reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME);
		if (reclaim) {
			int i;

			for (i = 0; i < trans_pcie->n_no_reclaim_cmds; i++) {
				if (trans_pcie->no_reclaim_cmds[i] ==
							pkt->hdr.cmd) {
					reclaim = false;
					break;
				}
			}
		}

		sequence = le16_to_cpu(pkt->hdr.sequence);
		index = SEQ_TO_INDEX(sequence);
		cmd_index = get_cmd_index(&txq->q, index);

		if (reclaim)
			cmd = txq->entries[cmd_index].cmd;
		else
			cmd = NULL;

		err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);

		if (reclaim) {
			kfree(txq->entries[cmd_index].free_buf);
			txq->entries[cmd_index].free_buf = NULL;
		}

		/*
		 * After here, we should always check rxcb._page_stolen,
		 * if it is true then one of the handlers took the page.
		 */

		if (reclaim) {
			/* Invoke any callbacks, transfer the buffer to caller,
			 * and fire off the (possibly) blocking
			 * iwl_trans_send_cmd()
			 * as we reclaim the driver command queue */
			if (!rxcb._page_stolen)
				iwl_pcie_hcmd_complete(trans, &rxcb, err);
			else
				IWL_WARN(trans, "Claim null rxb?\n");
		}

		page_stolen |= rxcb._page_stolen;
		offset += ALIGN(len, FH_RSCSR_FRAME_ALIGN);
	}

	/* page was stolen from us -- free our reference */
	if (page_stolen) {
		__free_pages(rxb->page, trans_pcie->rx_page_order);
		rxb->page = NULL;
	}

	/* Reuse the page if possible. For notification packets and
	 * SKBs that fail to Rx correctly, add them back into the
	 * rx_free list for reuse later. */
	spin_lock_irqsave(&rxq->lock, flags);
	if (rxb->page != NULL) {
		rxb->page_dma =
			dma_map_page(trans->dev, rxb->page, 0,
				     PAGE_SIZE << trans_pcie->rx_page_order,
				     DMA_FROM_DEVICE);
		if (dma_mapping_error(trans->dev, rxb->page_dma)) {
			/*
			 * free the page(s) as well to not break
			 * the invariant that the items on the used
			 * list have no page(s)
			 */
			__free_pages(rxb->page, trans_pcie->rx_page_order);
			rxb->page = NULL;
			list_add_tail(&rxb->list, &rxq->rx_used);
		} else {
			list_add_tail(&rxb->list, &rxq->rx_free);
			rxq->free_count++;
		}
	} else
		list_add_tail(&rxb->list, &rxq->rx_used);
	spin_unlock_irqrestore(&rxq->lock, flags);
}

/*
 * iwl_pcie_rx_handle - Main entry function for receiving responses from fw
 */
static void iwl_pcie_rx_handle(struct iwl_trans *trans)
{
	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
	struct iwl_rxq *rxq = &trans_pcie->rxq;
	u32 r, i;
	u8 fill_rx = 0;
	u32 count = 8;
	int total_empty;

	/* uCode's read index (stored in shared DRAM) indicates the last Rx
	 * buffer that the driver may process (last buffer filled by ucode). */
	r = le16_to_cpu(ACCESS_ONCE(rxq->rb_stts->closed_rb_num)) & 0x0FFF;
	i = rxq->read;

	/* Rx interrupt, but nothing sent from uCode */
	if (i == r)
		IWL_DEBUG_RX(trans, "HW = SW = %d\n", r);

	/* calculate total frames need to be restock after handling RX */
	total_empty = r - rxq->write_actual;
	if (total_empty < 0)
		total_empty += RX_QUEUE_SIZE;

	if (total_empty > (RX_QUEUE_SIZE / 2))
		fill_rx = 1;

	while (i != r) {
		struct iwl_rx_mem_buffer *rxb;

		rxb = rxq->queue[i];
		rxq->queue[i] = NULL;

		IWL_DEBUG_RX(trans, "rxbuf: HW = %d, SW = %d (%p)\n",
			     r, i, rxb);
		iwl_pcie_rx_handle_rb(trans, rxb);

		i = (i + 1) & RX_QUEUE_MASK;
		/* If there are a lot of unused frames,
		 * restock the Rx queue so ucode wont assert. */
		if (fill_rx) {
			count++;
			if (count >= 8) {
				rxq->read = i;
				iwl_pcie_rx_replenish_now(trans);
				count = 0;
			}
		}
	}

	/* Backtrack one entry */
	rxq->read = i;
	if (fill_rx)
		iwl_pcie_rx_replenish_now(trans);
	else
		iwl_pcie_rxq_restock(trans);
}

/*
 * iwl_pcie_irq_handle_error - called for HW or SW error interrupt from card
 */
static void iwl_pcie_irq_handle_error(struct iwl_trans *trans)
{
	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);

	/* W/A for WiFi/WiMAX coex and WiMAX own the RF */
	if (trans->cfg->internal_wimax_coex &&
	    (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) &
			     APMS_CLK_VAL_MRB_FUNC_MODE) ||
	     (iwl_read_prph(trans, APMG_PS_CTRL_REG) &
			    APMG_PS_CTRL_VAL_RESET_REQ))) {
		clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
		iwl_op_mode_wimax_active(trans->op_mode);
		wake_up(&trans_pcie->wait_command_queue);
		return;
	}

	iwl_pcie_dump_csr(trans);
	iwl_pcie_dump_fh(trans, NULL);

	set_bit(STATUS_FW_ERROR, &trans_pcie->status);
	clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
	wake_up(&trans_pcie->wait_command_queue);

	local_bh_disable();
	iwl_op_mode_nic_error(trans->op_mode);
	local_bh_enable();
}

irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
{
	struct iwl_trans *trans = dev_id;
	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
	struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
	u32 inta = 0;
	u32 handled = 0;
	unsigned long flags;
	u32 i;
#ifdef CONFIG_IWLWIFI_DEBUG
	u32 inta_mask;
#endif

	lock_map_acquire(&trans->sync_cmd_lockdep_map);

	spin_lock_irqsave(&trans_pcie->irq_lock, flags);

	/* Ack/clear/reset pending uCode interrupts.
	 * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
	 */
	/* There is a hardware bug in the interrupt mask function that some
	 * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if
	 * they are disabled in the CSR_INT_MASK register. Furthermore the
	 * ICT interrupt handling mechanism has another bug that might cause
	 * these unmasked interrupts fail to be detected. We workaround the
	 * hardware bugs here by ACKing all the possible interrupts so that
	 * interrupt coalescing can still be achieved.
	 */
	iwl_write32(trans, CSR_INT,
		    trans_pcie->inta | ~trans_pcie->inta_mask);

	inta = trans_pcie->inta;

#ifdef CONFIG_IWLWIFI_DEBUG
	if (iwl_have_debug_level(IWL_DL_ISR)) {
		/* just for debug */
		inta_mask = iwl_read32(trans, CSR_INT_MASK);
		IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n",
			      inta, inta_mask);
	}
#endif

	/* saved interrupt in inta variable now we can reset trans_pcie->inta */
	trans_pcie->inta = 0;

	spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);

	/* Now service all interrupt bits discovered above. */
	if (inta & CSR_INT_BIT_HW_ERR) {
		IWL_ERR(trans, "Hardware error detected.  Restarting.\n");

		/* Tell the device to stop sending interrupts */
		iwl_disable_interrupts(trans);

		isr_stats->hw++;
		iwl_pcie_irq_handle_error(trans);

		handled |= CSR_INT_BIT_HW_ERR;

		goto out;
	}

#ifdef CONFIG_IWLWIFI_DEBUG
	if (iwl_have_debug_level(IWL_DL_ISR)) {
		/* NIC fires this, but we don't use it, redundant with WAKEUP */
		if (inta & CSR_INT_BIT_SCD) {
			IWL_DEBUG_ISR(trans, "Scheduler finished to transmit "
				      "the frame/frames.\n");
			isr_stats->sch++;
		}

		/* Alive notification via Rx interrupt will do the real work */
		if (inta & CSR_INT_BIT_ALIVE) {
			IWL_DEBUG_ISR(trans, "Alive interrupt\n");
			isr_stats->alive++;
		}
	}
#endif
	/* Safely ignore these bits for debug checks below */
	inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);

	/* HW RF KILL switch toggled */
	if (inta & CSR_INT_BIT_RF_KILL) {
		bool hw_rfkill;

		hw_rfkill = iwl_is_rfkill_set(trans);
		IWL_WARN(trans, "RF_KILL bit toggled to %s.\n",
			 hw_rfkill ? "disable radio" : "enable radio");

		isr_stats->rfkill++;

		iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
		if (hw_rfkill) {
			set_bit(STATUS_RFKILL, &trans_pcie->status);
			if (test_and_clear_bit(STATUS_HCMD_ACTIVE,
					       &trans_pcie->status))
				IWL_DEBUG_RF_KILL(trans,
						  "Rfkill while SYNC HCMD in flight\n");
			wake_up(&trans_pcie->wait_command_queue);
		} else {
			clear_bit(STATUS_RFKILL, &trans_pcie->status);
		}

		handled |= CSR_INT_BIT_RF_KILL;
	}

	/* Chip got too hot and stopped itself */
	if (inta & CSR_INT_BIT_CT_KILL) {
		IWL_ERR(trans, "Microcode CT kill error detected.\n");
		isr_stats->ctkill++;
		handled |= CSR_INT_BIT_CT_KILL;
	}

	/* Error detected by uCode */
	if (inta & CSR_INT_BIT_SW_ERR) {
		IWL_ERR(trans, "Microcode SW error detected. "
			" Restarting 0x%X.\n", inta);
		isr_stats->sw++;
		iwl_pcie_irq_handle_error(trans);
		handled |= CSR_INT_BIT_SW_ERR;
	}

	/* uCode wakes up after power-down sleep */
	if (inta & CSR_INT_BIT_WAKEUP) {
		IWL_DEBUG_ISR(trans, "Wakeup interrupt\n");
		iwl_pcie_rxq_inc_wr_ptr(trans, &trans_pcie->rxq);
		for (i = 0; i < trans->cfg->base_params->num_of_queues; i++)
			iwl_pcie_txq_inc_wr_ptr(trans, &trans_pcie->txq[i]);

		isr_stats->wakeup++;
static void abort_usb_playback(struct ua101 *ua)
{
	if (test_and_clear_bit(USB_PLAYBACK_RUNNING, &ua->states))
		wake_up(&ua->alsa_playback_wait);
}
Exemple #17
0
/*
 * Check whether the dentry is still valid
 *
 * If the entry validity timeout has expired and the dentry is
 * positive, try to redo the lookup.  If the lookup results in a
 * different inode, then let the VFS invalidate the dentry and redo
 * the lookup once more.  If the lookup results in the same inode,
 * then refresh the attributes, timeouts and mark the dentry valid.
 */
static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
{
	struct inode *inode;
	struct dentry *parent;
	struct fuse_conn *fc;
	struct fuse_inode *fi;
	int ret;

	inode = ACCESS_ONCE(entry->d_inode);
	if (inode && is_bad_inode(inode))
		goto invalid;
	else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
		 (flags & LOOKUP_REVAL)) {
		struct fuse_entry_out outarg;
		FUSE_ARGS(args);
		struct fuse_forget_link *forget;
		u64 attr_version;

		/* For negative dentries, always do a fresh lookup */
		if (!inode)
			goto invalid;

		ret = -ECHILD;
		if (flags & LOOKUP_RCU)
			goto out;

		fc = get_fuse_conn(inode);

		forget = fuse_alloc_forget();
		ret = -ENOMEM;
		if (!forget)
			goto out;

		attr_version = fuse_get_attr_version(fc);

		parent = dget_parent(entry);
		fuse_lookup_init(fc, &args, get_node_id(parent->d_inode),
				 &entry->d_name, &outarg);
		ret = fuse_simple_request(fc, &args);
		dput(parent);
		/* Zero nodeid is same as -ENOENT */
		if (!ret && !outarg.nodeid)
			ret = -ENOENT;
		if (!ret) {
			fi = get_fuse_inode(inode);
			if (outarg.nodeid != get_node_id(inode)) {
				fuse_queue_forget(fc, forget, outarg.nodeid, 1);
				goto invalid;
			}
			spin_lock(&fc->lock);
			fi->nlookup++;
			spin_unlock(&fc->lock);
		}
		kfree(forget);
		if (ret == -ENOMEM)
			goto out;
		if (ret || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
			goto invalid;

		fuse_change_attributes(inode, &outarg.attr,
				       entry_attr_timeout(&outarg),
				       attr_version);
		fuse_change_entry_timeout(entry, &outarg);
	} else if (inode) {
		fi = get_fuse_inode(inode);
		if (flags & LOOKUP_RCU) {
			if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state))
				return -ECHILD;
		} else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) {
			parent = dget_parent(entry);
			fuse_advise_use_readdirplus(parent->d_inode);
			dput(parent);
		}
	}
	ret = 1;
out:
	return ret;

invalid:
	ret = 0;
	goto out;
}
Exemple #18
0
static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
{
	int ret;
	u32 vector;
	bool beacon_loss = false;
	bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS);
	bool disconnect_sta = false;
	unsigned long sta_bitmap = 0;

	wl1271_event_mbox_dump(mbox);

	vector = le32_to_cpu(mbox->events_vector);
	vector &= ~(le32_to_cpu(mbox->events_mask));
	wl1271_debug(DEBUG_EVENT, "vector: 0x%x", vector);

	if (vector & SCAN_COMPLETE_EVENT_ID) {
		wl1271_debug(DEBUG_EVENT, "status: 0x%x",
			     mbox->scheduled_scan_status);

		wl1271_scan_stm(wl);
	}

	if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) {
		wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_REPORT_EVENT "
			     "(status 0x%0x)", mbox->scheduled_scan_status);

		wl1271_scan_sched_scan_results(wl);
	}

	if (vector & PERIODIC_SCAN_COMPLETE_EVENT_ID) {
		wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT "
			     "(status 0x%0x)", mbox->scheduled_scan_status);
		if (wl->sched_scanning) {
			ieee80211_sched_scan_stopped(wl->hw);
			wl->sched_scanning = false;
		}
	}

	if (vector & SOFT_GEMINI_SENSE_EVENT_ID &&
	    wl->bss_type == BSS_TYPE_STA_BSS)
		wl12xx_event_soft_gemini_sense(wl,
					       mbox->soft_gemini_sense_info);

	if (vector & CHANGE_AUTO_MODE_TIMEOUT_EVENT_ID &&
	    wl->bss_type == BSS_TYPE_STA_BSS) {
		int timeout = 0;
		if (mbox->change_auto_mode_timeout)
			timeout = 500;
		ieee80211_set_dyn_ps_timeout(wl->vif, timeout);
	}
	
	/*
	 * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon
	 * filtering) is enabled. Without PSM, the stack will receive all
	 * beacons and can detect beacon loss by itself.
	 *
	 * As there's possibility that the driver disables PSM before receiving
	 * BSS_LOSE_EVENT, beacon loss has to be reported to the stack.
	 *
	 */
	if ((vector & BSS_LOSE_EVENT_ID) && !is_ap) {
		wl1271_info("Beacon loss detected.");

		/* indicate to the stack, that beacons have been lost */
		beacon_loss = true;
	}

	if ((vector & PS_REPORT_EVENT_ID) && !is_ap) {
		wl1271_debug(DEBUG_EVENT, "PS_REPORT_EVENT");
		ret = wl1271_event_ps_report(wl, mbox, &beacon_loss);
		if (ret < 0)
			return ret;
	}

	if ((vector & PSPOLL_DELIVERY_FAILURE_EVENT_ID) && !is_ap)
		wl1271_event_pspoll_delivery_fail(wl);

	if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) {
		wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT");
		if (wl->vif)
			wl1271_event_rssi_trigger(wl, mbox);
	}

	if ((vector & BA_SESSION_RX_CONSTRAINT_EVENT_ID)) {
		wl1271_debug(DEBUG_EVENT, "BA_SESSION_RX_CONSTRAINT_EVENT_ID. "
			     "ba_allowed = 0x%x", mbox->rx_ba_allowed);

		wl->ba_allowed = !!mbox->rx_ba_allowed;

		if (wl->vif && !wl->ba_allowed)
			wl1271_stop_ba_event(wl);
	}

	if ((vector & CHANNEL_SWITCH_COMPLETE_EVENT_ID) && !is_ap) {
		wl1271_debug(DEBUG_EVENT, "CHANNEL_SWITCH_COMPLETE_EVENT_ID. "
					  "channel_switch_status = 0x%x",
					  mbox->channel_switch_status);
		/*
		 * That event uses for two cases:
		 * 1) channel switch complete with channel_switch_status=0
		 * 2) fixing beacon actual TSF with channel_switch_status=1
		 * calling chswitch_done only for the first option
		 */
		if (!mbox->channel_switch_status &&
		    test_and_clear_bit(WL1271_FLAG_CS_PROGRESS, &wl->flags) &&
		    (wl->vif))
			ieee80211_chswitch_done(wl->vif, true);
	}

	if ((vector & DUMMY_PACKET_EVENT_ID)) {
		wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID");
		if (wl->vif)
			wl1271_tx_dummy_packet(wl);
	}

	if (vector & DISCONNECT_EVENT_COMPLETE_ID)
		wl1271_debug(DEBUG_EVENT, "disconnect event");

	/*
	 * "TX retries exceeded" has a different meaning according to mode.
	 * In AP mode the offending station is disconnected.
	 */
	if ((vector & MAX_TX_RETRY_EVENT_ID) && is_ap) {
		wl1271_debug(DEBUG_EVENT, "MAX_TX_RETRY_EVENT_ID");
		sta_bitmap |= le16_to_cpu(mbox->sta_tx_retry_exceeded);
		disconnect_sta = true;
	}

	if ((vector & INACTIVE_STA_EVENT_ID) && is_ap) {
		wl1271_debug(DEBUG_EVENT, "INACTIVE_STA_EVENT_ID");
		sta_bitmap |= le16_to_cpu(mbox->sta_aging_status);
		disconnect_sta = true;
	}

	if (is_ap && disconnect_sta) {
		u32 num_packets = wl->conf.tx.max_tx_retries;
		struct ieee80211_sta *sta;
		const u8 *addr;
		int h;

		for (h = find_first_bit(&sta_bitmap, AP_MAX_LINKS);
		     h < AP_MAX_LINKS;
		     h = find_next_bit(&sta_bitmap, AP_MAX_LINKS, h+1)) {
			if (!wl1271_is_active_sta(wl, h))
				continue;

			addr = wl->links[h].addr;

			rcu_read_lock();
			sta = ieee80211_find_sta(wl->vif, addr);
			if (sta) {
				wl1271_debug(DEBUG_EVENT, "remove sta %d", h);
				ieee80211_report_low_ack(sta, num_packets);
			}
			rcu_read_unlock();
		}
	}

	if (wl->vif && beacon_loss)
		ieee80211_connection_loss(wl->vif);

	return 0;
}
static irqreturn_t
W6692_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
	struct IsdnCardState	*cs = dev_id;
	u_char			val, exval, v1;
	struct sk_buff		*skb;
	u_int			count;
	u_long			flags;
	int			icnt = 5;

	spin_lock_irqsave(&cs->lock, flags);
	val = cs->readW6692(cs, W_ISTA);
	if (!val) {
		spin_unlock_irqrestore(&cs->lock, flags);
		return IRQ_NONE;
	}
      StartW6692:
	if (cs->debug & L1_DEB_ISAC)
		debugl1(cs, "W6692 ISTA %x", val);

	if (val & W_INT_D_RME) {	/* RME */
		exval = cs->readW6692(cs, W_D_RSTA);
		if (exval & (W_D_RSTA_RDOV | W_D_RSTA_CRCE | W_D_RSTA_RMB)) {
			if (exval & W_D_RSTA_RDOV)
				if (cs->debug & L1_DEB_WARN)
					debugl1(cs, "W6692 RDOV");
			if (exval & W_D_RSTA_CRCE)
				if (cs->debug & L1_DEB_WARN)
					debugl1(cs, "W6692 D-channel CRC error");
			if (exval & W_D_RSTA_RMB)
				if (cs->debug & L1_DEB_WARN)
					debugl1(cs, "W6692 D-channel ABORT");
			cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST);
		} else {
			count = cs->readW6692(cs, W_D_RBCL) & (W_D_FIFO_THRESH - 1);
			if (count == 0)
				count = W_D_FIFO_THRESH;
			W6692_empty_fifo(cs, count);
			if ((count = cs->rcvidx) > 0) {
				cs->rcvidx = 0;
				if (!(skb = alloc_skb(count, GFP_ATOMIC)))
					printk(KERN_WARNING "HiSax: D receive out of memory\n");
				else {
					memcpy(skb_put(skb, count), cs->rcvbuf, count);
					skb_queue_tail(&cs->rq, skb);
				}
			}
		}
		cs->rcvidx = 0;
		schedule_event(cs, D_RCVBUFREADY);
	}
	if (val & W_INT_D_RMR) {	/* RMR */
		W6692_empty_fifo(cs, W_D_FIFO_THRESH);
	}
	if (val & W_INT_D_XFR) {	/* XFR */
		if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
			del_timer(&cs->dbusytimer);
		if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
			schedule_event(cs, D_CLEARBUSY);
		if (cs->tx_skb) {
			if (cs->tx_skb->len) {
				W6692_fill_fifo(cs);
				goto afterXFR;
			} else {
				dev_kfree_skb_irq(cs->tx_skb);
				cs->tx_cnt = 0;
				cs->tx_skb = NULL;
			}
		}
		if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
			cs->tx_cnt = 0;
			W6692_fill_fifo(cs);
		} else
			schedule_event(cs, D_XMTBUFREADY);
	}
      afterXFR:
	if (val & (W_INT_XINT0 | W_INT_XINT1)) {	/* XINT0/1 - never */
		if (cs->debug & L1_DEB_ISAC)
			debugl1(cs, "W6692 spurious XINT!");
	}
	if (val & W_INT_D_EXI) {	/* EXI */
		exval = cs->readW6692(cs, W_D_EXIR);
		if (cs->debug & L1_DEB_WARN)
			debugl1(cs, "W6692 D_EXIR %02x", exval);
		if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) {	/* Transmit underrun/collision */
			debugl1(cs, "W6692 D-chan underrun/collision");
			printk(KERN_WARNING "HiSax: W6692 XDUN/XCOL\n");
			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
				del_timer(&cs->dbusytimer);
			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
				schedule_event(cs, D_CLEARBUSY);
			if (cs->tx_skb) {	/* Restart frame */
				skb_push(cs->tx_skb, cs->tx_cnt);
				cs->tx_cnt = 0;
				W6692_fill_fifo(cs);
			} else {
				printk(KERN_WARNING "HiSax: W6692 XDUN/XCOL no skb\n");
				debugl1(cs, "W6692 XDUN/XCOL no skb");
				cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_XRST);
			}
		}
		if (exval & W_D_EXI_RDOV) {	/* RDOV */
			debugl1(cs, "W6692 D-channel RDOV");
			printk(KERN_WARNING "HiSax: W6692 D-RDOV\n");
			cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RRST);
		}
		if (exval & W_D_EXI_TIN2) {	/* TIN2 - never */
			debugl1(cs, "W6692 spurious TIN2 interrupt");
		}
		if (exval & W_D_EXI_MOC) {	/* MOC - not supported */
			debugl1(cs, "W6692 spurious MOC interrupt");
			v1 = cs->readW6692(cs, W_MOSR);
			debugl1(cs, "W6692 MOSR %02x", v1);
		}
		if (exval & W_D_EXI_ISC) {	/* ISC - Level1 change */
			v1 = cs->readW6692(cs, W_CIR);
			if (cs->debug & L1_DEB_ISAC)
				debugl1(cs, "W6692 ISC CIR=0x%02X", v1);
			if (v1 & W_CIR_ICC) {
				cs->dc.w6692.ph_state = v1 & W_CIR_COD_MASK;
				if (cs->debug & L1_DEB_ISAC)
					debugl1(cs, "ph_state_change %x", cs->dc.w6692.ph_state);
				schedule_event(cs, D_L1STATECHANGE);
			}
			if (v1 & W_CIR_SCC) {
				v1 = cs->readW6692(cs, W_SQR);
				debugl1(cs, "W6692 SCC SQR=0x%02X", v1);
			}
		}
		if (exval & W_D_EXI_WEXP) {
			debugl1(cs, "W6692 spurious WEXP interrupt!");
		}
		if (exval & W_D_EXI_TEXP) {
			debugl1(cs, "W6692 spurious TEXP interrupt!");
		}
	}
	if (val & W_INT_B1_EXI) {
		debugl1(cs, "W6692 B channel 1 interrupt");
		W6692B_interrupt(cs, 0);
	}
	if (val & W_INT_B2_EXI) {
		debugl1(cs, "W6692 B channel 2 interrupt");
		W6692B_interrupt(cs, 1);
	}
	val = cs->readW6692(cs, W_ISTA);
	if (val && icnt) {
		icnt--;
		goto StartW6692;
	}
	if (!icnt) {
		printk(KERN_WARNING "W6692 IRQ LOOP\n");
		cs->writeW6692(cs, W_IMASK, 0xff);
	}
	spin_unlock_irqrestore(&cs->lock, flags);
	return IRQ_HANDLED;
}
Exemple #20
0
int __init
setup_netjet_u(struct IsdnCard *card)
{
    int bytecnt;
    struct IsdnCardState *cs = card->cs;
    char tmp[64];
    long flags;
#if CONFIG_PCI
#endif
#ifdef __BIG_ENDIAN
#error "not running on big endian machines now"
#endif
    strcpy(tmp, NETjet_U_revision);
    printk(KERN_INFO "HiSax: Traverse Tech. NETspider-U driver Rev. %s\n", HiSax_getrev(tmp));
    if (cs->typ != ISDN_CTYPE_NETJET_U)
        return(0);
    test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);

#if CONFIG_PCI

    for ( ;; )
    {
        if (!pci_present()) {
            printk(KERN_ERR "Netjet: no PCI bus present\n");
            return(0);
        }
        if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET,
                                          PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
            if (pci_enable_device(dev_netjet))
                return(0);
            pci_set_master(dev_netjet);
            cs->irq = dev_netjet->irq;
            if (!cs->irq) {
                printk(KERN_WARNING "NETspider-U: No IRQ for PCI card found\n");
                return(0);
            }
            cs->hw.njet.base = pci_resource_start(dev_netjet, 0);
            if (!cs->hw.njet.base) {
                printk(KERN_WARNING "NETspider-U: No IO-Adr for PCI card found\n");
                return(0);
            }
        } else {
            printk(KERN_WARNING "NETspider-U: No PCI card found\n");
            return(0);
        }

        cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA;
        cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF;

        save_flags(flags);
        sti();

        cs->hw.njet.ctrl_reg = 0xff;  /* Reset On */
        byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);

        set_current_state(TASK_UNINTERRUPTIBLE);
        schedule_timeout((10*HZ)/1000);	/* Timeout 10ms */

        cs->hw.njet.ctrl_reg = 0x00;  /* Reset Off and status read clear */
        byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);

        set_current_state(TASK_UNINTERRUPTIBLE);
        schedule_timeout((10*HZ)/1000);	/* Timeout 10ms */

        restore_flags(flags);

        cs->hw.njet.auxd = 0xC0;
        cs->hw.njet.dmactrl = 0;

        byteout(cs->hw.njet.auxa, 0);
        byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ);
        byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ);
        byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);

        switch ( ( ( NETjet_ReadIC( cs, ICC_RBCH ) >> 5 ) & 3 ) )
        {
        case 3 :
            break;

        case 0 :
            printk( KERN_WARNING "NETspider-U: NETjet-S PCI card found\n" );
            continue;

        default :
            printk( KERN_WARNING "NETspider-U: No PCI card found\n" );
            return 0;
        }
        break;
    }
#else

    printk(KERN_WARNING "NETspider-U: NO_PCI_BIOS\n");
    printk(KERN_WARNING "NETspider-U: unable to config NETspider-U PCI\n");
    return (0);

#endif /* CONFIG_PCI */

    bytecnt = 256;

    printk(KERN_INFO
           "NETspider-U: PCI card configured at %#lx IRQ %d\n",
           cs->hw.njet.base, cs->irq);
    if (check_region(cs->hw.njet.base, bytecnt)) {
        printk(KERN_WARNING
               "HiSax: %s config port %#lx-%#lx already in use\n",
               CardType[card->typ],
               cs->hw.njet.base,
               cs->hw.njet.base + bytecnt);
        return (0);
    } else {
        request_region(cs->hw.njet.base, bytecnt, "netspider-u isdn");
    }
    reset_netjet_u(cs);
    cs->readisac  = &NETjet_ReadIC;
    cs->writeisac = &NETjet_WriteIC;
    cs->readisacfifo  = &NETjet_ReadICfifo;
    cs->writeisacfifo = &NETjet_WriteICfifo;
    cs->BC_Read_Reg  = &dummyrr;
    cs->BC_Write_Reg = &dummywr;
    cs->BC_Send_Data = &netjet_fill_dma;
    cs->cardmsg = &NETjet_U_card_msg;
    cs->irq_func = &netjet_u_interrupt;
    cs->irq_flags |= SA_SHIRQ;
    ICCVersion(cs, "NETspider-U:");
    return (1);
}
Exemple #21
0
void
icc_interrupt(struct IsdnCardState *cs, u_char val)
{
	u_char exval, v1;
	struct sk_buff *skb;
	unsigned int count;

	if (cs->debug & L1_DEB_ISAC)
		debugl1(cs, "ICC interrupt %x", val);
	if (val & 0x80) {	/* RME */
		exval = cs->readisac(cs, ICC_RSTA);
		if ((exval & 0x70) != 0x20) {
			if (exval & 0x40) {
				if (cs->debug & L1_DEB_WARN)
					debugl1(cs, "ICC RDO");
#ifdef ERROR_STATISTIC
				cs->err_rx++;
#endif
			}
			if (!(exval & 0x20)) {
				if (cs->debug & L1_DEB_WARN)
					debugl1(cs, "ICC CRC error");
#ifdef ERROR_STATISTIC
				cs->err_crc++;
#endif
			}
			cs->writeisac(cs, ICC_CMDR, 0x80);
		} else {
			count = cs->readisac(cs, ICC_RBCL) & 0x1f;
			if (count == 0)
				count = 32;
			icc_empty_fifo(cs, count);
			if ((count = cs->rcvidx) > 0) {
				cs->rcvidx = 0;
				if (!(skb = alloc_skb(count, GFP_ATOMIC)))
					printk(KERN_WARNING "HiSax: D receive out of memory\n");
				else {
					memcpy(skb_put(skb, count), cs->rcvbuf, count);
					skb_queue_tail(&cs->rq, skb);
				}
			}
		}
		cs->rcvidx = 0;
		schedule_event(cs, D_RCVBUFREADY);
	}
	if (val & 0x40) {	/* RPF */
		icc_empty_fifo(cs, 32);
	}
	if (val & 0x20) {	/* RSC */
		/* never */
		if (cs->debug & L1_DEB_WARN)
			debugl1(cs, "ICC RSC interrupt");
	}
	if (val & 0x10) {	/* XPR */
		if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
			del_timer(&cs->dbusytimer);
		if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
			schedule_event(cs, D_CLEARBUSY);
		if (cs->tx_skb) {
			if (cs->tx_skb->len) {
				icc_fill_fifo(cs);
				goto afterXPR;
			} else {
				dev_kfree_skb_irq(cs->tx_skb);
				cs->tx_cnt = 0;
				cs->tx_skb = NULL;
			}
		}
		if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
			cs->tx_cnt = 0;
			icc_fill_fifo(cs);
		} else
			schedule_event(cs, D_XMTBUFREADY);
	}
      afterXPR:
	if (val & 0x04) {	/* CISQ */
		exval = cs->readisac(cs, ICC_CIR0);
		if (cs->debug & L1_DEB_ISAC)
			debugl1(cs, "ICC CIR0 %02X", exval );
		if (exval & 2) {
			cs->dc.icc.ph_state = (exval >> 2) & 0xf;
			if (cs->debug & L1_DEB_ISAC)
				debugl1(cs, "ph_state change %x", cs->dc.icc.ph_state);
			schedule_event(cs, D_L1STATECHANGE);
		}
Exemple #22
0
static void
netjet_u_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
    struct IsdnCardState *cs = dev_id;
    u_char val, sval;
    long flags;

    if (!cs) {
        printk(KERN_WARNING "NETspider-U: Spurious interrupt!\n");
        return;
    }
    if (!((sval = bytein(cs->hw.njet.base + NETJET_IRQSTAT1)) &
            NETJET_ISACIRQ)) {
        val = NETjet_ReadIC(cs, ICC_ISTA);
        if (cs->debug & L1_DEB_ISAC)
            debugl1(cs, "tiger: i1 %x %x", sval, val);
        if (val) {
            icc_interrupt(cs, val);
            NETjet_WriteIC(cs, ICC_MASK, 0xFF);
            NETjet_WriteIC(cs, ICC_MASK, 0x0);
        }
    }
    save_flags(flags);
    cli();
    /* start new code 13/07/00 GE */
    /* set bits in sval to indicate which page is free */
    if (inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR) <
            inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ))
        /* the 2nd write page is free */
        sval = 0x08;
    else	/* the 1st write page is free */
        sval = 0x04;
    if (inl(cs->hw.njet.base + NETJET_DMA_READ_ADR) <
            inl(cs->hw.njet.base + NETJET_DMA_READ_IRQ))
        /* the 2nd read page is free */
        sval = sval | 0x02;
    else	/* the 1st read page is free */
        sval = sval | 0x01;
    if (sval != cs->hw.njet.last_is0) /* we have a DMA interrupt */
    {
        if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
            restore_flags(flags);
            return;
        }
        cs->hw.njet.irqstat0 = sval;
        restore_flags(flags);
        if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) !=
                (cs->hw.njet.last_is0 & NETJET_IRQM0_READ))
            /* we have a read dma int */
            read_tiger(cs);
        if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE) !=
                (cs->hw.njet.last_is0 & NETJET_IRQM0_WRITE))
            /* we have a write dma int */
            write_tiger(cs);
        /* end new code 13/07/00 GE */
        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
    } else
        restore_flags(flags);

    /*	if (!testcnt--) {
    		cs->hw.njet.dmactrl = 0;
    		byteout(cs->hw.njet.base + NETJET_DMACTRL,
    			cs->hw.njet.dmactrl);
    		byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
    	}
    */
}
Exemple #23
0
/*
 * Callback for completed capture URB.
 */
static void audio_in_callback(struct urb *urb)
{
	int i, index, length = 0, shutdown = 0;
	unsigned long flags;

	struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;

	line6pcm->last_frame_in = urb->start_frame;

	/* find index of URB */
	for (index = 0; index < LINE6_ISO_BUFFERS; ++index)
		if (urb == line6pcm->urb_audio_in[index])
			break;

#ifdef CONFIG_LINE6_USB_DUMP_PCM
	for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
		struct usb_iso_packet_descriptor *fout =
		    &urb->iso_frame_desc[i];
		line6_write_hexdump(line6pcm->line6, 'C',
				    urb->transfer_buffer + fout->offset,
				    fout->length);
	}
#endif

	spin_lock_irqsave(&line6pcm->lock_audio_in, flags);

	for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
		char *fbuf;
		int fsize;
		struct usb_iso_packet_descriptor *fin = &urb->iso_frame_desc[i];

		if (fin->status == -EXDEV) {
			shutdown = 1;
			break;
		}

		fbuf = urb->transfer_buffer + fin->offset;
		fsize = fin->actual_length;

		if (fsize > line6pcm->max_packet_size) {
			dev_err(line6pcm->line6->ifcdev,
				"driver and/or device bug: packet too large (%d > %d)\n",
				fsize, line6pcm->max_packet_size);
		}

		length += fsize;

		/* the following assumes LINE6_ISO_PACKETS == 1: */
		line6pcm->prev_fbuf = fbuf;
		line6pcm->prev_fsize = fsize;

#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
		if (!(line6pcm->flags & MASK_PCM_IMPULSE))
#endif
			if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags)
			    && (fsize > 0))
				line6_capture_copy(line6pcm, fbuf, fsize);
	}

	clear_bit(index, &line6pcm->active_urb_in);

	if (test_and_clear_bit(index, &line6pcm->unlink_urb_in))
		shutdown = 1;

	spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);

	if (!shutdown) {
		submit_audio_in_urb(line6pcm);

#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
		if (!(line6pcm->flags & MASK_PCM_IMPULSE))
#endif
			if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags))
				line6_capture_check_period(line6pcm, length);
	}
}
Exemple #24
0
void
clear_arcofi(struct IsdnCardState *cs) {
	if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) {
		del_timer(&cs->dc.isac.arcofitimer);
	}
}
Exemple #25
0
static ssize_t read_chan(struct tty_struct *tty, struct file *file,
			 unsigned char __user *buf, size_t nr)
{
	unsigned char __user *b = buf;
	DECLARE_WAITQUEUE(wait, current);
	int c;
	int minimum, time;
	ssize_t retval = 0;
	ssize_t size;
	long timeout;
	unsigned long flags;

do_it_again:

	if (!tty->read_buf) {
		printk("n_tty_read_chan: called with read_buf == NULL?!?\n");
		return -EIO;
	}

	c = job_control(tty, file);
	if(c < 0)
		return c;
	
	minimum = time = 0;
	timeout = MAX_SCHEDULE_TIMEOUT;
	if (!tty->icanon) {
		time = (HZ / 10) * TIME_CHAR(tty);
		minimum = MIN_CHAR(tty);
		if (minimum) {
			if (time)
				tty->minimum_to_wake = 1;
			else if (!waitqueue_active(&tty->read_wait) ||
				 (tty->minimum_to_wake > minimum))
				tty->minimum_to_wake = minimum;
		} else {
			timeout = 0;
			if (time) {
				timeout = time;
				time = 0;
			}
			tty->minimum_to_wake = minimum = 1;
		}
	}

	/*
	 *	Internal serialization of reads.
	 */
	if (file->f_flags & O_NONBLOCK) {
		if (down_trylock(&tty->atomic_read))
			return -EAGAIN;
	}
	else {
		if (down_interruptible(&tty->atomic_read))
			return -ERESTARTSYS;
	}

	add_wait_queue(&tty->read_wait, &wait);
	set_bit(TTY_DONT_FLIP, &tty->flags);
	while (nr) {
		/* First test for status change. */
		if (tty->packet && tty->link->ctrl_status) {
			unsigned char cs;
			if (b != buf)
				break;
			cs = tty->link->ctrl_status;
			tty->link->ctrl_status = 0;
			if (put_user(cs, b++)) {
				retval = -EFAULT;
				b--;
				break;
			}
			nr--;
			break;
		}
		/* This statement must be first before checking for input
		   so that any interrupt will set the state back to
		   TASK_RUNNING. */
		set_current_state(TASK_INTERRUPTIBLE);
		
		if (((minimum - (b - buf)) < tty->minimum_to_wake) &&
		    ((minimum - (b - buf)) >= 1))
			tty->minimum_to_wake = (minimum - (b - buf));
		
		if (!input_available_p(tty, 0)) {
			if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
				retval = -EIO;
				break;
			}
			if (tty_hung_up_p(file))
				break;
			if (!timeout)
				break;
			if (file->f_flags & O_NONBLOCK) {
				retval = -EAGAIN;
				break;
			}
			if (signal_pending(current)) {
				retval = -ERESTARTSYS;
				break;
			}
			clear_bit(TTY_DONT_FLIP, &tty->flags);
			timeout = schedule_timeout(timeout);
			set_bit(TTY_DONT_FLIP, &tty->flags);
			continue;
		}
		__set_current_state(TASK_RUNNING);

		/* Deal with packet mode. */
		if (tty->packet && b == buf) {
			if (put_user(TIOCPKT_DATA, b++)) {
				retval = -EFAULT;
				b--;
				break;
			}
			nr--;
		}

		if (tty->icanon) {
			/* N.B. avoid overrun if nr == 0 */
			while (nr && tty->read_cnt) {
 				int eol;

				eol = test_and_clear_bit(tty->read_tail,
						tty->read_flags);
				c = tty->read_buf[tty->read_tail];
				spin_lock_irqsave(&tty->read_lock, flags);
				tty->read_tail = ((tty->read_tail+1) &
						  (N_TTY_BUF_SIZE-1));
				tty->read_cnt--;
				if (eol) {
					/* this test should be redundant:
					 * we shouldn't be reading data if
					 * canon_data is 0
					 */
					if (--tty->canon_data < 0)
						tty->canon_data = 0;
				}
				spin_unlock_irqrestore(&tty->read_lock, flags);

				if (!eol || (c != __DISABLED_CHAR)) {
					if (put_user(c, b++)) {
						retval = -EFAULT;
						b--;
						break;
					}
					nr--;
				}
				if (eol)
					break;
			}
			if (retval)
				break;
		} else {
			int uncopied;
			uncopied = copy_from_read_buf(tty, &b, &nr);
			uncopied += copy_from_read_buf(tty, &b, &nr);
			if (uncopied) {
				retval = -EFAULT;
				break;
			}
		}

		/* If there is enough space in the read buffer now, let the
		 * low-level driver know. We use n_tty_chars_in_buffer() to
		 * check the buffer, as it now knows about canonical mode.
		 * Otherwise, if the driver is throttled and the line is
		 * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode,
		 * we won't get any more characters.
		 */
		if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE)
			check_unthrottle(tty);

		if (b - buf >= minimum)
			break;
		if (time)
			timeout = time;
	}
	clear_bit(TTY_DONT_FLIP, &tty->flags);
	up(&tty->atomic_read);
	remove_wait_queue(&tty->read_wait, &wait);

	if (!waitqueue_active(&tty->read_wait))
		tty->minimum_to_wake = minimum;

	__set_current_state(TASK_RUNNING);
	size = b - buf;
	if (size) {
		retval = size;
		if (nr)
	       		clear_bit(TTY_PUSH, &tty->flags);
	} else if (test_and_clear_bit(TTY_PUSH, &tty->flags))
		 goto do_it_again;

	return retval;
}
Exemple #26
0
int
arcofi_fsm(struct IsdnCardState *cs, int event, void *data) {
	if (cs->debug & L1_DEB_MONITOR) {
		debugl1(cs, "arcofi state %d event %d", cs->dc.isac.arcofi_state, event);
	}
	if (event == ARCOFI_TIMEOUT) {
		cs->dc.isac.arcofi_state = ARCOFI_NOP;
		test_and_set_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags);
		wake_up(&cs->dc.isac.arcofi_wait);
 		return(1);
	}
	switch (cs->dc.isac.arcofi_state) {
		case ARCOFI_NOP:
			if (event == ARCOFI_START) {
				cs->dc.isac.arcofi_list = data;
				cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT;
				send_arcofi(cs);
			}
			break;
		case ARCOFI_TRANSMIT:
			if (event == ARCOFI_TX_END) {
				if (cs->dc.isac.arcofi_list->receive) {
					add_arcofi_timer(cs);
					cs->dc.isac.arcofi_state = ARCOFI_RECEIVE;
				} else {
					if (cs->dc.isac.arcofi_list->next) {
						cs->dc.isac.arcofi_list =
							cs->dc.isac.arcofi_list->next;
						send_arcofi(cs);
					} else {
						if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) {
							del_timer(&cs->dc.isac.arcofitimer);
						}
						cs->dc.isac.arcofi_state = ARCOFI_NOP;
						wake_up(&cs->dc.isac.arcofi_wait);
					}
				}
			}
			break;
		case ARCOFI_RECEIVE:
			if (event == ARCOFI_RX_END) {
				if (cs->dc.isac.arcofi_list->next) {
					cs->dc.isac.arcofi_list =
						cs->dc.isac.arcofi_list->next;
					cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT;
					send_arcofi(cs);
				} else {
					if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) {
						del_timer(&cs->dc.isac.arcofitimer);
					}
					cs->dc.isac.arcofi_state = ARCOFI_NOP;
					wake_up(&cs->dc.isac.arcofi_wait);
				}
			}
			break;
		default:
			debugl1(cs, "Arcofi unknown state %x", cs->dc.isac.arcofi_state);
			return(2);
	}
	return(0);
}
Exemple #27
0
static int iwl_send_scan_abort(struct iwl_priv *priv)
{
	int ret;
	struct iwl_rx_packet *pkt;
	struct iwl_host_cmd cmd = {
		.id = REPLY_SCAN_ABORT_CMD,
		.flags = CMD_SYNC | CMD_WANT_SKB,
	};

	/* Exit instantly with error when device is not ready
	 * to receive scan abort command or it does not perform
	 * hardware scan currently */
	if (!test_bit(STATUS_READY, &priv->shrd->status) ||
	    !test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) ||
	    !test_bit(STATUS_SCAN_HW, &priv->shrd->status) ||
	    test_bit(STATUS_FW_ERROR, &priv->shrd->status) ||
	    test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
		return -EIO;

	ret = iwl_trans_send_cmd(trans(priv), &cmd);
	if (ret)
		return ret;

	pkt = (struct iwl_rx_packet *)cmd.reply_page;
	if (pkt->u.status != CAN_ABORT_STATUS) {
		/* The scan abort will return 1 for success or
		 * 2 for "failure".  A failure condition can be
		 * due to simply not being in an active scan which
		 * can occur if we send the scan abort before we
		 * the microcode has notified us that a scan is
		 * completed. */
		IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
		ret = -EIO;
	}

	iwl_free_pages(priv->shrd, cmd.reply_page);
	return ret;
}

static void iwl_complete_scan(struct iwl_priv *priv, bool aborted)
{
	/* check if scan was requested from mac80211 */
	if (priv->scan_request) {
		IWL_DEBUG_SCAN(priv, "Complete scan in mac80211\n");
		ieee80211_scan_completed(priv->hw, aborted);
	}

	if (priv->scan_type == IWL_SCAN_ROC) {
		ieee80211_remain_on_channel_expired(priv->hw);
		priv->hw_roc_channel = NULL;
		schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ);
	}

	priv->scan_type = IWL_SCAN_NORMAL;
	priv->scan_vif = NULL;
	priv->scan_request = NULL;
}

static void iwl_process_scan_complete(struct iwl_priv *priv)
{
	bool aborted;

	lockdep_assert_held(&priv->shrd->mutex);

	if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status))
		return;

	IWL_DEBUG_SCAN(priv, "Completed scan.\n");

	cancel_delayed_work(&priv->scan_check);

	aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status);
	if (aborted)
		IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n");

	if (!test_and_clear_bit(STATUS_SCANNING, &priv->shrd->status)) {
		IWL_DEBUG_SCAN(priv, "Scan already completed.\n");
		goto out_settings;
	}

	if (priv->scan_type == IWL_SCAN_ROC) {
		ieee80211_remain_on_channel_expired(priv->hw);
		priv->hw_roc_channel = NULL;
		schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ);
	}

	if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) {
		int err;

		/* Check if mac80211 requested scan during our internal scan */
		if (priv->scan_request == NULL)
			goto out_complete;

		/* If so request a new scan */
		err = iwl_scan_initiate(priv, priv->scan_vif, IWL_SCAN_NORMAL,
					priv->scan_request->channels[0]->band);
		if (err) {
			IWL_DEBUG_SCAN(priv,
				"failed to initiate pending scan: %d\n", err);
			aborted = true;
			goto out_complete;
		}

		return;
	}

out_complete:
	iwl_complete_scan(priv, aborted);

out_settings:
	/* Can we still talk to firmware ? */
	if (!iwl_is_ready_rf(priv->shrd))
		return;

	iwlagn_post_scan(priv);
}
/* called by config.c */
int __init
setup_enternow_pci(struct IsdnCard *card)
{
	int bytecnt;
	struct IsdnCardState *cs = card->cs;
	char tmp[64];

#if CONFIG_PCI
#ifdef __BIG_ENDIAN
#error "not running on big endian machines now"
#endif
        strcpy(tmp, enternow_pci_rev);
	printk(KERN_INFO "HiSax: Formula-n Europe AG enter:now ISDN PCI driver Rev. %s\n", HiSax_getrev(tmp));
	if (cs->typ != ISDN_CTYPE_ENTERNOW)
		return(0);
	test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);

	for ( ;; )
	{
		if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET,
			PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
			if (pci_enable_device(dev_netjet))
				return(0);
			cs->irq = dev_netjet->irq;
			if (!cs->irq) {
				printk(KERN_WARNING "enter:now PCI: No IRQ for PCI card found\n");
				return(0);
			}
			cs->hw.njet.base = pci_resource_start(dev_netjet, 0);
			if (!cs->hw.njet.base) {
				printk(KERN_WARNING "enter:now PCI: No IO-Adr for PCI card found\n");
				return(0);
			}
                        /* checks Sub-Vendor ID because system crashes with Traverse-Card */
			if ((dev_netjet->subsystem_vendor != 0x55) ||
				(dev_netjet->subsystem_device != 0x02)) {
				printk(KERN_WARNING "enter:now: You tried to load this driver with an incompatible TigerJet-card\n");
                                printk(KERN_WARNING "Use type=20 for Traverse NetJet PCI Card.\n");
                                return(0);
                        }
		} else {
                        printk(KERN_WARNING "enter:now PCI: No PCI card found\n");
			return(0);
		}

		cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA;
		cs->hw.njet.isac = cs->hw.njet.base + 0xC0; // Fenster zum AMD

		/* Reset an */
		cs->hw.njet.ctrl_reg = 0x07;  // geändert von 0xff
		OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
		/* 20 ms Pause */
		mdelay(20);

		cs->hw.njet.ctrl_reg = 0x30;  /* Reset Off and status read clear */
		OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
		mdelay(10);

		cs->hw.njet.auxd = 0x00; // war 0xc0
		cs->hw.njet.dmactrl = 0;

		OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ);
		OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ);
		OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd);

		break;
	}
#else

	printk(KERN_WARNING "enter:now PCI: NO_PCI_BIOS\n");
	printk(KERN_WARNING "enter:now PCI: unable to config Formula-n enter:now ISDN PCI ab\n");
	return (0);

#endif /* CONFIG_PCI */

	bytecnt = 256;

	printk(KERN_INFO
		"enter:now PCI: PCI card configured at 0x%lx IRQ %d\n",
		cs->hw.njet.base, cs->irq);
	if (!request_region(cs->hw.njet.base, bytecnt, "Fn_ISDN")) {
		printk(KERN_WARNING
			   "HiSax: %s config port %lx-%lx already in use\n",
			   CardType[card->typ],
			   cs->hw.njet.base,
			   cs->hw.njet.base + bytecnt);
		return (0);
	}
	setup_Amd7930(cs);
	cs->hw.njet.last_is0 = 0;
        /* macro rByteAMD */
        cs->readisac = &ReadByteAmd7930;
        /* macro wByteAMD */
        cs->writeisac = &WriteByteAmd7930;
        cs->dc.amd7930.setIrqMask = &enpci_setIrqMask;

        cs->BC_Read_Reg  = &dummyrr;
	cs->BC_Write_Reg = &dummywr;
	cs->BC_Send_Data = &netjet_fill_dma;
	cs->cardmsg = &enpci_card_msg;
	cs->irq_func = &enpci_interrupt;
	cs->irq_flags |= SA_SHIRQ;

        return (1);
}
Exemple #29
0
static int process_measurement(struct file *file, const struct cred *cred,
			       u32 secid, char *buf, loff_t size, int mask,
			       enum ima_hooks func)
{
	struct inode *inode = file_inode(file);
	struct integrity_iint_cache *iint = NULL;
	struct ima_template_desc *template_desc;
	char *pathbuf = NULL;
	char filename[NAME_MAX];
	const char *pathname = NULL;
	int rc = 0, action, must_appraise = 0;
	int pcr = CONFIG_IMA_MEASURE_PCR_IDX;
	struct evm_ima_xattr_data *xattr_value = NULL;
	int xattr_len = 0;
	bool violation_check;
	enum hash_algo hash_algo;

	if (!ima_policy_flag || !S_ISREG(inode->i_mode))
		return 0;

	/* Return an IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT action
	 * bitmask based on the appraise/audit/measurement policy.
	 * Included is the appraise submask.
	 */
	action = ima_get_action(inode, cred, secid, mask, func, &pcr);
	violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) &&
			   (ima_policy_flag & IMA_MEASURE));
	if (!action && !violation_check)
		return 0;

	must_appraise = action & IMA_APPRAISE;

	/*  Is the appraise rule hook specific?  */
	if (action & IMA_FILE_APPRAISE)
		func = FILE_CHECK;

	inode_lock(inode);

	if (action) {
		iint = integrity_inode_get(inode);
		if (!iint)
			rc = -ENOMEM;
	}

	if (!rc && violation_check)
		ima_rdwr_violation_check(file, iint, action & IMA_MEASURE,
					 &pathbuf, &pathname, filename);

	inode_unlock(inode);

	if (rc)
		goto out;
	if (!action)
		goto out;

	mutex_lock(&iint->mutex);

	if (test_and_clear_bit(IMA_CHANGE_ATTR, &iint->atomic_flags))
		/* reset appraisal flags if ima_inode_post_setattr was called */
		iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED |
				 IMA_APPRAISE_SUBMASK | IMA_APPRAISED_SUBMASK |
				 IMA_ACTION_FLAGS);

	/*
	 * Re-evaulate the file if either the xattr has changed or the
	 * kernel has no way of detecting file change on the filesystem.
	 * (Limited to privileged mounted filesystems.)
	 */
	if (test_and_clear_bit(IMA_CHANGE_XATTR, &iint->atomic_flags) ||
	    ((inode->i_sb->s_iflags & SB_I_IMA_UNVERIFIABLE_SIGNATURE) &&
	     !(inode->i_sb->s_iflags & SB_I_UNTRUSTED_MOUNTER) &&
	     !(action & IMA_FAIL_UNVERIFIABLE_SIGS))) {
		iint->flags &= ~IMA_DONE_MASK;
		iint->measured_pcrs = 0;
	}

	/* Determine if already appraised/measured based on bitmask
	 * (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED,
	 *  IMA_AUDIT, IMA_AUDITED)
	 */
	iint->flags |= action;
	action &= IMA_DO_MASK;
	action &= ~((iint->flags & (IMA_DONE_MASK ^ IMA_MEASURED)) >> 1);

	/* If target pcr is already measured, unset IMA_MEASURE action */
	if ((action & IMA_MEASURE) && (iint->measured_pcrs & (0x1 << pcr)))
		action ^= IMA_MEASURE;

	/* HASH sets the digital signature and update flags, nothing else */
	if ((action & IMA_HASH) &&
	    !(test_bit(IMA_DIGSIG, &iint->atomic_flags))) {
		xattr_len = ima_read_xattr(file_dentry(file), &xattr_value);
		if ((xattr_value && xattr_len > 2) &&
		    (xattr_value->type == EVM_IMA_XATTR_DIGSIG))
			set_bit(IMA_DIGSIG, &iint->atomic_flags);
		iint->flags |= IMA_HASHED;
		action ^= IMA_HASH;
		set_bit(IMA_UPDATE_XATTR, &iint->atomic_flags);
	}

	/* Nothing to do, just return existing appraised status */
	if (!action) {
		if (must_appraise)
			rc = ima_get_cache_status(iint, func);
		goto out_locked;
	}

	template_desc = ima_template_desc_current();
	if ((action & IMA_APPRAISE_SUBMASK) ||
		    strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0)
		/* read 'security.ima' */
		xattr_len = ima_read_xattr(file_dentry(file), &xattr_value);

	hash_algo = ima_get_hash_algo(xattr_value, xattr_len);

	rc = ima_collect_measurement(iint, file, buf, size, hash_algo);
	if (rc != 0 && rc != -EBADF && rc != -EINVAL)
		goto out_locked;

	if (!pathbuf)	/* ima_rdwr_violation possibly pre-fetched */
		pathname = ima_d_path(&file->f_path, &pathbuf, filename);

	if (action & IMA_MEASURE)
		ima_store_measurement(iint, file, pathname,
				      xattr_value, xattr_len, pcr);
	if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) {
		inode_lock(inode);
		rc = ima_appraise_measurement(func, iint, file, pathname,
					      xattr_value, xattr_len);
		inode_unlock(inode);
	}
	if (action & IMA_AUDIT)
		ima_audit_measurement(iint, pathname);

	if ((file->f_flags & O_DIRECT) && (iint->flags & IMA_PERMIT_DIRECTIO))
		rc = 0;
out_locked:
	if ((mask & MAY_WRITE) && test_bit(IMA_DIGSIG, &iint->atomic_flags) &&
	     !(iint->flags & IMA_NEW_FILE))
		rc = -EACCES;
	mutex_unlock(&iint->mutex);
	kfree(xattr_value);
out:
	if (pathbuf)
		__putname(pathbuf);
	if (must_appraise) {
		if (rc && (ima_appraise & IMA_APPRAISE_ENFORCE))
			return -EACCES;
		if (file->f_mode & FMODE_WRITE)
			set_bit(IMA_UPDATE_XATTR, &iint->atomic_flags);
	}
	return 0;
}
Exemple #30
0
static void
amd7930_Dchan_l2l1(struct PStack *st, int pr, void *arg)
{
	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
	struct sk_buff *skb = arg;
	char str[64];

	switch (pr) {
		case (PH_DATA_REQ):
			if (cs->tx_skb) {
				skb_queue_tail(&cs->sq, skb);
#ifdef L2FRAME_DEBUG		/* psa */
				if (cs->debug & L1_DEB_LAPD)
					Logl2Frame(cs, skb, "PH_DATA Queued", 0);
#endif
			} else {
				if ((cs->dlogflag) && (!(skb->data[2] & 1))) {
					/* I-FRAME */
					LogFrame(cs, skb->data, skb->len);
					sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei);
					dlogframe(cs, skb->data+4, skb->len-4,
						  str);
				}
				cs->tx_skb = skb;
				cs->tx_cnt = 0;
#ifdef L2FRAME_DEBUG		/* psa */
				if (cs->debug & L1_DEB_LAPD)
					Logl2Frame(cs, skb, "PH_DATA", 0);
#endif
				amd7930_dxmit(0, skb->data, skb->len,
					      &amd7930_dxmit_callback, cs);
			}
			break;
		case (PH_PULL_IND):
			if (cs->tx_skb) {
				if (cs->debug & L1_DEB_WARN)
					debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
				skb_queue_tail(&cs->sq, skb);
				break;
			}
			if ((cs->dlogflag) && (!(skb->data[2] & 1))) {	/* I-FRAME */
				LogFrame(cs, skb->data, skb->len);
				sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei);
				dlogframe(cs, skb->data + 4, skb->len - 4,
					  str);
			}
			cs->tx_skb = skb;
			cs->tx_cnt = 0;
#ifdef L2FRAME_DEBUG		/* psa */
			if (cs->debug & L1_DEB_LAPD)
				Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
#endif
			amd7930_dxmit(0, cs->tx_skb->data, cs->tx_skb->len,
				      &amd7930_dxmit_callback, cs);
			break;
		case (PH_PULL_REQ):
#ifdef L2FRAME_DEBUG		/* psa */
			if (cs->debug & L1_DEB_LAPD)
				debugl1(cs, "-> PH_REQUEST_PULL");
#endif
			if (!cs->tx_skb) {
				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
				st->l1.l1l2(st, PH_PULL_CNF, NULL);
			} else
				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
			break;
	}
}