aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/netfilter_ipv6
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2009-10-05 14:10:44 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2009-10-05 14:10:44 -0400
commit4ad2bcf6f6fff31ace097f7616b002df445110ec (patch)
treed7dda7c8cdfcabf1e92ac7044f0e08b3b7cc455c /include/linux/netfilter_ipv6
parentf8ed8c406d70b9a040807a01de5296d8832cafd7 (diff)
Bugfix: Fix FMLP priority inheritance under GSN-EDFHEADmaster
This fixes a regression introduced by the RTSS'09 improvements. Just calling unlink() on any task is not safe: it might reside in a release heap. This was done in the case that a new blocker increases a lock holder's priority. To avoid crashing in this case, the FMLP code was changed to be more careful when propagating an inherited priority. The code now detects three different scenarios and uses heap_decrease() to update the position of the lock holder's heap node. This fixes a simple test case.
Diffstat (limited to 'include/linux/netfilter_ipv6')
0 files changed, 0 insertions, 0 deletions
wip-shared-lib The LITMUS^RT kernel.Bjoern Brandenburg
aboutsummaryrefslogblamecommitdiffstats
path: root/drivers/pcmcia/pcmcia_resource.c
blob: 599b116d9747211514a6522625e6830756f0d492 (plain) (tree)
























                                                                       











                            





                                  
                    














































                                                                              
                                           














































































































                                                                                            
 
                                                                     

                                                         

                                                                      


                                                    
























































                                                                      
 
                                                              
                                                        
 

                                                                        

                                             





























































































                                                                                          



                                                                  
                           
                                                          


                                 




































                                                            
                                                            




                                               

                          



































                                                                    
                                                             

                                             
                                                

              
                                                   
                                     
                                              
 

                                             































                                                                                 
                                                                 
 
                                                
 
                                            
                                     
                                       
 

                                             


















                                                                    
                                                                   
 

                                                
                                     
                                        
 

                                             






















































                                                               
                                                             



                                                   
                                                


                            


                                         

                                           
                          



































































































                                                                                     
                                             









                                                               
                                                                 
 
                                                

                    


                                         

                                           
                          























                                                                            
                                      





















                                                                           
                                                                   
 
                                                

                                     
 

                                         
                          











                                                                               
                                                                                      

















































                                                                                                              
                                       














                                                                   
                                                                                            
 
                                                   



                      



























                                                               
                             







                                                                                                
                                             




























                                                   
/*
 * PCMCIA 16-bit resource management functions
 *
 * The initial developer of the original code is David A. Hinds
 * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
 * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 *
 * Copyright (C) 1999	     David A. Hinds
 * Copyright (C) 2004-2005   Dominik Brodowski
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/device.h>

#define IN_CARD_SERVICES
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>

#include "cs_internal.h"
#include "ds_internal.h"


/* Access speed for IO windows */
static int io_speed = 0;
module_param(io_speed, int, 0444);


#ifdef CONFIG_PCMCIA_PROBE
#include <asm/irq.h>
/* mask of IRQs already reserved by other cards, we should avoid using them */
static u8 pcmcia_used_irq[NR_IRQS];
#endif


#ifdef DEBUG
extern int ds_pc_debug;
#define cs_socket_name(skt)    ((skt)->dev.class_id)

#define ds_dbg(skt, lvl, fmt, arg...) do {			\
	if (ds_pc_debug >= lvl)					\
		printk(KERN_DEBUG "pcmcia_resource: %s: " fmt,	\
			cs_socket_name(skt) , ## arg);		\
} while (0)
#else
#define ds_dbg(lvl, fmt, arg...) do { } while (0)
#endif



/** alloc_io_space
 *
 * Special stuff for managing IO windows, because they are scarce
 */

static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
			  ioaddr_t num, u_int lines)
{
	int i;
	kio_addr_t try, align;

	align = (*base) ? (lines ? 1<<lines : 0) : 1;
	if (align && (align < num)) {
		if (*base) {
			ds_dbg(s, 0, "odd IO request: num %#x align %#lx\n",
			       num, align);
			align = 0;
		} else
			while (align && (align < num)) align <<= 1;
	}
	if (*base & ~(align-1)) {
		ds_dbg(s, 0, "odd IO request: base %#x align %#lx\n",
		       *base, align);
		align = 0;
	}
	if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) {
		*base = s->io_offset | (*base & 0x0fff);
		s->io[0].Attributes = attr;
		return 0;
	}
	/* Check for an already-allocated window that must conflict with
	 * what was asked for.  It is a hack because it does not catch all
	 * potential conflicts, just the most obvious ones.
	 */
	for (i = 0; i < MAX_IO_WIN; i++)
		if ((s->io[i].NumPorts != 0) &&
		    ((s->io[i].BasePort & (align-1)) == *base))
			return 1;
	for (i = 0; i < MAX_IO_WIN; i++) {
		if (s->io[i].NumPorts == 0) {
			s->io[i].res = pcmcia_find_io_region(*base, num, align, s);
			if (s->io[i].res) {
				s->io[i].Attributes = attr;
				s->io[i].BasePort = *base = s->io[i].res->start;
				s->io[i].NumPorts = s->io[i].InUse = num;
				break;
			} else
				return 1;
		} else if (s->io[i].Attributes != attr)
			continue;
		/* Try to extend top of window */
		try = s->io[i].BasePort + s->io[i].NumPorts;
		if ((*base == 0) || (*base == try))
			if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start,
						    s->io[i].res->end + num, s) == 0) {
				*base = try;
				s->io[i].NumPorts += num;
				s->io[i].InUse += num;
				break;
			}
		/* Try to extend bottom of window */
		try = s->io[i].BasePort - num;
		if ((*base == 0) || (*base == try))
			if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num,
						    s->io[i].res->end, s) == 0) {
				s->io[i].BasePort = *base = try;
				s->io[i].NumPorts += num;
				s->io[i].InUse += num;
				break;
			}
	}
	return (i == MAX_IO_WIN);
} /* alloc_io_space */


static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,
			     ioaddr_t num)
{
	int i;

	for (i = 0; i < MAX_IO_WIN; i++) {
		if ((s->io[i].BasePort <= base) &&
		    (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) {
			s->io[i].InUse -= num;
			/* Free the window if no one else is using it */
			if (s->io[i].InUse == 0) {
				s->io[i].NumPorts = 0;
				release_resource(s->io[i].res);
				kfree(s->io[i].res);
				s->io[i].res = NULL;
			}
		}
	}
} /* release_io_space */


/** pccard_access_configuration_register
 *
 * Access_configuration_register() reads and writes configuration
 * registers in attribute memory.  Memory window 0 is reserved for
 * this and the tuple reading services.
 */

int pccard_access_configuration_register(struct pcmcia_socket *s,
					 unsigned int function,
					 conf_reg_t *reg)
{
	config_t *c;
	int addr;
	u_char val;

	if (!s || !s->config)
		return CS_NO_CARD;

	c = &s->config[function];

	if (c == NULL)
		return CS_NO_CARD;

	if (!(c->state & CONFIG_LOCKED))
		return CS_CONFIGURATION_LOCKED;

	addr = (c->ConfigBase + reg->Offset) >> 1;

	switch (reg->Action) {
	case CS_READ:
		pcmcia_read_cis_mem(s, 1, addr, 1, &val);
		reg->Value = val;
		break;
	case CS_WRITE:
		val = reg->Value;
		pcmcia_write_cis_mem(s, 1, addr, 1, &val);
		break;
	default:
		return CS_BAD_ARGS;
		break;
	}
	return CS_SUCCESS;
} /* pccard_access_configuration_register */

int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
					 conf_reg_t *reg)
{
	return pccard_access_configuration_register(p_dev->socket,
						    p_dev->func, reg);
}
EXPORT_SYMBOL(pcmcia_access_configuration_register);



int pccard_get_configuration_info(struct pcmcia_socket *s,
				  unsigned int function,
				  config_info_t *config)
{
	config_t *c;

	if (!(s->state & SOCKET_PRESENT))
		return CS_NO_CARD;

	config->Function = function;

#ifdef CONFIG_CARDBUS
	if (s->state & SOCKET_CARDBUS) {
		memset(config, 0, sizeof(config_info_t));
		config->Vcc = s->socket.Vcc;
		config->Vpp1 = config->Vpp2 = s->socket.Vpp;
		config->Option = s->cb_dev->subordinate->number;
		if (s->state & SOCKET_CARDBUS_CONFIG) {
			config->Attributes = CONF_VALID_CLIENT;
			config->IntType = INT_CARDBUS;
			config->AssignedIRQ = s->irq.AssignedIRQ;
			if (config->AssignedIRQ)
				config->Attributes |= CONF_ENABLE_IRQ;
			config->BasePort1 = s->io[0].BasePort;
			config->NumPorts1 = s->io[0].NumPorts;
		}
		return CS_SUCCESS;
	}
#endif

	c = (s->config != NULL) ? &s->config[function] : NULL;

	if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
		config->Attributes = 0;
		config->Vcc = s->socket.Vcc;
		config->Vpp1 = config->Vpp2 = s->socket.Vpp;
		return CS_SUCCESS;
	}

	/* !!! This is a hack !!! */
	memcpy(&config->Attributes, &c->Attributes, sizeof(config_t));
	config->Attributes |= CONF_VALID_CLIENT;
	config->CardValues = c->CardValues;
	config->IRQAttributes = c->irq.Attributes;
	config->AssignedIRQ = s->irq.AssignedIRQ;
	config->BasePort1 = c->io.BasePort1;
	config->NumPorts1 = c->io.NumPorts1;
	config->Attributes1 = c->io.Attributes1;
	config->BasePort2 = c->io.BasePort2;
	config->NumPorts2 = c->io.NumPorts2;
	config->Attributes2 = c->io.Attributes2;
	config->IOAddrLines = c->io.IOAddrLines;

	return CS_SUCCESS;
} /* pccard_get_configuration_info */

int pcmcia_get_configuration_info(struct pcmcia_device *p_dev,
				  config_info_t *config)
{
	return pccard_get_configuration_info(p_dev->socket, p_dev->func,
					     config);
}
EXPORT_SYMBOL(pcmcia_get_configuration_info);


/** pcmcia_get_window
 */
int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,
		      int idx, win_req_t *req)
{
	window_t *win;
	int w;

	if (!s || !(s->state & SOCKET_PRESENT))
		return CS_NO_CARD;
	for (w = idx; w < MAX_WIN; w++)