Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d37a371 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6: (49 commits)
  pcmcia: validate late-added resources
  pcmcia: allow for extension of resource interval
  pcmcia: remove useless msleep in ds.c
  pcmcia: use read_cis_mem return value
  pcmcia: handle error in serial_cs config calls
  pcmcia: add locking to pcmcia_{read,write}_cis_mem
  pcmcia: avoid prod_id memleak
  pcmcia: avoid sysfs-related lockup for cardbus
  pcmcia: use state machine for extended requery
  pcmcia: delay re-scanning and re-querying of PCMCIA bus
  pcmcia: use pccardd to handle eject, insert, suspend and resume requests
  pcmcia: use ops_mutex for rsrc_{mgr,nonstatic} locking
  pcmcia: use mutex for dynid lock
  pcmcia: assert locking to struct pcmcia_device
  pcmcia: add locking documentation
  pcmcia: simplify locking
  pcmcia: add locking to struct pcmcia_socket->pcmcia_state()
  pcmcia: protect s->device_count
  pcmcia: properly lock skt->irq, skt->irq_mask
  pcmcia: lock ops->set_socket
  ...
parents ef1a8de8 7b4884ca
Loading
Loading
Loading
Loading
+118 −0
Original line number Original line Diff line number Diff line
This file explains the locking and exclusion scheme used in the PCCARD
and PCMCIA subsystems.


A) Overview, Locking Hierarchy:
===============================

pcmcia_socket_list_rwsem	- protects only the list of sockets
- skt_mutex			- serializes card insert / ejection
  - ops_mutex			- serializes socket operation


B) Exclusion
============

The following functions and callbacks to struct pcmcia_socket must
be called with "skt_mutex" held:

	socket_detect_change()
	send_event()
	socket_reset()
	socket_shutdown()
	socket_setup()
	socket_remove()
	socket_insert()
	socket_early_resume()
	socket_late_resume()
	socket_resume()
	socket_suspend()

	struct pcmcia_callback	*callback

The following functions and callbacks to struct pcmcia_socket must
be called with "ops_mutex" held:

	socket_reset()
	socket_setup()

	struct pccard_operations	*ops
	struct pccard_resource_ops	*resource_ops;

Note that send_event() and struct pcmcia_callback *callback must not be
called with "ops_mutex" held.


C) Protection
=============

1. Global Data:
---------------
struct list_head	pcmcia_socket_list;

protected by pcmcia_socket_list_rwsem;


2. Per-Socket Data:
-------------------
The resource_ops and their data are protected by ops_mutex.

The "main" struct pcmcia_socket is protected as follows (read-only fields
or single-use fields not mentioned):

- by pcmcia_socket_list_rwsem:
	struct list_head	socket_list;

- by thread_lock:
	unsigned int		thread_events;

- by skt_mutex:
	u_int			suspended_state;
	void			(*tune_bridge);
	struct pcmcia_callback	*callback;
	int			resume_status;

- by ops_mutex:
	socket_state_t		socket;
	u_int			state;
	u_short			lock_count;
	pccard_mem_map		cis_mem;
	void __iomem 		*cis_virt;
	struct { }		irq;
	io_window_t		io[];
	pccard_mem_map		win[];
	struct list_head	cis_cache;
	size_t			fake_cis_len;
	u8			*fake_cis;
	u_int			irq_mask;
	void 			(*zoom_video);
	int 			(*power_hook);
	u8			resource...;
	struct list_head	devices_list;
	u8			device_count;
	struct 			pcmcia_state;


3. Per PCMCIA-device Data:
--------------------------

The "main" struct pcmcia_devie is protected as follows (read-only fields
or single-use fields not mentioned):


- by pcmcia_socket->ops_mutex:
	struct list_head	socket_device_list;
	struct config_t		*function_config;
	u16			_irq:1;
	u16			_io:1;
	u16			_win:4;
	u16			_locked:1;
	u16			allow_func_id_match:1;
	u16			suspended:1;
	u16			_removed:1;

- by the PCMCIA driver:
	io_req_t		io;
	irq_req_t		irq;
	config_req_t		conf;
	window_handle_t		win;
+1 −1
Original line number Original line Diff line number Diff line
@@ -1047,7 +1047,7 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
static ssize_t cmm_write(struct file *filp, const char __user *buf,
static ssize_t cmm_write(struct file *filp, const char __user *buf,
			 size_t count, loff_t *ppos)
			 size_t count, loff_t *ppos)
{
{
	struct cm4000_dev *dev = (struct cm4000_dev *) filp->private_data;
	struct cm4000_dev *dev = filp->private_data;
	unsigned int iobase = dev->p_dev->io.BasePort1;
	unsigned int iobase = dev->p_dev->io.BasePort1;
	unsigned short s;
	unsigned short s;
	unsigned char tmp;
	unsigned char tmp;
+2 −4
Original line number Original line Diff line number Diff line
@@ -453,8 +453,7 @@ static int mhz_mfc_config(struct pcmcia_device *link)


    link->conf.Attributes |= CONF_ENABLE_SPKR;
    link->conf.Attributes |= CONF_ENABLE_SPKR;
    link->conf.Status = CCSR_AUDIO_ENA;
    link->conf.Status = CCSR_AUDIO_ENA;
    link->irq.Attributes =
    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
	IRQ_TYPE_DYNAMIC_SHARING;
    link->io.IOAddrLines = 16;
    link->io.IOAddrLines = 16;
    link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
    link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
    link->io.NumPorts2 = 8;
    link->io.NumPorts2 = 8;
@@ -652,8 +651,7 @@ static int osi_config(struct pcmcia_device *link)


    link->conf.Attributes |= CONF_ENABLE_SPKR;
    link->conf.Attributes |= CONF_ENABLE_SPKR;
    link->conf.Status = CCSR_AUDIO_ENA;
    link->conf.Status = CCSR_AUDIO_ENA;
    link->irq.Attributes =
    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
	IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
    link->io.NumPorts1 = 64;
    link->io.NumPorts1 = 64;
    link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
    link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
    link->io.NumPorts2 = 8;
    link->io.NumPorts2 = 8;
+3 −6
Original line number Original line Diff line number Diff line
@@ -84,7 +84,7 @@ config YENTA
	tristate "CardBus yenta-compatible bridge support"
	tristate "CardBus yenta-compatible bridge support"
	depends on PCI
	depends on PCI
	select CARDBUS if !EMBEDDED
	select CARDBUS if !EMBEDDED
	select PCCARD_NONSTATIC
	select PCCARD_NONSTATIC if PCMCIA != n
	---help---
	---help---
	  This option enables support for CardBus host bridges.  Virtually
	  This option enables support for CardBus host bridges.  Virtually
	  all modern PCMCIA bridges are CardBus compatible.  A "bridge" is
	  all modern PCMCIA bridges are CardBus compatible.  A "bridge" is
@@ -161,9 +161,8 @@ config TCIC


config PCMCIA_M8XX
config PCMCIA_M8XX
	tristate "MPC8xx PCMCIA support"
	tristate "MPC8xx PCMCIA support"
	depends on PCMCIA && PPC && 8xx
	depends on PCCARD && PPC && 8xx
	select PCCARD_IODYN
	select PCCARD_IODYN if PCMCIA != n
	select PCCARD_NONSTATIC
	help
	help
	  Say Y here to include support for PowerPC 8xx series PCMCIA
	  Say Y here to include support for PowerPC 8xx series PCMCIA
	  controller.
	  controller.
@@ -238,14 +237,12 @@ config PCMCIA_PROBE
config M32R_PCC
config M32R_PCC
	bool "M32R PCMCIA I/F"
	bool "M32R PCMCIA I/F"
	depends on M32R && CHIP_M32700 && PCMCIA
	depends on M32R && CHIP_M32700 && PCMCIA
	select PCCARD_NONSTATIC
	help
	help
	  Say Y here to use the M32R PCMCIA controller.
	  Say Y here to use the M32R PCMCIA controller.


config M32R_CFC
config M32R_CFC
	bool "M32R CF I/F Controller"
	bool "M32R CF I/F Controller"
	depends on M32R && (PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_MAPPI3 || PLAT_OPSPUT)
	depends on M32R && (PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_MAPPI3 || PLAT_OPSPUT)
	select PCCARD_NONSTATIC
	help
	help
	  Say Y here to use the M32R CompactFlash controller.
	  Say Y here to use the M32R CompactFlash controller.


+2 −2
Original line number Original line Diff line number Diff line
@@ -2,11 +2,11 @@
# Makefile for the kernel pcmcia subsystem (c/o David Hinds)
# Makefile for the kernel pcmcia subsystem (c/o David Hinds)
#
#


pcmcia_core-y					+= cs.o cistpl.o rsrc_mgr.o socket_sysfs.o
pcmcia_core-y					+= cs.o rsrc_mgr.o socket_sysfs.o
pcmcia_core-$(CONFIG_CARDBUS)			+= cardbus.o
pcmcia_core-$(CONFIG_CARDBUS)			+= cardbus.o
obj-$(CONFIG_PCCARD)				+= pcmcia_core.o
obj-$(CONFIG_PCCARD)				+= pcmcia_core.o


pcmcia-y					+= ds.o pcmcia_resource.o
pcmcia-y					+= ds.o pcmcia_resource.o cistpl.o
pcmcia-$(CONFIG_PCMCIA_IOCTL)			+= pcmcia_ioctl.o
pcmcia-$(CONFIG_PCMCIA_IOCTL)			+= pcmcia_ioctl.o
obj-$(CONFIG_PCMCIA)				+= pcmcia.o
obj-$(CONFIG_PCMCIA)				+= pcmcia.o


Loading