2010/11/17 Pei Lin <telent997@xxxxxxxxx> > > 2010/11/17 Dave Hylands <dhylands@xxxxxxxxx>: > > Hi lalith, > > > > On Tue, Nov 16, 2010 at 12:19 AM, laliteshwar yadav <lalit4294@xxxxxxxxx> wrote: > >> how probe function works? > >> > >> how is it getting called? > >> > >> after registering the device driver who is the first function to call it.. > > > > There are 2 things required for the probe function to be called: a > > device and a driver. > > > > Normally, the architecture portion of the kernel registers devices for > > all of the device that it has. > > Then when you register a driver, it will detect if a device with a > > matching name has been registered. If it finds a match, it will call > > the probe routine. > > > > I normally work with linux in an embedded environment (ARM and MIPS), > > not programming for linux under x86, so its possible that things > > happen a little differently in that environment. > > > > Dave gave the good explanation. > In linux world, codes show everything. > codes: > /* Structure for a device driver */ > static struct platform_driver gfar_driver = { > .probe = gfar_probe, > .remove = gfar_remove, > .driver = { > .name = "fsl-gianfar", > }, > }; > > > 1987 static int __init gfar_init(void) > 1988 { > 1989 int err = gfar_mdio_init(); > 1990 > 1991 if (err) > 1992 return err; > 1993 > 1994 err = platform_driver_register(&gfar_driver); > 1995 > 1996 if (err) > 1997 gfar_mdio_exit(); > 1998 > 1999 return err; > 2000 } > > > 443 int platform_driver_register(struct platform_driver *drv) > 444 { > 445 drv->driver.bus = &platform_bus_type; > 446 if (drv->probe) > 447 drv->driver.probe = platform_drv_probe; > 448 if (drv->remove) > 449 drv->driver.remove = platform_drv_remove; > 450 if (drv->shutdown) > 451 drv->driver.shutdown = platform_drv_shutdown; > 452 if (drv->suspend) > 453 drv->driver.suspend = platform_drv_suspend; > 454 if (drv->resume) > 455 drv->driver.resume = platform_drv_resume; > 456 return driver_register(&drv->driver); > 457 } > > 217 int driver_register(struct device_driver *drv) > 218 { > 219 int ret; > 220 > 221 if ((drv->bus->probe && drv->probe) || > 222 (drv->bus->remove && drv->remove) || > 223 (drv->bus->shutdown && drv->shutdown)) > 224 printk(KERN_WARNING "Driver '%s' needs updating - > please use " > 225 "bus_type methods\n", drv->name); > 226 ret = bus_add_driver(drv); > 227 if (ret) > 228 return ret; > 229 ret = driver_add_groups(drv, drv->groups); > 230 if (ret) > 231 bus_remove_driver(drv); > 232 return ret; > 233 } > 532 int bus_add_driver(struct device_driver * drv) 533 { 534 struct bus_type * bus = get_bus(drv->bus); 535 int error = 0; 536 537 if (bus) { 538 pr_debug("bus %s: add driver %s\n", bus->name, drv->name); 539 error = kobject_set_name(&drv->kobj, "%s", drv->name); 540 if (error) { 541 put_bus(bus); 542 return error; 543 } 544 drv->kobj.kset = &bus->drivers; 545 if ((error = kobject_register(&drv->kobj))) { 546 put_bus(bus); 547 return error; 548 } 549 550 down_write(&bus->subsys.rwsem); 551 driver_attach(drv); 552 up_write(&bus->subsys.rwsem); 553 module_add_driver(drv->owner, drv); 554 555 driver_add_attrs(bus, drv); 556 } 557 return error; 558 } 353 void driver_attach(struct device_driver * drv) 354 { 355 struct bus_type * bus = drv->bus; 356 struct list_head * entry; 357 int error; 358 359 if (!bus->match) 360 return; 361 362 list_for_each(entry, &bus->devices.list) { 363 struct device * dev = container_of(entry, struct device, bus_list); 364 if (!dev->driver) { 365 error = driver_probe_device(drv, dev); 366 if (error && (error != -ENODEV)) 367 /* driver matched but the probe failed */ 368 printk(KERN_WARNING 369 "%s: probe of %s failed with error %d\n", 370 drv->name, dev->bus_id, error); 371 } 372 } 373 } 284 int driver_probe_device(struct device_driver * drv, struct device * dev) 285 { 286 if (drv->bus->match && !drv->bus->match(dev, drv)) 287 return -ENODEV; 288 289 dev->driver = drv; 290 if (drv->probe) { 291 int error = drv->probe(dev); 292 if (error) { 293 dev->driver = NULL; 294 return error; 295 } 296 } 297 298 device_bind_driver(dev); 299 return 0; 300 } > > > -- > > Dave Hylands > > Shuswap, BC, Canada > > http://www.DaveHylands.com/ > > > > -- > > To unsubscribe from this list: send an email with > > "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx > > Please read the FAQ at http://kernelnewbies.org/FAQ > > > > > > > > -- > Best Regards > Lin -- Best Regards Lin -- To unsubscribe from this list: send an email with "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ