215 /* Client path failover callback */ |
218 /* Client path failover callback */ |
216 int (*vo_failover)(dev_info_t *vdip, dev_info_t *cdip, int flags); |
219 int (*vo_failover)(dev_info_t *vdip, dev_info_t *cdip, int flags); |
217 } mdi_vhci_ops_t; |
220 } mdi_vhci_ops_t; |
218 |
221 |
219 /* |
222 /* |
220 * phci bus config structure - one for for each phci bus config operation that |
|
221 * we initiate on behalf of a vhci. |
|
222 */ |
|
223 typedef struct mdi_phci_config { |
|
224 struct mdi_vhci_config *phc_vhc; /* vhci bus config */ |
|
225 struct mdi_phci_config *phc_next; /* next one on this list */ |
|
226 dev_info_t *phc_parent_dip; /* parent of the phci */ |
|
227 char phc_devnm[MAXNAMELEN]; /* /name@addr of the phci */ |
|
228 } mdi_phci_config_t; |
|
229 |
|
230 /* vhci bus config structure - one for vhci instance */ |
|
231 typedef struct mdi_vhci_config { |
|
232 volatile ddi_bus_config_op_t vhc_op; /* bus config - op type */ |
|
233 major_t vhc_major; /* bus config - major */ |
|
234 int vhc_flags; /* bus config - flags */ |
|
235 volatile int64_t vhc_start_time; /* bus config start time */ |
|
236 int64_t vhc_cutoff_time; /* end time + some timeout */ |
|
237 taskq_t *vhc_taskq; |
|
238 kcondvar_t vhc_cv; /* mutex is mdi_mutex */ |
|
239 mdi_phci_config_t *vhc_phc; /* phci bus config list */ |
|
240 int vhc_phc_cnt; /* # of phcs on vhc_phc list */ |
|
241 } mdi_vhci_config_t; |
|
242 |
|
243 /* |
|
244 * An mdi_vhci structure is created and bound to the devinfo node of every |
223 * An mdi_vhci structure is created and bound to the devinfo node of every |
245 * registered vHCI class driver; this happens when a vHCI registers itself from |
224 * registered vHCI class driver; this happens when a vHCI registers itself from |
246 * attach(9e). This structure is unbound and freed when the vHCI unregisters |
225 * attach(9e). This structure is unbound and freed when the vHCI unregisters |
247 * at detach(9e) time; |
226 * at detach(9e) time; |
248 * |
227 * |
899 |
879 |
900 #define MDI_PI_IS_SUSPENDED(pip) \ |
880 #define MDI_PI_IS_SUSPENDED(pip) \ |
901 ((MDI_PI(pip))->pi_phci->ph_flags & MDI_PHCI_FLAGS_SUSPEND) |
881 ((MDI_PI(pip))->pi_phci->ph_flags & MDI_PHCI_FLAGS_SUSPEND) |
902 |
882 |
903 /* |
883 /* |
|
884 * mdi_vhcache_client, mdi_vhcache_pathinfo, and mdi_vhcache_phci structures |
|
885 * hold the vhci to phci client mappings of the on-disk vhci busconfig cache. |
|
886 */ |
|
887 |
|
888 /* phci structure of vhci cache */ |
|
889 typedef struct mdi_vhcache_phci { |
|
890 char *cphci_path; /* phci path name */ |
|
891 uint32_t cphci_id; /* used when building nvlist */ |
|
892 mdi_phci_t *cphci_phci; /* pointer to actual phci */ |
|
893 struct mdi_vhcache_phci *cphci_next; /* next in vhci phci list */ |
|
894 } mdi_vhcache_phci_t; |
|
895 |
|
896 /* pathinfo structure of vhci cache */ |
|
897 typedef struct mdi_vhcache_pathinfo { |
|
898 char *cpi_addr; /* path address */ |
|
899 mdi_vhcache_phci_t *cpi_cphci; /* phci the path belongs to */ |
|
900 struct mdi_pathinfo *cpi_pip; /* ptr to actual pathinfo */ |
|
901 uint32_t cpi_flags; /* see below */ |
|
902 struct mdi_vhcache_pathinfo *cpi_next; /* next path for the client */ |
|
903 } mdi_vhcache_pathinfo_t; |
|
904 |
|
905 /* |
|
906 * cpi_flags |
|
907 * |
|
908 * MDI_CPI_HINT_PATH_DOES_NOT_EXIST - set when configuration of the path has |
|
909 * failed. |
|
910 */ |
|
911 #define MDI_CPI_HINT_PATH_DOES_NOT_EXIST 0x0001 |
|
912 |
|
913 /* client structure of vhci cache */ |
|
914 typedef struct mdi_vhcache_client { |
|
915 char *cct_name_addr; /* client address */ |
|
916 mdi_vhcache_pathinfo_t *cct_cpi_head; /* client's path list head */ |
|
917 mdi_vhcache_pathinfo_t *cct_cpi_tail; /* client's path list tail */ |
|
918 struct mdi_vhcache_client *cct_next; /* next in vhci client list */ |
|
919 } mdi_vhcache_client_t; |
|
920 |
|
921 /* vhci cache structure - one for vhci instance */ |
|
922 typedef struct mdi_vhci_cache { |
|
923 mdi_vhcache_phci_t *vhcache_phci_head; /* phci list head */ |
|
924 mdi_vhcache_phci_t *vhcache_phci_tail; /* phci list tail */ |
|
925 mdi_vhcache_client_t *vhcache_client_head; /* client list head */ |
|
926 mdi_vhcache_client_t *vhcache_client_tail; /* client list tail */ |
|
927 mod_hash_t *vhcache_client_hash; /* client hash */ |
|
928 int vhcache_flags; /* see below */ |
|
929 int64_t vhcache_clean_time; /* last clean time */ |
|
930 krwlock_t vhcache_lock; /* cache lock */ |
|
931 } mdi_vhci_cache_t; |
|
932 |
|
933 /* vhcache_flags */ |
|
934 #define MDI_VHCI_CACHE_SETUP_DONE 0x0001 /* cache setup completed */ |
|
935 |
|
936 typedef struct mdi_phci_driver_info { |
|
937 char *phdriver_name; /* name of the phci driver */ |
|
938 |
|
939 /* set to non zero if the phci driver supports root device */ |
|
940 int phdriver_root_support; |
|
941 } mdi_phci_driver_info_t; |
|
942 |
|
943 /* vhci bus config structure - one for vhci instance */ |
|
944 typedef struct mdi_vhci_config { |
|
945 char *vhc_vhcache_filename; /* on-disk file name */ |
|
946 mdi_vhci_cache_t vhc_vhcache; /* vhci cache */ |
|
947 mdi_phci_driver_info_t *vhc_phci_driver_list; /* ph drv info array */ |
|
948 int vhc_nphci_drivers; /* # of phci drivers */ |
|
949 kmutex_t vhc_lock; /* vhci config lock */ |
|
950 kcondvar_t vhc_cv; |
|
951 int vhc_flags; /* see below */ |
|
952 |
|
953 /* flush vhci cache when lbolt reaches vhc_flush_at_ticks */ |
|
954 clock_t vhc_flush_at_ticks; |
|
955 |
|
956 /* |
|
957 * Head and tail of the client list whose paths are being configured |
|
958 * asynchronously. vhc_acc_count is the number of clients on this list. |
|
959 * vhc_acc_thrcount is the number threads running to configure |
|
960 * the paths for these clients. |
|
961 */ |
|
962 struct mdi_async_client_config *vhc_acc_list_head; |
|
963 struct mdi_async_client_config *vhc_acc_list_tail; |
|
964 int vhc_acc_count; |
|
965 int vhc_acc_thrcount; |
|
966 |
|
967 /* callback id - for flushing the cache during system shutdown */ |
|
968 callb_id_t vhc_cbid; |
|
969 } mdi_vhci_config_t; |
|
970 |
|
971 /* vhc_flags */ |
|
972 #define MDI_VHC_SINGLE_THREADED 0x0001 /* config single threaded */ |
|
973 #define MDI_VHC_EXIT 0x0002 /* exit all config activity */ |
|
974 #define MDI_VHC_VHCACHE_DIRTY 0x0004 /* cache dirty */ |
|
975 #define MDI_VHC_VHCACHE_FLUSH_THREAD 0x0008 /* cache flush thead running */ |
|
976 #define MDI_VHC_VHCACHE_FLUSH_ERROR 0x0010 /* failed to flush cache */ |
|
977 #define MDI_VHC_READONLY_FS 0x0020 /* filesys is readonly */ |
|
978 #define MDI_VHC_BUILD_VHCI_CACHE_THREAD 0x0040 /* cachebuild thread running */ |
|
979 |
|
980 typedef struct mdi_phys_path { |
|
981 char *phys_path; |
|
982 struct mdi_phys_path *phys_path_next; |
|
983 } mdi_phys_path_t; |
|
984 |
|
985 /* |
|
986 * Lookup tokens are used to cache the result of the vhci cache client lookup |
|
987 * operations (to reduce the number of real lookup operations). |
|
988 */ |
|
989 typedef struct mdi_vhcache_lookup_token { |
|
990 mdi_vhcache_client_t *lt_cct; /* vhcache client */ |
|
991 int64_t lt_cct_lookup_time; /* last lookup time */ |
|
992 } mdi_vhcache_lookup_token_t; |
|
993 |
|
994 /* asynchronous configuration of client paths */ |
|
995 typedef struct mdi_async_client_config { |
|
996 char *acc_ct_name; /* client name */ |
|
997 char *acc_ct_addr; /* client address */ |
|
998 mdi_phys_path_t *acc_phclient_path_list_head; /* path head */ |
|
999 mdi_vhcache_lookup_token_t acc_token; /* lookup token */ |
|
1000 struct mdi_async_client_config *acc_next; /* next in vhci acc list */ |
|
1001 } mdi_async_client_config_t; |
|
1002 |
|
1003 /* |
904 * vHCI driver instance registration/unregistration |
1004 * vHCI driver instance registration/unregistration |
905 * |
1005 * |
906 * mdi_vhci_register() is called by a vHCI driver to register itself as the |
1006 * mdi_vhci_register() is called by a vHCI driver to register itself as the |
907 * manager of devices from a particular 'class'. This should be called from |
1007 * manager of devices from a particular 'class'. This should be called from |
908 * attach(9e). |
1008 * attach(9e). |