Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

=======
Locking
=======

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_device 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;