Changeset deac215e in mainline for uspace/drv/infrastructure/rootvirt/rootvirt.c
- Timestamp:
- 2011-09-03T13:37:16Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8ff0bd2, a9abe5fc
- Parents:
- b29bb09
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/infrastructure/rootvirt/rootvirt.c
rb29bb09 rdeac215e 63 63 64 64 static int rootvirt_add_device(ddf_dev_t *dev); 65 static int rootvirt_dev_remove(ddf_dev_t *dev); 65 66 static int rootvirt_fun_online(ddf_fun_t *fun); 66 67 static int rootvirt_fun_offline(ddf_fun_t *fun); … … 68 69 static driver_ops_t rootvirt_ops = { 69 70 .add_device = &rootvirt_add_device, 71 .dev_remove = &rootvirt_dev_remove, 70 72 .fun_online = &rootvirt_fun_online, 71 73 .fun_offline = &rootvirt_fun_offline … … 77 79 }; 78 80 81 /* Device soft state */ 82 typedef struct { 83 ddf_dev_t *dev; 84 list_t functions; 85 } rootvirt_t; 86 87 /* Function soft state */ 88 typedef struct { 89 ddf_fun_t *fun; 90 link_t dev_link; 91 } rootvirt_fun_t; 92 93 static int instances = 0; 94 95 79 96 /** Add function to the virtual device. 80 97 * … … 83 100 * @return EOK on success or negative error code. 84 101 */ 85 static int rootvirt_add_fun(ddf_dev_t *vdev, virtual_function_t *vfun) 86 { 102 static int rootvirt_add_fun(rootvirt_t *rootvirt, virtual_function_t *vfun) 103 { 104 ddf_dev_t *vdev = rootvirt->dev; 87 105 ddf_fun_t *fun; 106 rootvirt_fun_t *rvfun; 88 107 int rc; 89 108 … … 97 116 } 98 117 118 rvfun = ddf_fun_data_alloc(fun, sizeof(rootvirt_fun_t)); 119 if (rvfun == NULL) { 120 ddf_msg(LVL_ERROR, "Failed allocating soft state for %s.", 121 vfun->name); 122 ddf_fun_destroy(fun); 123 return ENOMEM; 124 } 125 126 rvfun->fun = fun; 127 99 128 rc = ddf_fun_add_match_id(fun, vfun->match_id, 10); 100 129 if (rc != EOK) { … … 113 142 } 114 143 144 list_append(&rvfun->dev_link, &rootvirt->functions); 145 115 146 ddf_msg(LVL_NOTE, "Registered child device `%s'", vfun->name); 116 147 return EOK; 117 148 } 118 149 150 static int rootvirt_fun_remove(rootvirt_fun_t *rvfun) 151 { 152 int rc; 153 const char *name = rvfun->fun->name; 154 155 ddf_msg(LVL_DEBUG, "rootvirt_fun_remove('%s')", name); 156 rc = ddf_fun_offline(rvfun->fun); 157 if (rc != EOK) { 158 ddf_msg(LVL_ERROR, "Error offlining function '%s'.", name); 159 return rc; 160 } 161 162 rc = ddf_fun_unbind(rvfun->fun); 163 if (rc != EOK) { 164 ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.", name); 165 return rc; 166 } 167 168 list_remove(&rvfun->dev_link); 169 ddf_fun_destroy(rvfun->fun); 170 return EOK; 171 } 172 173 119 174 static int rootvirt_add_device(ddf_dev_t *dev) 120 175 { 121 static int instances = 0;176 rootvirt_t *rootvirt; 122 177 123 178 /* 124 179 * Allow only single instance of root virtual device. 125 180 */ 126 instances++; 127 if (instances > 1) { 181 if (++instances > 1) { 128 182 return ELIMIT; 129 183 } 130 184 131 185 ddf_msg(LVL_DEBUG, "add_device(handle=%d)", (int)dev->handle); 186 187 rootvirt = ddf_dev_data_alloc(dev, sizeof(rootvirt_t)); 188 if (rootvirt == NULL) 189 return ENOMEM; 190 191 rootvirt->dev = dev; 192 list_initialize(&rootvirt->functions); 132 193 133 194 /* … … 137 198 virtual_function_t *vfun = virtual_functions; 138 199 while (vfun->name != NULL) { 139 (void) rootvirt_add_fun( dev, vfun);200 (void) rootvirt_add_fun(rootvirt, vfun); 140 201 vfun++; 141 202 } 142 203 204 return EOK; 205 } 206 207 static int rootvirt_dev_remove(ddf_dev_t *dev) 208 { 209 rootvirt_t *rootvirt = (rootvirt_t *)dev->driver_data; 210 int rc; 211 212 while (!list_empty(&rootvirt->functions)) { 213 rootvirt_fun_t *rvfun = list_get_instance( 214 list_first(&rootvirt->functions), rootvirt_fun_t, 215 dev_link); 216 217 rc = rootvirt_fun_remove(rvfun); 218 if (rc != EOK) 219 return rc; 220 } 221 222 --instances; 143 223 return EOK; 144 224 }
Note:
See TracChangeset
for help on using the changeset viewer.