Diff for /src/sys/kern/subr_bus.c between versions 1.16 and 1.17

version 1.16, 2004/04/01 08:41:24 version 1.17, 2004/04/15 13:31:41
Line 107  DEFINE_CLASS(null, null_methods, 0); Line 107  DEFINE_CLASS(null, null_methods, 0);
 static devclass_list_t devclasses = TAILQ_HEAD_INITIALIZER(devclasses);  static devclass_list_t devclasses = TAILQ_HEAD_INITIALIZER(devclasses);
   
 static devclass_t  static devclass_t
 devclass_find_internal(const char *classname, int create)  devclass_find_internal(const char *classname, const char *parentname,
                          int create)
 {  {
         devclass_t dc;          devclass_t dc;
   
Line 117  devclass_find_internal(const char *class Line 118  devclass_find_internal(const char *class
   
         TAILQ_FOREACH(dc, &devclasses, link)          TAILQ_FOREACH(dc, &devclasses, link)
                 if (!strcmp(dc->name, classname))                  if (!strcmp(dc->name, classname))
                         return(dc);                          break;
   
         PDEBUG(("%s not found%s", classname, (create? ", creating": "")));          if (create && !dc) {
         if (create) {                  PDEBUG(("creating %s", classname));
                 dc = malloc(sizeof(struct devclass) + strlen(classname) + 1,                  dc = malloc(sizeof(struct devclass) + strlen(classname) + 1,
                             M_BUS, M_INTWAIT | M_ZERO);                              M_BUS, M_INTWAIT | M_ZERO);
                 if (!dc)                  if (!dc)
                         return NULL;                          return(NULL);
                   dc->parent = NULL;
                 dc->name = (char*) (dc + 1);                  dc->name = (char*) (dc + 1);
                 strcpy(dc->name, classname);                  strcpy(dc->name, classname);
                 dc->devices = NULL;                  dc->devices = NULL;
Line 132  devclass_find_internal(const char *class Line 134  devclass_find_internal(const char *class
                 TAILQ_INIT(&dc->drivers);                  TAILQ_INIT(&dc->drivers);
                 TAILQ_INSERT_TAIL(&devclasses, dc, link);                  TAILQ_INSERT_TAIL(&devclasses, dc, link);
         }          }
           if (parentname && dc && !dc->parent)
                   dc->parent = devclass_find_internal(parentname, NULL, FALSE);
   
         return(dc);          return(dc);
 }  }
Line 139  devclass_find_internal(const char *class Line 143  devclass_find_internal(const char *class
 devclass_t  devclass_t
 devclass_create(const char *classname)  devclass_create(const char *classname)
 {  {
         return(devclass_find_internal(classname, TRUE));          return(devclass_find_internal(classname, NULL, TRUE));
 }  }
   
 devclass_t  devclass_t
 devclass_find(const char *classname)  devclass_find(const char *classname)
 {  {
         return(devclass_find_internal(classname, FALSE));          return(devclass_find_internal(classname, NULL, FALSE));
 }  }
   
 int  int
Line 171  devclass_add_driver(devclass_t dc, drive Line 175  devclass_add_driver(devclass_t dc, drive
         /*          /*
          * Make sure the devclass which the driver is implementing exists.           * Make sure the devclass which the driver is implementing exists.
          */           */
         devclass_find_internal(driver->name, TRUE);          devclass_find_internal(driver->name, NULL, TRUE);
   
         dl->driver = driver;          dl->driver = driver;
         TAILQ_INSERT_TAIL(&dc->drivers, dl, link);          TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
Line 256  devclass_find_driver_internal(devclass_t Line 260  devclass_find_driver_internal(devclass_t
         return(NULL);          return(NULL);
 }  }
   
 driver_t *  kobj_class_t
 devclass_find_driver(devclass_t dc, const char *classname)  devclass_find_driver(devclass_t dc, const char *classname)
 {  {
         driverlink_t dl;          driverlink_t dl;
Line 329  devclass_get_maxunit(devclass_t dc) Line 333  devclass_get_maxunit(devclass_t dc)
         return(dc->maxunit);          return(dc->maxunit);
 }  }
   
   void
   devclass_set_parent(devclass_t dc, devclass_t pdc)
   {
           dc->parent = pdc;
   }
   
   devclass_t
   devclass_get_parent(devclass_t dc)
   {
           return(dc->parent);
   }
   
 static int  static int
 devclass_alloc_unit(devclass_t dc, int *unitp)  devclass_alloc_unit(devclass_t dc, int *unitp)
 {  {
Line 441  make_device(device_t parent, const char Line 457  make_device(device_t parent, const char
         PDEBUG(("%s at %s as unit %d", name, DEVICENAME(parent), unit));          PDEBUG(("%s at %s as unit %d", name, DEVICENAME(parent), unit));
   
         if (name != NULL) {          if (name != NULL) {
                 dc = devclass_find_internal(name, TRUE);                  dc = devclass_find_internal(name, NULL, TRUE);
                 if (!dc) {                  if (!dc) {
                         printf("make_device: can't find device class %s\n", name);                          printf("make_device: can't find device class %s\n", name);
                         return(NULL);                          return(NULL);
Line 619  device_probe_child(device_t dev, device_ Line 635  device_probe_child(device_t dev, device_
         if (child->state == DS_ALIVE)          if (child->state == DS_ALIVE)
                 return(0);                  return(0);
   
         for (dl = first_matching_driver(dc, child); dl;          for (; dc; dc = dc->parent) {
              dl = next_matching_driver(dc, child, dl)) {                  for (dl = first_matching_driver(dc, child); dl;
                 PDEBUG(("Trying %s", DRIVERNAME(dl->driver)));                       dl = next_matching_driver(dc, child, dl)) {
                 device_set_driver(child, dl->driver);                          PDEBUG(("Trying %s", DRIVERNAME(dl->driver)));
                 if (!hasclass)                          device_set_driver(child, dl->driver);
                         device_set_devclass(child, dl->driver->name);                          if (!hasclass)
                 result = DEVICE_PROBE(child);                                  device_set_devclass(child, dl->driver->name);
                 if (!hasclass)                          result = DEVICE_PROBE(child);
                         device_set_devclass(child, 0);                          if (!hasclass)
                                   device_set_devclass(child, 0);
   
                 /*                          /*
                  * If the driver returns SUCCESS, there can be no higher match                           * If the driver returns SUCCESS, there can be
                  * for this device.                           * no higher match for this device.
                  */                           */
                 if (result == 0) {                          if (result == 0) {
                         best = dl;                                  best = dl;
                         pri = 0;                                  pri = 0;
                         break;                                  break;
                 }                          }
   
                 /*                          /*
                  * The driver returned an error so it certainly doesn't match.                           * The driver returned an error so it
                  */                           * certainly doesn't match.
                 if (result > 0) {                           */
                         device_set_driver(child, 0);                          if (result > 0) {
                         continue;                                  device_set_driver(child, 0);
                 }                                  continue;
                           }
   
                           /*
                            * A priority lower than SUCCESS, remember the
                            * best matching driver. Initialise the value
                            * of pri for the first match.
                            */
                           if (best == 0 || result > pri) {
                                   best = dl;
                                   pri = result;
                                   continue;
                           }
                   }
                 /*                  /*
                  * A priority lower than SUCCESS, remember the best matching                   * If we have unambiguous match in this devclass,
                  * driver. Initialise the value of pri for the first match.                   * don't look in the parent.
                  */                   */
                 if (best == 0 || result > pri) {                  if (best && pri == 0)
                         best = dl;                          break;
                         pri = result;  
                         continue;  
                 }  
         }          }
   
         /*          /*
Line 959  device_set_devclass(device_t dev, const Line 985  device_set_devclass(device_t dev, const
                 return(EINVAL);                  return(EINVAL);
         }          }
   
         dc = devclass_find_internal(classname, TRUE);          dc = devclass_find_internal(classname, NULL, TRUE);
         if (!dc)          if (!dc)
                 return(ENOMEM);                  return(ENOMEM);
   
Line 2254  root_bus_module_handler(module_t mod, in Line 2280  root_bus_module_handler(module_t mod, in
                 kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver);                  kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver);
                 root_bus->driver = &root_driver;                  root_bus->driver = &root_driver;
                 root_bus->state = DS_ATTACHED;                  root_bus->state = DS_ATTACHED;
                 root_devclass = devclass_find_internal("root", FALSE);                  root_devclass = devclass_find_internal("root", NULL, FALSE);
                 return(0);                  return(0);
   
         case MOD_SHUTDOWN:          case MOD_SHUTDOWN:
Line 2286  root_bus_configure(void) Line 2312  root_bus_configure(void)
 int  int
 driver_module_handler(module_t mod, int what, void *arg)  driver_module_handler(module_t mod, int what, void *arg)
 {  {
         int error, i;          int error;
         struct driver_module_data *dmd;          struct driver_module_data *dmd;
         devclass_t bus_devclass;          devclass_t bus_devclass;
           kobj_class_t driver;
           const char *parentname;
   
         dmd = (struct driver_module_data *)arg;          dmd = (struct driver_module_data *)arg;
         bus_devclass = devclass_find_internal(dmd->dmd_busname, TRUE);          bus_devclass = devclass_find_internal(dmd->dmd_busname, NULL, TRUE);
         error = 0;          error = 0;
   
         switch (what) {          switch (what) {
Line 2299  driver_module_handler(module_t mod, int Line 2327  driver_module_handler(module_t mod, int
                 if (dmd->dmd_chainevh)                  if (dmd->dmd_chainevh)
                         error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);                          error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
   
                 for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {                  driver = dmd->dmd_driver;
                         PDEBUG(("Loading module: driver %s on bus %s",                  PDEBUG(("Loading module: driver %s on bus %s",
                                 DRIVERNAME(dmd->dmd_drivers[i]),                           DRIVERNAME(driver), dmd->dmd_busname));
                                 dmd->dmd_busname));                  error = devclass_add_driver(bus_devclass, driver);
                         error = devclass_add_driver(bus_devclass,  
                                                     dmd->dmd_drivers[i]);  
                 }  
                 if (error)                  if (error)
                         break;                          break;
   
                 /*                  /*
                  * The drivers loaded in this way are assumed to all                   * If the driver has any base classes, make the
                  * implement the same devclass.                   * devclass inherit from the devclass of the driver's
                    * first base class. This will allow the system to
                    * search for drivers in both devclasses for children
                    * of a device using this driver.
                  */                   */
                 *dmd->dmd_devclass =                  if (driver->baseclasses)
                         devclass_find_internal(dmd->dmd_drivers[0]->name,                          parentname = driver->baseclasses[0]->name;
                                                TRUE);                  else
                           parentname = NULL;
                   *dmd->dmd_devclass = devclass_find_internal(driver->name,
                                                               parentname, TRUE);
                 break;                  break;
   
         case MOD_UNLOAD:          case MOD_UNLOAD:
                 for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {                  PDEBUG(("Unloading module: driver %s from bus %s",
                         PDEBUG(("Unloading module: driver %s from bus %s",                          DRIVERNAME(dmd->dmd_driver), dmd->dmd_busname));
                                 DRIVERNAME(dmd->dmd_drivers[i]),                   error = devclass_delete_driver(bus_devclass, dmd->dmd_driver);
                                 dmd->dmd_busname));  
                         error = devclass_delete_driver(bus_devclass,  
                                                        dmd->dmd_drivers[i]);  
                 }  
   
                 if (!error && dmd->dmd_chainevh)                  if (!error && dmd->dmd_chainevh)
                         error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);                          error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);

Removed from v.1.16  
changed lines
  Added in v.1.17