/**
 * get_tlabel - allocate a transaction label
 * @host: host to be used for transmission
 * @nodeid: the node ID of the transmission target
 * @wait: whether to sleep if no tlabel is available
 *
 * Every asynchronous transaction on the 1394 bus needs a transaction label to
 * match the response to the request.  This label has to be different from any
 * other transaction label in an outstanding request to the same node to make
 * matching possible without ambiguity.
 *
 * There are 64 different tlabels, so an allocated tlabel has to be freed with
 * free_tlabel() after the transaction is complete (unless it's reused again for
 * the same target node).
 *
 * @wait must not be set to true if you are calling from interrupt context.
 *
 * Return value: The allocated transaction label or -1 if there was no free
 * tlabel and @wait is false.
 */
int get_tlabel(struct hpsb_host *host, nodeid_t nodeid, int wait)
{
	int tlabel;
	unsigned long flags;

	if (wait) {
		down(&host->tlabel_count);
	} else {
		if (down_trylock(&host->tlabel_count)) return -1;
	}

	spin_lock_irqsave(&host->tlabel_lock, flags);

	if (host->tlabel_pool[0] != ~0) {
		tlabel = ffz(host->tlabel_pool[0]);
		host->tlabel_pool[0] |= 1 << tlabel;
	} else {
		tlabel = ffz(host->tlabel_pool[1]);
		host->tlabel_pool[1] |= 1 << tlabel;
		tlabel += 32;
	}

	spin_unlock_irqrestore(&host->tlabel_lock, flags);

	return tlabel;
}
示例#2
0
unsigned long find_next_zero_bit(unsigned long *addr,
                                     unsigned long size, unsigned long offset)
{
        unsigned long *word, *last;
        unsigned long first_bit, bit, base;

        word = addr + OFF_BY_START(offset);
        last = addr + OFF_BY_START(size-1);
        first_bit = offset % BITS_PER_LONG;
        base = offset - first_bit;

        if (offset >= size)
                return size;
        if (first_bit != 0) {
                int tmp = (*word++) & (~0UL << first_bit);
                bit = ffz(tmp);
                if (bit < BITS_PER_LONG)
                        goto found;
                word++;
                base += BITS_PER_LONG;
        }
        while (word <= last) {
                if (*word != ~0UL) {
                        bit = ffz(*word);
                        goto found;
                }
                word++;
                base += BITS_PER_LONG;
        }
        return size;
found:
        return base + bit;
}
示例#3
0
文件: irq.c 项目: ivucica/linux
int bigsur_irq_demux(int irq)
{
        int dmux_irq = irq;
        u8 mask, actv_irqs;
        u32 reg_num;

        DIPRINTK(3,"bigsur_irq_demux, irq=%d\n", irq);
        /* decode the 1st level IRQ */
        if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
                /* Get corresponding L2 ISR bitmask and ISR number */
                mask = bigsur_l2irq_mask[irq-BIGSUR_IRQ_LOW];
                reg_num = bigsur_l2irq_reg[irq-BIGSUR_IRQ_LOW];
                /* find the active IRQ's (XOR with inactive level)*/
                actv_irqs = inb(isr_base-reg_num*isr_offset) ^
                                        bigsur_l2_inactv_state[reg_num];
                /* decode active IRQ's */
                actv_irqs = actv_irqs & mask & ~(inb(imr_base-reg_num*imr_offset));
                /* if NEZ then we have an active L2 IRQ */
                if(actv_irqs) dmux_irq = ffz(~actv_irqs) + reg_num*8+BIGSUR_2NDLVL_IRQ_LOW;
                /* if no 2nd level IRQ action, but has 1st level, use 1st level handler */
                if(!irq_desc[dmux_irq].action && irq_desc[irq].action)
                        dmux_irq = irq;
                DIPRINTK(1,"bigsur_irq_demux: irq=%d dmux_irq=%d mask=0x%04x reg=%d\n",
                        irq, dmux_irq, mask, reg_num);
        }
#ifdef CONFIG_HD64465
        dmux_irq = hd64465_irq_demux(dmux_irq);
#endif /* CONFIG_HD64465 */
        DIPRINTK(3,"bigsur_irq_demux, demux_irq=%d\n", dmux_irq);

        return dmux_irq;
}
示例#4
0
文件: irq.c 项目: mischief/los
/*
 * Free all allocated IRQs.
 * If only one of the IRQs grabbed was received, return it.
 * Otherwise, autoprobe failed.
 */
int
probe_irq_off (unsigned long irqs)
{
    unsigned int i, irqmask;

    irqmask = probe_mask;	/* IRQs received */
    /* free all allocated IRQs */
    for (i = (NHWI - 1); i > 0; i--) {
        if (irqs & (1 << i)) {
            free_irq(i, NULL);
        }
    }
#ifdef IRQ_DEBUG
    printk("probe_irq_off: irqs=0x%04x irqmask=0x%04x\n", (unsigned)irqs,
           irqmask);
#endif
    /* what allocated IRQs did I receive? */
    irqs &= irqmask;
    if (!irqs)	/* none found... */
        return 0;
    i = ffz(~irqs);
    if (irqs != (irqs & (1 << i)))	/* multiple IRQs found? */
        i = -i;
    return i;
}
示例#5
0
static inline int find_next_one_bit(void *addr, int size, int offset)
{
	uintBPL_t *p = ((uintBPL_t *) addr) + (offset / BITS_PER_LONG);
	int result = offset & ~(BITS_PER_LONG - 1);
	unsigned long tmp;

	if (offset >= size)
		return size;
	size -= result;
	offset &= (BITS_PER_LONG - 1);
	if (offset) {
		tmp = leBPL_to_cpup(p++);
		tmp &= ~0UL << offset;
		if (size < BITS_PER_LONG)
			goto found_first;
		if (tmp)
			goto found_middle;
		size -= BITS_PER_LONG;
		result += BITS_PER_LONG;
	}
	while (size & ~(BITS_PER_LONG - 1)) {
		tmp = leBPL_to_cpup(p++);
		if (tmp)
			goto found_middle;
		result += BITS_PER_LONG;
		size -= BITS_PER_LONG;
	}
	if (!size)
		return result;
	tmp = leBPL_to_cpup(p);
found_first:
	tmp &= ~0UL >> (BITS_PER_LONG - size);
found_middle:
	return result + ffz(~tmp);
}
示例#6
0
/*
 * Scan the free space map, for this zone, calculating the total
 * number of map bits in each free space fragment.
 *
 * Note: idmask is limited to 15 bits [3.2]
 */
static unsigned int
scan_free_map(struct adfs_sb_info *asb, struct adfs_discmap *dm)
{
	const unsigned int mapsize = dm->dm_endbit + 32;
	const unsigned int idlen  = asb->s_idlen;
	const unsigned int frag_idlen = idlen <= 15 ? idlen : 15;
	const u32 idmask = (1 << frag_idlen) - 1;
	unsigned char *map = dm->dm_bh->b_data;
	unsigned int start = 8, mapptr;
	u32 frag;
	unsigned long total = 0;

	/*
	 * get fragment id
	 */
	frag = GET_FRAG_ID(map, start, idmask);

	/*
	 * If the freelink is null, then no free fragments
	 * exist in this zone.
	 */
	if (frag == 0)
		return 0;

	do {
		start += frag;

		/*
		 * get fragment id
		 */
		frag = GET_FRAG_ID(map, start, idmask);
		mapptr = start + idlen;

		/*
		 * find end of fragment
		 */
		{
			__le32 *_map = (__le32 *)map;
			u32 v = le32_to_cpu(_map[mapptr >> 5]) >> (mapptr & 31);
			while (v == 0) {
				mapptr = (mapptr & ~31) + 32;
				if (mapptr >= mapsize)
					goto error;
				v = le32_to_cpu(_map[mapptr >> 5]);
			}

			mapptr += 1 + ffz(~v);
		}

		total += mapptr - start;
	} while (frag >= idlen + 1);

	if (frag != 0)
		printk(KERN_ERR "adfs: undersized free fragment\n");

	return total;
error:
	printk(KERN_ERR "adfs: oversized free fragment\n");
	return 0;
}
示例#7
0
static void
dp264_device_interrupt(unsigned long vector, struct pt_regs * regs)
{
#if 1
	printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n");
#else
	unsigned long pld;
	unsigned int i;

	/* Read the interrupt summary register of TSUNAMI */
	pld = TSUNAMI_cchip->dir0.csr;

	/*
	 * Now for every possible bit set, work through them and call
	 * the appropriate interrupt handler.
	 */
	while (pld) {
		i = ffz(~pld);
		pld &= pld - 1; /* clear least bit set */
		if (i == 55)
			isa_device_interrupt(vector, regs);
		else
			handle_irq(16 + i, 16 + i, regs);
#if 0
		TSUNAMI_cchip->dir0.csr = 1UL << i; mb();
		tmp = TSUNAMI_cchip->dir0.csr;
#endif
	}
#endif
}
示例#8
0
/*
 * Return the next free block in the map.
 */
static int get_next_free_block(struct thread_data *td, struct fio_file *f,
			       enum fio_ddir ddir, unsigned long long *b)
{
	unsigned long long block, min_bs = td->o.rw_min_bs, lastb;
	int i;

	lastb = last_block(td, f, ddir);
	if (!lastb)
		return 1;

	i = f->last_free_lookup;
	block = i * BLOCKS_PER_MAP;
	while (block * min_bs < f->real_file_size &&
		block * min_bs < f->io_size) {
		if (f->file_map[i] != -1UL) {
			block += ffz(f->file_map[i]);
			if (block > lastb)
				break;
			f->last_free_lookup = i;
			*b = block;
			return 0;
		}

		block += BLOCKS_PER_MAP;
		i++;
	}

	dprint(FD_IO, "failed finding a free block\n");
	return 1;
}
static void
mikasa_device_interrupt(unsigned long vector)
{
	unsigned long pld;
	unsigned int i;

	/* Read the interrupt summary registers */
	pld = (((~inw(0x534) & 0x0000ffffUL) << 16)
	       | (((unsigned long) inb(0xa0)) << 8)
	       | inb(0x20));

	/*
	 * Now for every possible bit set, work through them and call
	 * the appropriate interrupt handler.
	 */
	while (pld) {
		i = ffz(~pld);
		pld &= pld - 1; /* clear least bit set */
		if (i < 16) {
			isa_device_interrupt(vector);
		} else {
			handle_irq(i);
		}
	}
}
示例#10
0
文件: sys_rx164.c 项目: 08opt/linux
static void 
rx164_device_interrupt(unsigned long vector)
{
	unsigned long pld;
	volatile unsigned int *dirr;
	long i;

	/* Read the interrupt summary register.  On Polaris, this is
	   the DIRR register in PCI config space (offset 0x84).  */
	dirr = (void *)(POLARIS_DENSE_CONFIG_BASE + 0x84);
	pld = *dirr;

	/*
	 * Now for every possible bit set, work through them and call
	 * the appropriate interrupt handler.
	 */
	while (pld) {
		i = ffz(~pld);
		pld &= pld - 1; /* clear least bit set */
		if (i == 20) {
			isa_no_iack_sc_device_interrupt(vector);
		} else {
			handle_irq(16+i);
		}
	}
}
示例#11
0
文件: irq.c 项目: andreiw/mkunity
static inline void eb66_and_eb64p_device_interrupt(unsigned long vector,
						   struct pt_regs * regs)
{
	unsigned long pld;
	unsigned int i;
	unsigned long flags;

	save_flags(flags);
	cli();

	/* read the interrupt summary registers */
	pld = inb(0x26) | (inb(0x27) << 8);
	/*
	 * Now, for every possible bit set, work through
	 * them and call the appropriate interrupt handler.
	 */
	while (pld) {
		i = ffz(~pld);
		pld &= pld - 1;	/* clear least bit set */

		if (i == 5) {
			isa_device_interrupt(vector, regs);
		} else {
			device_interrupt(16 + i, 16 + i, regs);
		}
	}
	restore_flags(flags);
}
示例#12
0
static int i8259_get_irq_number(int irq)
{
	unsigned long isr;

	isr = inb(0x20);
	irq = ffz(~isr);
	if (irq == 2) {
		isr = inb(0xa0);
		irq = 8 + ffz(~isr);
	}

	if (irq < 0 || irq > 15)
		return -EINVAL;

	return I8259_IRQ_BASE + irq;
}
示例#13
0
文件: irq.c 项目: andreiw/mkunity
static inline void cabriolet_and_eb66p_device_interrupt(unsigned long vector,
							struct pt_regs * regs)
{
	unsigned long pld;
	unsigned int i;
	unsigned long flags;

	save_flags(flags);
	cli();

	/* read the interrupt summary registers */
	pld = inb(0x804) | (inb(0x805) << 8) | (inb(0x806) << 16);

#if 0
	printk("[0x%04X/0x%04X]", pld, inb(0x20) | (inb(0xA0) << 8));
#endif

	/*
	 * Now for every possible bit set, work through them and call
	 * the appropriate interrupt handler.
	 */
	while (pld) {
		i = ffz(~pld);
		pld &= pld - 1;	/* clear least bit set */
		if (i == 4) {
			isa_device_interrupt(vector, regs);
		} else {
			device_interrupt(16 + i, 16 + i, regs);
		}
	}
	restore_flags(flags);
}
示例#14
0
文件: irq.c 项目: andreiw/mkunity
static inline void mikasa_device_interrupt(unsigned long vector,
					   struct pt_regs * regs)
{
	unsigned long pld;
	unsigned int i;
	unsigned long flags;

	save_flags(flags);
	cli();

        /* read the interrupt summary registers */
        pld = (((unsigned long) (~inw(0x534)) & 0x0000ffffUL) << 16) |
	       (((unsigned long) inb(0xa0))  <<  8) |
	       ((unsigned long) inb(0x20));

#if 0
        printk("[0x%08lx]", pld);
#endif

        /*
         * Now for every possible bit set, work through them and call
         * the appropriate interrupt handler.
         */
        while (pld) {
		i = ffz(~pld);
		pld &= pld - 1; /* clear least bit set */
		if (i < 16) {
			isa_device_interrupt(vector, regs);
		} else {
			device_interrupt(i, i, regs);
		}
        }
	restore_flags(flags);
}
示例#15
0
文件: irq.c 项目: andreiw/mkunity
/* we have to conditionally compile this because of GRU_xxx symbols */
static inline void alcor_and_xlt_device_interrupt(unsigned long vector,
                                                  struct pt_regs * regs)
{
        unsigned long pld;
        unsigned int i;
        unsigned long flags;

        save_flags(flags);
        cli();

        /* read the interrupt summary register of the GRU */
        pld = (*(unsigned int *)GRU_INT_REQ) & GRU_INT_REQ_BITS;

#if 0
        printk("[0x%08lx/0x%04x]", pld, inb(0x20) | (inb(0xA0) << 8));
#endif

        /*
         * Now for every possible bit set, work through them and call
         * the appropriate interrupt handler.
         */
        while (pld) {
                i = ffz(~pld);
                pld &= pld - 1; /* clear least bit set */
                if (i == 31) {
                        isa_device_interrupt(vector, regs);
                } else {
                        device_interrupt(16 + i, 16 + i, regs);
                }
        }
        restore_flags(flags);
}
示例#16
0
文件: io_u.c 项目: jeefke/fio
/*
 * Return the next free block in the map.
 */
static int get_next_free_block(struct thread_data *td, struct fio_file *f,
			       enum fio_ddir ddir, unsigned long long *b)
{
	unsigned long long min_bs = td->o.rw_min_bs, lastb;
	int i;

	lastb = last_block(td, f, ddir);
	if (!lastb)
		return 1;

	i = f->last_free_lookup;
	*b = (i * BLOCKS_PER_MAP);
	while ((*b) * min_bs < f->real_file_size &&
		(*b) * min_bs < f->io_size) {
		if (f->file_map[i] != (unsigned int) -1) {
			*b += ffz(f->file_map[i]);
			if (*b > lastb)
				break;
			f->last_free_lookup = i;
			return 0;
		}

		*b += BLOCKS_PER_MAP;
		i++;
	}

	dprint(FD_IO, "failed finding a free block\n");
	return 1;
}
示例#17
0
文件: goptions.c 项目: Rapaka/fio
static GtkWidget *gopt_get_group_frame(struct gopt_job_view *gjv,
				       GtkWidget *box, unsigned int groupmask)
{
	unsigned int mask, group;
	struct opt_group *og;
	GtkWidget *frame, *hbox;
	struct gopt_frame_widget *gfw;

	if (!groupmask)
		return 0;

	mask = groupmask;
	og = opt_group_cat_from_mask(&mask);
	if (!og)
		return NULL;

	group = ffz(~groupmask);
	gfw = &gjv->g_widgets[group];
	if (!gfw->vbox[0]) {
		frame = gtk_frame_new(og->name);
		gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 3);
		hbox = gtk_hbox_new(FALSE, 0);
		gtk_container_add(GTK_CONTAINER(frame), hbox);
		gfw->vbox[0] = gtk_vbox_new(TRUE, 5);
		gfw->vbox[1] = gtk_vbox_new(TRUE, 5);
		gtk_box_pack_start(GTK_BOX(hbox), gfw->vbox[0], TRUE, TRUE, 5);
		gtk_box_pack_start(GTK_BOX(hbox), gfw->vbox[1], TRUE, TRUE, 5);
	}

	hbox = gtk_hbox_new(FALSE, 3);
	gtk_box_pack_start(GTK_BOX(gfw->vbox[gfw->nr++ & 1]), hbox, FALSE, FALSE, 5);
	return hbox;
}
示例#18
0
文件: smp.c 项目: dduval/kernel-rhel3
void
handle_IPI (int irq, void *dev_id, struct pt_regs *regs)
{
	int this_cpu = smp_processor_id();
	unsigned long *pending_ipis = &local_cpu_data->ipi.operation;
	unsigned long ops;

	/* Count this now; we may make a call that never returns. */
	local_cpu_data->ipi_count++;

	mb();	/* Order interrupt and bit testing. */
	while ((ops = xchg(pending_ipis, 0)) != 0) {
	  mb();	/* Order bit clearing and data access. */
	  do {
		unsigned long which;

		which = ffz(~ops);
		ops &= ~(1 << which);

		switch (which) {
		case IPI_CALL_FUNC:
			{
				struct call_data_struct *data;
				void (*func)(void *info);
				void *info;
				int wait;

				/* release the 'pointer lock' */
				data = (struct call_data_struct *) call_data;
				func = data->func;
				info = data->info;
				wait = data->wait;

				mb();
				atomic_inc(&data->started);

				/* At this point the structure may be gone unless wait is true.  */
				(*func)(info);

				/* Notify the sending CPU that the task is done.  */
				mb();
				if (wait)
					atomic_inc(&data->finished);
			}
			break;

		case IPI_CPU_STOP:
			stop_this_cpu();
			break;

		default:
			printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which);
			break;
		} /* Switch */
	  } while (ops);

	  mb();	/* Order data access and bit testing. */
	}
}
示例#19
0
/*
 * return the map bit offset of the fragment frag_id in the zone dm.
 * Note that the loop is optimised for best asm code - look at the
 * output of:
 *  gcc -D__KERNEL__ -O2 -I../../include -o - -S map.c
 */
static int
lookup_zone(const struct adfs_discmap *dm, const unsigned int idlen,
	    const unsigned int frag_id, unsigned int *offset)
{
	const unsigned int mapsize = dm->dm_endbit;
	const u32 idmask = (1 << idlen) - 1;
	unsigned char *map = dm->dm_bh->b_data + 4;
	unsigned int start = dm->dm_startbit;
	unsigned int mapptr;
	u32 frag;

	do {
		frag = GET_FRAG_ID(map, start, idmask);
		mapptr = start + idlen;

		/*
		 * find end of fragment
		 */
		{
			u32 v, *_map = (u32 *)map;

			v = le32_to_cpu(_map[mapptr >> 5]) >> (mapptr & 31);
			while (v == 0) {
				mapptr = (mapptr & ~31) + 32;
				if (mapptr >= mapsize)
					goto error;
				v = le32_to_cpu(_map[mapptr >> 5]);
			}

			mapptr += 1 + ffz(~v);
		}

		if (frag == frag_id)
			goto found;
again:
		start = mapptr;
	} while (mapptr < mapsize);
	return -1;

error:
	printk(KERN_ERR "adfs: oversized fragment 0x%x at 0x%x-0x%x\n",
		frag, start, mapptr);
	return -1;

found:
	{
		int length = mapptr - start;
		if (*offset >= length) {
			*offset -= length;
			goto again;
		}
	}
	return start + *offset;
}
示例#20
0
/*
 * Find the first cleared bit in a memory region.
 */
unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
{
	unsigned long idx;

	for (idx = 0; idx * BITS_PER_LONG < size; idx++) {
		if (addr[idx] != ~0UL)
			return min(idx * BITS_PER_LONG + ffz(addr[idx]), size);
	}

	return size;
}
int set_next_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
{
	u32 idx = ffz(gd->used_laws);

	if (idx >= FSL_HW_NUM_LAWS)
		return -1;

	set_law(idx, addr, sz, id);

	return idx;
}
示例#22
0
// Reserves a free slot in ReserveBMap
qitem* queue_get_item(queue *q)
{
	int i;
	qitem *buf        = (qitem*)(q->buf + q->mapbytes*2);
	atomic_llong *map = (atomic_llong*)q->buf;
	int zbit;
	qitem *r;

	while(1)
	{
		// Reserve space
		for (i = 0; i < q->map_elements; i++)
		{
			long long int mval = atomic_load(&map[i]);
			long long int nval;

			// if no zero bit go to next element
			if (!(zbit = ffz(mval)))
			{
				continue;
			}

			nval = mval | (((long long int)1) << (--zbit));

			// update map val with bit set. 
			// If successful we are done.
			if (atomic_compare_exchange_strong(&map[i], &mval, nval))
			{
				// printf("ZBIT %d %lld %lld\n",zbit,mval, sizeof(mval));
				atomic_fetch_add(&q->size, 1);
				break;
			}
			// Unable to exchange, go again for same index. 
			else
			{
				atomic_fetch_add(&q->ct, 1);
				i--;
			}
		}

		if (i < q->map_elements)
		{
			r = &buf[i*64+zbit];
			break;
		}
		else
		{
			usleep(100);
		}
	}
	return r;
}
示例#23
0
void
LinuxMode::setCPU()
{
    uval local;
    cpuControl->P();

    do {
	local = availCPU;
	tassertMsg(local!=0, "All cpus used: %lx\n",local);
	cpu = ffz(~local);
	tassertMsg(cpu<NR_CPUS, "Bad cpu: %lx %ld\n",local,cpu);
    } while (!CompareAndStoreSynced(&availCPU, local, local & ~(1ULL<<cpu)));
}
示例#24
0
int wbuf_put(const int npages, char *buf1, char *data, int *tries)
{
	int i,t = 0;
	char *buf = buf1+WBUF_MAPBYTES(npages);
	atomic_llong *map = (atomic_llong*)buf1;
	int zbit;

	while(1)
	{
		// Reserve space
		for (i = 0; i < WBUF_MAP_ELEMENTS(npages); i++)
		{
			long long int mval = atomic_load(&map[i]);
			long long int nval;

			// if no zero bit go to next element
			if (!(zbit = ffz(mval)))
				continue;

			nval = mval | (((long long int)1) << (--zbit));

			// update map val with bit set. 
			// If successful we are done.
			if (atomic_compare_exchange_strong(&map[i], &mval, nval))
				break;
			// Unable to exchange, go again for same index. 
			else
			{
				i--;
				t++;
			}
		}

		if (i < WBUF_MAP_ELEMENTS(npages))
		{
			// Copy data
			memcpy(buf + i*64*PGSZ + zbit*PGSZ, data, PGSZ);
			break;
		}
		else
		{
			usleep(100);
		}
	}

	if (tries != NULL)
		*tries = t;

	return i*64 + zbit;
}
示例#25
0
/*
 * return the map bit offset of the fragment frag_id in
 * the zone dm.
 * Note that the loop is optimised for best asm code -
 * look at the output of:
 *  gcc -D__KERNEL__ -O2 -I../../include -o - -S map.c
 */
static int
lookup_zone(const struct adfs_discmap *dm, const unsigned int idlen,
	    const unsigned int frag_id, unsigned int *offset)
{
	const unsigned int mapsize = dm->dm_endbit;
	const unsigned int idmask = (1 << idlen) - 1;
	unsigned long *map = ((unsigned long *)dm->dm_bh->b_data) + 1;
	unsigned int start = dm->dm_startbit;
	unsigned int mapptr;

	do {
		unsigned long frag;

		frag = GET_FRAG_ID(map, start, idmask);
		mapptr = start + idlen;

		/*
		 * find end of fragment
		 */
		{
			unsigned long v2;

			while ((v2 = map[mapptr >> 5] >> (mapptr & 31)) == 0) {
				mapptr = (mapptr & ~31) + 32;
				if (mapptr >= mapsize)
					goto error;
			}

			mapptr += 1 + ffz(~v2);
		}

		if (frag == frag_id)
			goto found;
again:
		start = mapptr;
	} while (mapptr < mapsize);

error:
	return -1;

found:
	{
		int length = mapptr - start;
		if (*offset >= length) {
			*offset -= length;
			goto again;
		}
	}
	return start + *offset;
}
int
kgsl_g12_drawctxt_create(struct kgsl_device_private *dev_priv,
			uint32_t unused,
			unsigned int *drawctxt_id)
{
	int cmd;
	int result;
	unsigned int ctx_id;
	struct kgsl_device *device = dev_priv->device;

	if (g_z1xx.numcontext == 0) {
		if (kgsl_sharedmem_alloc(0, KGSL_G12_RB_SIZE,
					&g_z1xx.cmdbufdesc) !=  0)
			return -ENOMEM;

		cmd = (int)(((VGV3_NEXTCMD_JUMP) &
			VGV3_NEXTCMD_NEXTCMD_FMASK)
			<< VGV3_NEXTCMD_NEXTCMD_FSHIFT);

		result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
					 ADDR_VGV3_MODE, 4);
		if (result != 0)
			return result;
		result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
					 ADDR_VGV3_NEXTADDR,
					 g_z1xx.cmdbufdesc.physaddr);
		if (result != 0)
			return result;
		result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
					 ADDR_VGV3_NEXTCMD, cmd | 5);
		if (result != 0)
			return result;

		result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
					 ADDR_VGV3_CONTROL, 0);
		if (result != 0)
			return result;
	}
	ctx_id = ffz(dev_priv->ctxt_id_mask);

	g_z1xx.numcontext++;
	if (g_z1xx.numcontext > KGSL_G12_CONTEXT_MAX) {
		*drawctxt_id = 0;
		return KGSL_FAILURE;

	}
	*drawctxt_id = ctx_id;

	return KGSL_SUCCESS;
}
示例#27
0
/***
 *  rt_udp_socket - create a new UDP-Socket
 *  @s: socket
 */
int rt_udp_socket(struct rtdm_dev_context *context,
                  rtdm_user_info_t *user_info)
{
    struct rtsocket *sock = (struct rtsocket *)&context->dev_private;
    int             ret;
    int             i;
    int             index;
    unsigned long   flags;


    if ((ret = rt_socket_init(context)) != 0)
        return ret;

    sock->protocol        = IPPROTO_UDP;
    sock->prot.inet.saddr = INADDR_ANY;
    sock->prot.inet.state = TCP_CLOSE;
#ifdef CONFIG_RTNET_RTDM_SELECT
    sock->wakeup_select   = NULL;
#endif /* CONFIG_RTNET_RTDM_SELECT */

    rtos_spin_lock_irqsave(&udp_socket_base_lock, flags);

    /* enforce maximum number of UDP sockets */
    if (free_ports == 0) {
        rtos_spin_unlock_irqrestore(&udp_socket_base_lock, flags);
        rt_socket_cleanup(context);
        return -EAGAIN;
    }
    free_ports--;

    /* find free auto-port in bitmap */
    for (i = 0; i < sizeof(port_bitmap)/4; i++)
        if (port_bitmap[i] != 0xFFFFFFFF)
            break;
    index = ffz(port_bitmap[i]);
    set_bit(index, &port_bitmap[i]);
    index += i*32;
    sock->prot.inet.reg_index = index;
    sock->prot.inet.sport     = index + auto_port_start;

    /* register UDP socket */
    port_registry[index].sport = sock->prot.inet.sport;
    port_registry[index].saddr = INADDR_ANY;
    port_registry[index].sock  = sock;

    rtos_spin_unlock_irqrestore(&udp_socket_base_lock, flags);

    return 0;
}
示例#28
0
文件: irq.c 项目: andreiw/mkunity
/*
 * Get the result of the IRQ probe.. A negative result means that
 * we have several candidates (but we return the lowest-numbered
 * one).
 */
int probe_irq_off(unsigned long irqs)
{
	int i;
	
	irqs &= irq_mask & ~1;	/* always mask out irq 0---it's the unused timer */
#ifdef CONFIG_ALPHA_P2K
	irqs &= ~(1 << 8);	/* mask out irq 8 since that's the unused RTC input to PIC */
#endif
	if (!irqs)
		return 0;
	i = ffz(~irqs);
	if (irqs != (1UL << i))
		i = -i;
	return i;
}
示例#29
0
文件: irq.c 项目: 12019/hg556a_source
/* Yuck.  the _demux API is ugly */
int ec3104_irq_demux(int irq)
{
        if (irq == EC3104_IRQ) {
                unsigned int mask;

                mask = ctrl_readl(EC3104_IRR);

                if (mask == 0xffffffff)
                        return EC3104_IRQ;
                else
                        return EC3104_IRQBASE + ffz(mask);
        }

        return irq;
}
示例#30
0
/* this returns the number of consequative 1 bits starting
 * from the right, get_index128(00 00 00 00 00 00 ... 00 00 10 FB) = 2 */
static inline int get_index128(be128 *block)
{
	int x;
	__be32 *p = (__be32 *) block;

	for (p += 3, x = 0; x < 128; p--, x += 32) {
		u32 val = be32_to_cpup(p);

		if (!~val)
			continue;

		return x + ffz(val);
	}

	return x;
}