|
@@ -0,0 +1,92 @@
|
|
|
+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
|
|
|
+
|
|
|
+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 are on their own to provide proper locking.
|
|
|
+
|
|
|
+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;
|