Changeset b25970f in mainline
- Timestamp:
- 2018-10-29T14:11:39Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 94ab1fe
- Parents:
- 184f2f8a
- git-author:
- Jiri Svoboda <jiri@…> (2018-10-28 22:10:25)
- git-committer:
- Jiri Svoboda <jiri@…> (2018-10-29 14:11:39)
- Location:
- uspace
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/isa/isa.c
r184f2f8a rb25970f 1 1 /* 2 * Copyright (c) 2018 Jiri Svoboda 2 3 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda4 4 * Copyright (c) 2011 Jan Vesely 5 5 * All rights reserved. … … 697 697 } 698 698 699 static errno_t isa_dev_add(ddf_dev_t *dev) 700 { 701 async_sess_t *sess; 699 static errno_t isa_read_pci_cfg(isa_bus_t *isa, async_sess_t *sess) 700 { 702 701 errno_t rc; 703 704 ddf_msg(LVL_DEBUG, "isa_dev_add, device handle = %d",705 (int) ddf_dev_get_handle(dev));706 707 isa_bus_t *isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));708 if (isa == NULL)709 return ENOMEM;710 711 fibril_mutex_initialize(&isa->mutex);712 isa->dev = dev;713 list_initialize(&isa->functions);714 715 sess = ddf_dev_parent_sess_get(dev);716 if (sess == NULL) {717 ddf_msg(LVL_ERROR, "isa_dev_add failed to connect to the "718 "parent driver.");719 return ENOENT;720 }721 702 722 703 rc = pci_config_space_read_16(sess, PCI_VENDOR_ID, &isa->pci_vendor_id); … … 733 714 return rc; 734 715 716 return EOK; 717 } 718 719 static errno_t isa_dev_add(ddf_dev_t *dev) 720 { 721 async_sess_t *sess; 722 errno_t rc; 723 724 ddf_msg(LVL_DEBUG, "isa_dev_add, device handle = %d", 725 (int) ddf_dev_get_handle(dev)); 726 727 isa_bus_t *isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t)); 728 if (isa == NULL) 729 return ENOMEM; 730 731 fibril_mutex_initialize(&isa->mutex); 732 isa->dev = dev; 733 list_initialize(&isa->functions); 734 735 sess = ddf_dev_parent_sess_get(dev); 736 if (sess == NULL) { 737 ddf_msg(LVL_ERROR, "isa_dev_add failed to connect to the " 738 "parent driver."); 739 return ENOENT; 740 } 741 742 rc = isa_read_pci_cfg(isa, sess); 743 if (rc != EOK) { 744 ddf_msg(LVL_NOTE, "Cannot read PCI config. Assuming ISA classic."); 745 isa->pci_vendor_id = 0; 746 isa->pci_device_id = 0; 747 isa->pci_class = BASE_CLASS_BRIDGE; 748 isa->pci_subclass = SUB_CLASS_BRIDGE_ISA; 749 } 750 735 751 rc = pio_window_get(sess, &isa->pio_win); 736 752 if (rc != EOK) { -
uspace/drv/bus/isa/isa.ma
r184f2f8a rb25970f 1 # Classic ISA 2 10 isa 3 1 4 # ISA bridge 2 5 10 pci/class=06&subclass=01 -
uspace/drv/platform/pc/pc.c
r184f2f8a rb25970f 1 1 /* 2 * Copyright (c) 2018 Jiri Svoboda 2 3 * Copyright (c) 2010 Lenka Trochtova 3 4 * All rights reserved. … … 93 94 }; 94 95 95 static pc_fun_t pci_data = {96 static pc_fun_t sys_data = { 96 97 .hw_resources = { 97 98 sizeof(pci_conf_regs) / sizeof(pci_conf_regs[0]), … … 151 152 static ddf_dev_ops_t pc_fun_ops; 152 153 153 static bool 154 pc_add_fun(ddf_dev_t *dev, const char *name, const char *str_match_id, 155 pc_fun_t *fun_proto) 156 { 157 ddf_msg(LVL_DEBUG, "Adding new function '%s'.", name); 158 154 static errno_t pc_add_sysbus(ddf_dev_t *dev) 155 { 159 156 ddf_fun_t *fnode = NULL; 160 157 errno_t rc; 161 158 159 ddf_msg(LVL_DEBUG, "Adding system bus."); 160 162 161 /* Create new device. */ 163 fnode = ddf_fun_create(dev, fun_inner, name); 164 if (fnode == NULL) 165 goto failure; 162 fnode = ddf_fun_create(dev, fun_inner, "sys"); 163 if (fnode == NULL) { 164 rc = ENOMEM; 165 goto error; 166 } 166 167 167 168 pc_fun_t *fun = ddf_fun_data_alloc(fnode, sizeof(pc_fun_t)); 168 *fun = *fun_proto;169 170 /* Add match ID */171 rc = ddf_fun_add_match_id(fnode, str_match_id, 100);169 *fun = sys_data; 170 171 /* Add match IDs */ 172 rc = ddf_fun_add_match_id(fnode, "intel_pci", 100); 172 173 if (rc != EOK) 173 goto failure; 174 goto error; 175 176 rc = ddf_fun_add_match_id(fnode, "isa", 10); 177 if (rc != EOK) 178 goto error; 174 179 175 180 /* Set provided operations to the device. */ … … 177 182 178 183 /* Register function. */ 179 if (ddf_fun_bind(fnode) != EOK) { 180 ddf_msg(LVL_ERROR, "Failed binding function %s.", name); 181 goto failure; 182 } 183 184 return true; 185 186 failure: 184 rc = ddf_fun_bind(fnode); 185 if (rc != EOK) { 186 ddf_msg(LVL_ERROR, "Failed binding system bus function."); 187 goto error; 188 } 189 190 return EOK; 191 192 error: 187 193 if (fnode != NULL) 188 194 ddf_fun_destroy(fnode); 189 195 190 ddf_msg(LVL_ERROR, "Failed adding function '%s'.", name); 191 192 return false; 193 } 194 195 static bool pc_add_functions(ddf_dev_t *dev) 196 { 197 return pc_add_fun(dev, "pci0", "intel_pci", &pci_data); 196 ddf_msg(LVL_ERROR, "Failed adding system bus."); 197 return rc; 198 } 199 200 static errno_t pc_add_functions(ddf_dev_t *dev) 201 { 202 errno_t rc; 203 204 rc = pc_add_sysbus(dev); 205 if (rc != EOK) 206 return rc; 207 208 return EOK; 198 209 } 199 210 … … 206 217 static errno_t pc_dev_add(ddf_dev_t *dev) 207 218 { 219 errno_t rc; 220 208 221 ddf_msg(LVL_DEBUG, "pc_dev_add, device handle = %d", 209 222 (int)ddf_dev_get_handle(dev)); 210 223 211 224 /* Register functions. */ 212 if (!pc_add_functions(dev)) { 225 rc = pc_add_functions(dev); 226 if (rc != EOK) { 213 227 ddf_msg(LVL_ERROR, "Failed to add functions for PC platform."); 228 return rc; 214 229 } 215 230 -
uspace/srv/devman/driver.c
r184f2f8a rb25970f 1 1 /* 2 * Copyright (c) 2018 Jiri Svoboda 2 3 * Copyright (c) 2010 Lenka Trochtova 3 4 * All rights reserved. … … 43 44 #include "devman.h" 44 45 #include "driver.h" 46 #include "fun.h" 45 47 #include "match.h" 48 #include "main.h" 49 50 static errno_t driver_reassign_fibril(void *); 46 51 47 52 /** … … 194 199 } 195 200 196 /** Lookup the best matching driver for the specified device in the list of 197 * drivers. 201 /** Lookup the next best matching driver for a device. 198 202 * 199 203 * A match between a device and a driver is found if one of the driver's match … … 203 207 * of the match between the device and the driver. 204 208 * 209 * If a driver is already assigned to the device (node->drv != NULL), 210 * we look for the next best driver. That is either the next driver with the 211 * same score in the list of drivers, or a driver with the next best score 212 * (greater than zero). 213 * 205 214 * @param drivers_list The list of drivers, where we look for the driver 206 215 * suitable for handling the device. … … 213 222 driver_t *best_drv = NULL; 214 223 int best_score = 0, score = 0; 224 int cur_score; 225 link_t *link; 226 driver_t *drv; 215 227 216 228 fibril_mutex_lock(&drivers_list->drivers_mutex); 217 229 230 if (node->drv != NULL) { 231 cur_score = get_match_score(node->drv, node); 232 233 link = list_next(&drv->drivers, &drivers_list->drivers); 234 235 /* 236 * Find next driver with score equal to the current. 237 */ 238 while (link != NULL) { 239 drv = list_get_instance(link, driver_t, drivers); 240 score = get_match_score(drv, node); 241 if (score == cur_score) { 242 /* Found it */ 243 fibril_mutex_unlock(&drivers_list->drivers_mutex); 244 return drv; 245 } 246 247 link = list_next(link, &drivers_list->drivers); 248 } 249 250 /* There is no driver with the same score */ 251 } else { 252 cur_score = INT_MAX; 253 } 254 255 /* 256 * Find driver with the next best score 257 */ 218 258 list_foreach(drivers_list->drivers, drivers, driver_t, drv) { 219 259 score = get_match_score(drv, node); 220 if (score > best_score ) {260 if (score > best_score && score < cur_score) { 221 261 best_score = score; 222 262 best_drv = drv; … … 225 265 226 266 fibril_mutex_unlock(&drivers_list->drivers_mutex); 227 228 267 return best_drv; 229 268 } … … 244 283 245 284 dev->drv = drv; 285 dev->passed_to_driver = false; 286 dev->state = DEVICE_NOT_INITIALIZED; 246 287 list_append(&dev->driver_devices, &drv->devices); 247 288 … … 415 456 416 457 add_device(driver, dev, tree); 458 459 /* Device probe failed, need to try next best driver */ 460 if (dev->state == DEVICE_NOT_PRESENT) { 461 fibril_mutex_lock(&driver->driver_mutex); 462 list_remove(&dev->driver_devices); 463 fibril_mutex_unlock(&driver->driver_mutex); 464 fid_t fid = fibril_create(driver_reassign_fibril, dev); 465 if (fid == 0) { 466 log_msg(LOG_DEFAULT, LVL_ERROR, 467 "Error creating fibril to assign driver."); 468 } 469 fibril_add_ready(fid); 470 } 417 471 418 472 dev_del_ref(dev); … … 519 573 dev_tree_t *tree) 520 574 { 575 driver_t *drv; 576 521 577 assert(dev != NULL); 522 578 assert(drivers_list != NULL); … … 524 580 525 581 /* 526 * Find the driver which is the most suitable for handlingthis device.582 * Find the next best driver for this device. 527 583 */ 528 driver_t *drv = find_best_match_driver(drivers_list, dev); 584 again: 585 drv = find_best_match_driver(drivers_list, dev); 529 586 if (drv == NULL) { 530 587 log_msg(LOG_DEFAULT, LVL_ERROR, "No driver found for device `%s'.", … … 545 602 546 603 /* Notify the driver about the new device. */ 547 if (is_running) 604 if (is_running) { 548 605 add_device(drv, dev, tree); 606 607 /* If the device probe failed, need to try next available driver */ 608 if (dev->state == DEVICE_NOT_PRESENT) 609 goto again; 610 } 549 611 550 612 fibril_mutex_lock(&drv->driver_mutex); … … 781 843 } 782 844 845 /** Try to find next available driver in a separate fibril. 846 * 847 * @param arg Device node (dev_node_t) 848 */ 849 static errno_t driver_reassign_fibril(void *arg) 850 { 851 dev_node_t *dev_node = (dev_node_t *) arg; 852 assign_driver(dev_node, &drivers_list, &device_tree); 853 854 /* Delete one reference we got from the caller. */ 855 dev_del_ref(dev_node); 856 return EOK; 857 } 858 783 859 /** @} 784 860 */
Note:
See TracChangeset
for help on using the changeset viewer.