static inline void __lock_kernel(void)
{
	preempt_disable();
	if (unlikely(!_raw_spin_trylock(&kernel_flag))) {
		/*
		 * If preemption was disabled even before this
		 * was called, there's nothing we can be polite
		 * about - just spin.
		 */
		if (preempt_count() > 1) {
			_raw_spin_lock(&kernel_flag);
			return;
		}

		/*
		 * Otherwise, let's wait for the kernel lock
		 * with preemption enabled..
		 */
		do {
			preempt_enable();
			while (spin_is_locked(&kernel_flag))
				cpu_relax();
			preempt_disable();
		} while (!_raw_spin_trylock(&kernel_flag));
	}
}
int _dbg_write_trylock(rwlock_t *rw, const char *bfile, int bline)
{
#if 0
	void *inline_pc = __builtin_return_address(0);
	int cpu = smp_processor_id();
#endif
	
	if(unlikely(in_interrupt())) {	/* acquiring write lock in interrupt context, bad idea */
		pdc_printf("write_lock caller: %s:%d, IRQs enabled,\n", bfile, bline);
		BUG();
	}

	/* Note: if interrupts are disabled (which is most likely), the printk
	will never show on the console. We might need a polling method to flush
	the dmesg buffer anyhow. */
	
	_raw_spin_lock(&rw->lock);

	if(rw->counter != 0) {
		/* this basically never happens */
		_raw_spin_unlock(&rw->lock);
		return 0;
	}

	/* got it.  now leave without unlocking */
	rw->counter = -1; /* remember we are locked */
#if 0
	pdc_printf("%s:%d: try write_lock grabbed in %s at %p(%d)\n",
		   bfile, bline, current->comm, inline_pc, cpu);
#endif
	return 1;
}
Exemple #3
0
static int fhci_hub_status_data(struct usb_hcd *hcd, char *buf)
{
	struct fhci_hcd *fhci = hcd_to_fhci(hcd);
	int ret = 0;
	unsigned long flags;

	fhci_dbg(fhci, "-> %s\n", __func__);

	udelay(1000);

	local_irq_save(flags);
	_raw_spin_lock(&fhci->lock);

	if (fhci->vroot_hub->port.wPortChange & (USB_PORT_STAT_C_CONNECTION |
			USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_SUSPEND |
			USB_PORT_STAT_C_RESET | USB_PORT_STAT_C_OVERCURRENT)) {
		*buf = 1 << 1;
		ret = 1;
		printk("%x\n", fhci->vroot_hub->port.wPortChange);
	} 

	_raw_spin_unlock(&fhci->lock);
	local_irq_restore(flags);

	fhci_dbg(fhci, "<- %s\n", __func__);

	return ret;
}
void _dbg_write_lock(rwlock_t *rw, const char *bfile, int bline)
{
	void *inline_pc = __builtin_return_address(0);
	unsigned long started = jiffies;
	long stuck = INIT_STUCK;
	int printed = 0;
	int cpu = smp_processor_id();
	
	if(unlikely(in_interrupt())) {	/* acquiring write lock in interrupt context, bad idea */
		pdc_printf("write_lock caller: %s:%d, IRQs enabled,\n", bfile, bline);
		BUG();
	}

	/* Note: if interrupts are disabled (which is most likely), the printk
	will never show on the console. We might need a polling method to flush
	the dmesg buffer anyhow. */
	
retry:
	_raw_spin_lock(&rw->lock);

	if(rw->counter != 0) {
		/* this basically never happens */
		_raw_spin_unlock(&rw->lock);
		
		stuck--;
		if ((unlikely(stuck <= 0)) && (rw->counter < 0)) {
			pdc_printf(
				"%s:%d: write_lock stuck on writer"
				" in %s at %p(%d) %ld ticks\n",
				bfile, bline, current->comm, inline_pc,
				cpu, jiffies - started);
			stuck = INIT_STUCK;
			printed = 1;
		}
		else if (unlikely(stuck <= 0)) {
			pdc_printf(
				"%s:%d: write_lock stuck on reader"
				" in %s at %p(%d) %ld ticks\n",
				bfile, bline, current->comm, inline_pc,
				cpu, jiffies - started);
			stuck = INIT_STUCK;
			printed = 1;
		}
		
		while(rw->counter != 0);

		goto retry;
	}

	/* got it.  now leave without unlocking */
	rw->counter = -1; /* remember we are locked */

	if (unlikely(printed)) {
		pdc_printf(
			"%s:%d: write_lock grabbed in %s at %p(%d) %ld ticks\n",
			bfile, bline, current->comm, inline_pc,
			cpu, jiffies - started);
	}
}
Exemple #5
0
/*
 * This could be a long-held lock.  If another CPU holds it for a long time,
 * and that CPU is not asked to reschedule then *this* CPU will spin on the
 * lock for a long time, even if *this* CPU is asked to reschedule.
 *
 * So what we do here, in the slow (contended) path is to spin on the lock by
 * hand while permitting preemption.
 *
 * Called inside preempt_disable().
 */
static inline void __preempt_spin_lock(spinlock_t *lock)
{
	if (preempt_count() > 1) {
		_raw_spin_lock(lock);
		return;
	}

	do {
		preempt_enable();
		while (spin_is_locked(lock))
			cpu_relax();
		preempt_disable();
	} while (!_raw_spin_trylock(lock));
}
int _atomic_dec_and_raw_spin_lock(atomic_t *atomic, raw_spinlock_t *lock)
{
	int counter;
	int newcount;

	for (;;) {
		counter = atomic_read(atomic);
		newcount = counter - 1;
		if (!newcount)
			break;		/* do it the slow way */

		newcount = cmpxchg(&atomic->counter, counter, newcount);
		if (newcount == counter)
			return 0;
	}

	_raw_spin_lock(lock);
	if (atomic_dec_and_test(atomic))
		return 1;
	_raw_spin_unlock(lock);
	return 0;
}
void _dbg_read_lock(rwlock_t * rw, const char *bfile, int bline)
{
#if 0
	void *inline_pc = __builtin_return_address(0);
	unsigned long started = jiffies;
	int cpu = smp_processor_id();
#endif
	unsigned long flags;

	local_irq_save(flags);
	_raw_spin_lock(&rw->lock); 

	rw->counter++;
#if 0
	pdc_printf(
		"%s:%d: read_lock grabbed in %s at %p(%d) %ld ticks\n",
		bfile, bline, current->comm, inline_pc,
		cpu, jiffies - started);
#endif
	_raw_spin_unlock(&rw->lock);
	local_irq_restore(flags);
}
/*
 * Non-preemption case - just get the spinlock
 */
static inline void __lock_kernel(void)
{
	_raw_spin_lock(&kernel_flag);
}
Exemple #9
0
/*
 * Non-preemption case - just get the spinlock
 */
static inline void __lock_kernel(void)
{
	preempt_disable();
	_raw_spin_lock(&kernel_flag);
}
Exemple #10
0
static int fhci_hub_control(struct usb_hcd *hcd,
			    u16 typeReq,
			    u16 wValue, u16 wIndex, char *buf, u16 wLength)
{
	struct fhci_hcd *fhci = hcd_to_fhci(hcd);
	int retval = 0;
	int len = 0;
	struct usb_hub_status *hub_status;
	struct usb_port_status *port_status;
	unsigned long flags;

	local_irq_save(flags);
	_raw_spin_lock(&fhci->lock);

	fhci_dbg(fhci, "-> %s\n", __func__);

	switch (typeReq) {
	case ClearHubFeature:
		switch (wValue) {
		case C_HUB_LOCAL_POWER:
		case C_HUB_OVER_CURRENT:
			break;
		default:
			goto error;
		}
		break;
	case ClearPortFeature:
		fhci->vroot_hub->feature &= (1 << wValue);

		switch (wValue) {
		case USB_PORT_FEAT_ENABLE:
			fhci->vroot_hub->port.wPortStatus &=
			    ~USB_PORT_STAT_ENABLE;
			usb_port_disable(fhci);
			break;
		case USB_PORT_FEAT_C_ENABLE:
			fhci->vroot_hub->port.wPortChange &=
			    ~USB_PORT_STAT_C_ENABLE;
			break;
		case USB_PORT_FEAT_SUSPEND:
			fhci->vroot_hub->port.wPortStatus &=
			    ~USB_PORT_STAT_SUSPEND;
			fhci_stop_sof_timer(fhci);
			break;
		case USB_PORT_FEAT_C_SUSPEND:
			fhci->vroot_hub->port.wPortChange &=
			    ~USB_PORT_STAT_C_SUSPEND;
			break;
		case USB_PORT_FEAT_POWER:
			fhci->vroot_hub->port.wPortStatus &=
			    ~USB_PORT_STAT_POWER;
			config_transceiver(fhci, FHCI_OP_POWER_OFF);
			break;
		case USB_PORT_FEAT_C_CONNECTION:
			fhci->vroot_hub->port.wPortChange &=
			    ~USB_PORT_STAT_C_CONNECTION;
			break;
		case USB_PORT_FEAT_C_OVER_CURRENT:
			fhci->vroot_hub->port.wPortChange &=
			    ~USB_PORT_STAT_C_OVERCURRENT;
			break;
		case USB_PORT_FEAT_C_RESET:
			fhci->vroot_hub->port.wPortChange &=
			    ~USB_PORT_STAT_C_RESET;
		default:
			goto error;
		}
		break;
	case GetHubDescriptor:
		memcpy(buf, root_hub_des, sizeof(root_hub_des));
		buf[3] = 0x11; /* per-port power, no ovrcrnt */
		len = (buf[0] < wLength) ? buf[0] : wLength;
		break;
	case GetHubStatus:
		hub_status = (struct usb_hub_status *)buf;
		hub_status->wHubStatus =
		    cpu_to_le16(fhci->vroot_hub->hub.wHubStatus);
		hub_status->wHubChange =
		    cpu_to_le16(fhci->vroot_hub->hub.wHubChange);
		len = 4;
		break;
	case GetPortStatus:
		port_status = (struct usb_port_status *)buf;
		port_status->wPortStatus =
		    cpu_to_le16(fhci->vroot_hub->port.wPortStatus);
		port_status->wPortChange =
		    cpu_to_le16(fhci->vroot_hub->port.wPortChange);
		len = 4;
		break;
	case SetHubFeature:
		switch (wValue) {
		case C_HUB_OVER_CURRENT:
		case C_HUB_LOCAL_POWER:
			break;
		default:
			goto error;
		}
		break;
	case SetPortFeature:
		fhci->vroot_hub->feature |= (1 << wValue);

		switch (wValue) {
		case USB_PORT_FEAT_ENABLE:
			fhci->vroot_hub->port.wPortStatus |=
			    USB_PORT_STAT_ENABLE;
			usb_port_enable(fhci->usb_lld);
			break;
		case USB_PORT_FEAT_SUSPEND:
			fhci->vroot_hub->port.wPortStatus |=
			    USB_PORT_STAT_SUSPEND;
			fhci_stop_sof_timer(fhci);
			break;
		case USB_PORT_FEAT_RESET:
			fhci->vroot_hub->port.wPortStatus |=
			    USB_PORT_STAT_RESET;
			usb_port_reset(fhci->usb_lld);
			fhci->vroot_hub->port.wPortStatus |=
			    USB_PORT_STAT_ENABLE;
			fhci->vroot_hub->port.wPortStatus &=
			    ~USB_PORT_STAT_RESET;
			break;
		case USB_PORT_FEAT_POWER:
			fhci->vroot_hub->port.wPortStatus |=
			    USB_PORT_STAT_POWER;
			config_transceiver(fhci, FHCI_OP_POWER_ON);
			break;
		default:
			goto error;
		}
		break;
	default:
error:
		retval = -EPIPE;
	}

	fhci_dbg(fhci, "<- %s\n", __func__);

	_raw_spin_unlock(&fhci->lock);
	local_irq_restore(flags);

	return retval;
}
Exemple #11
0
extern void spin_lock(struct spinlock *lock) { _raw_spin_lock(lock); }
Exemple #12
0
void __lockfunc _spin_lock(spinlock_t *lock)
{
	preempt_disable();
	_raw_spin_lock(lock);
}
Exemple #13
0
void __lockfunc _spin_lock_bh(spinlock_t *lock)
{
	local_bh_disable();
	preempt_disable();
	_raw_spin_lock(lock);
}