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