Documentation / pcmcia / locking.rst


Based on kernel version 6.8. Page generated on 2024-03-11 21:26 EST.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
=======
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;