1*4882a593Smuzhiyun======= 2*4882a593SmuzhiyunLocking 3*4882a593Smuzhiyun======= 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunThis file explains the locking and exclusion scheme used in the PCCARD 6*4882a593Smuzhiyunand PCMCIA subsystems. 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun 9*4882a593SmuzhiyunA) Overview, Locking Hierarchy: 10*4882a593Smuzhiyun=============================== 11*4882a593Smuzhiyun 12*4882a593Smuzhiyunpcmcia_socket_list_rwsem 13*4882a593Smuzhiyun - protects only the list of sockets 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun- skt_mutex 16*4882a593Smuzhiyun - serializes card insert / ejection 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun - ops_mutex 19*4882a593Smuzhiyun - serializes socket operation 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun 22*4882a593SmuzhiyunB) Exclusion 23*4882a593Smuzhiyun============ 24*4882a593Smuzhiyun 25*4882a593SmuzhiyunThe following functions and callbacks to struct pcmcia_socket must 26*4882a593Smuzhiyunbe called with "skt_mutex" held:: 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun socket_detect_change() 29*4882a593Smuzhiyun send_event() 30*4882a593Smuzhiyun socket_reset() 31*4882a593Smuzhiyun socket_shutdown() 32*4882a593Smuzhiyun socket_setup() 33*4882a593Smuzhiyun socket_remove() 34*4882a593Smuzhiyun socket_insert() 35*4882a593Smuzhiyun socket_early_resume() 36*4882a593Smuzhiyun socket_late_resume() 37*4882a593Smuzhiyun socket_resume() 38*4882a593Smuzhiyun socket_suspend() 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun struct pcmcia_callback *callback 41*4882a593Smuzhiyun 42*4882a593SmuzhiyunThe following functions and callbacks to struct pcmcia_socket must 43*4882a593Smuzhiyunbe called with "ops_mutex" held:: 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun socket_reset() 46*4882a593Smuzhiyun socket_setup() 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun struct pccard_operations *ops 49*4882a593Smuzhiyun struct pccard_resource_ops *resource_ops; 50*4882a593Smuzhiyun 51*4882a593SmuzhiyunNote that send_event() and `struct pcmcia_callback *callback` must not be 52*4882a593Smuzhiyuncalled with "ops_mutex" held. 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun 55*4882a593SmuzhiyunC) Protection 56*4882a593Smuzhiyun============= 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun1. Global Data: 59*4882a593Smuzhiyun--------------- 60*4882a593Smuzhiyunstruct list_head pcmcia_socket_list; 61*4882a593Smuzhiyun 62*4882a593Smuzhiyunprotected by pcmcia_socket_list_rwsem; 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun2. Per-Socket Data: 66*4882a593Smuzhiyun------------------- 67*4882a593SmuzhiyunThe resource_ops and their data are protected by ops_mutex. 68*4882a593Smuzhiyun 69*4882a593SmuzhiyunThe "main" struct pcmcia_socket is protected as follows (read-only fields 70*4882a593Smuzhiyunor single-use fields not mentioned): 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun- by pcmcia_socket_list_rwsem:: 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun struct list_head socket_list; 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun- by thread_lock:: 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun unsigned int thread_events; 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun- by skt_mutex:: 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun u_int suspended_state; 83*4882a593Smuzhiyun void (*tune_bridge); 84*4882a593Smuzhiyun struct pcmcia_callback *callback; 85*4882a593Smuzhiyun int resume_status; 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun- by ops_mutex:: 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun socket_state_t socket; 90*4882a593Smuzhiyun u_int state; 91*4882a593Smuzhiyun u_short lock_count; 92*4882a593Smuzhiyun pccard_mem_map cis_mem; 93*4882a593Smuzhiyun void __iomem *cis_virt; 94*4882a593Smuzhiyun struct { } irq; 95*4882a593Smuzhiyun io_window_t io[]; 96*4882a593Smuzhiyun pccard_mem_map win[]; 97*4882a593Smuzhiyun struct list_head cis_cache; 98*4882a593Smuzhiyun size_t fake_cis_len; 99*4882a593Smuzhiyun u8 *fake_cis; 100*4882a593Smuzhiyun u_int irq_mask; 101*4882a593Smuzhiyun void (*zoom_video); 102*4882a593Smuzhiyun int (*power_hook); 103*4882a593Smuzhiyun u8 resource...; 104*4882a593Smuzhiyun struct list_head devices_list; 105*4882a593Smuzhiyun u8 device_count; 106*4882a593Smuzhiyun struct pcmcia_state; 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun3. Per PCMCIA-device Data: 110*4882a593Smuzhiyun-------------------------- 111*4882a593Smuzhiyun 112*4882a593SmuzhiyunThe "main" struct pcmcia_device is protected as follows (read-only fields 113*4882a593Smuzhiyunor single-use fields not mentioned): 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun- by pcmcia_socket->ops_mutex:: 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun struct list_head socket_device_list; 119*4882a593Smuzhiyun struct config_t *function_config; 120*4882a593Smuzhiyun u16 _irq:1; 121*4882a593Smuzhiyun u16 _io:1; 122*4882a593Smuzhiyun u16 _win:4; 123*4882a593Smuzhiyun u16 _locked:1; 124*4882a593Smuzhiyun u16 allow_func_id_match:1; 125*4882a593Smuzhiyun u16 suspended:1; 126*4882a593Smuzhiyun u16 _removed:1; 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun- by the PCMCIA driver:: 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun io_req_t io; 131*4882a593Smuzhiyun irq_req_t irq; 132*4882a593Smuzhiyun config_req_t conf; 133*4882a593Smuzhiyun window_handle_t win; 134