summaryrefslogtreecommitdiffstats
path: root/Documentation/pcmcia/locking.rst
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Documentation/pcmcia/locking.rst133
1 files changed, 133 insertions, 0 deletions
diff --git a/Documentation/pcmcia/locking.rst b/Documentation/pcmcia/locking.rst
new file mode 100644
index 000000000..e35257139
--- /dev/null
+++ b/Documentation/pcmcia/locking.rst
@@ -0,0 +1,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;