Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Revert "parport: daisy: use new parport device model"

This reverts commit 1aec4211204d9463d1fd209eb50453de16254599.

Steven Rostedt reports that it causes a hang at bootup and bisected it
to this commit.

The troigger is apparently a module alias for "parport_lowlevel" that
points to "parport_pc", which causes a hang with

modprobe -q -- parport_lowlevel

blocking forever with a backtrace like this:

wait_for_completion_killable+0x1c/0x28
call_usermodehelper_exec+0xa7/0x108
__request_module+0x351/0x3d8
get_lowlevel_driver+0x28/0x41 [parport]
__parport_register_driver+0x39/0x1f4 [parport]
daisy_drv_init+0x31/0x4f [parport]
parport_bus_init+0x5d/0x7b [parport]
parport_default_proc_register+0x26/0x1000 [parport]
do_one_initcall+0xc2/0x1e0
do_init_module+0x50/0x1d4
load_module+0x1c2e/0x21b3
sys_init_module+0xef/0x117

Supid says:
"Due to the new device model daisy driver will now try to find the
parallel ports while trying to register its driver so that it can bind
with them. Now, since daisy driver is loaded while parport bus is
initialising the list of parport is still empty and it tries to load
the lowlevel driver, which has an alias set to parport_pc, now causes
a deadlock"

But I don't think the daisy driver should be loaded by the parport
initialization in the first place, so let's revert the whole change.

If the daisy driver can just initialize separately on its own (like a
driver should), instead of hooking into the parport init sequence
directly, this issue probably would go away.

Reported-and-bisected-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Reported-by: Michal Kubecek <mkubecek@suse.cz>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

+3 -54
+1 -31
drivers/parport/daisy.c
··· 213 213 struct pardevice *parport_open(int devnum, const char *name) 214 214 { 215 215 struct daisydev *p = topology; 216 - struct pardev_cb par_cb; 217 216 struct parport *port; 218 217 struct pardevice *dev; 219 218 int daisy; 220 219 221 - memset(&par_cb, 0, sizeof(par_cb)); 222 220 spin_lock(&topology_lock); 223 221 while (p && p->devnum != devnum) 224 222 p = p->next; ··· 230 232 port = parport_get_port(p->port); 231 233 spin_unlock(&topology_lock); 232 234 233 - dev = parport_register_dev_model(port, name, &par_cb, devnum); 235 + dev = parport_register_device(port, name, NULL, NULL, NULL, 0, NULL); 234 236 parport_put_port(port); 235 237 if (!dev) 236 238 return NULL; ··· 479 481 480 482 kfree(deviceid); 481 483 return detected; 482 - } 483 - 484 - static int daisy_drv_probe(struct pardevice *par_dev) 485 - { 486 - struct device_driver *drv = par_dev->dev.driver; 487 - 488 - if (strcmp(drv->name, "daisy_drv")) 489 - return -ENODEV; 490 - if (strcmp(par_dev->name, daisy_dev_name)) 491 - return -ENODEV; 492 - 493 - return 0; 494 - } 495 - 496 - static struct parport_driver daisy_driver = { 497 - .name = "daisy_drv", 498 - .probe = daisy_drv_probe, 499 - .devmodel = true, 500 - }; 501 - 502 - int daisy_drv_init(void) 503 - { 504 - return parport_register_driver(&daisy_driver); 505 - } 506 - 507 - void daisy_drv_exit(void) 508 - { 509 - parport_unregister_driver(&daisy_driver); 510 484 }
+1 -1
drivers/parport/probe.c
··· 257 257 ssize_t parport_device_id (int devnum, char *buffer, size_t count) 258 258 { 259 259 ssize_t retval = -ENXIO; 260 - struct pardevice *dev = parport_open(devnum, daisy_dev_name); 260 + struct pardevice *dev = parport_open (devnum, "Device ID probe"); 261 261 if (!dev) 262 262 return -ENXIO; 263 263
+1 -9
drivers/parport/share.c
··· 137 137 138 138 int parport_bus_init(void) 139 139 { 140 - int retval; 141 - 142 - retval = bus_register(&parport_bus_type); 143 - if (retval) 144 - return retval; 145 - daisy_drv_init(); 146 - 147 - return 0; 140 + return bus_register(&parport_bus_type); 148 141 } 149 142 150 143 void parport_bus_exit(void) 151 144 { 152 - daisy_drv_exit(); 153 145 bus_unregister(&parport_bus_type); 154 146 } 155 147
-13
include/linux/parport.h
··· 460 460 void *, size_t, int); 461 461 462 462 /* IEEE1284.3 functions */ 463 - #define daisy_dev_name "Device ID probe" 464 463 extern int parport_daisy_init (struct parport *port); 465 464 extern void parport_daisy_fini (struct parport *port); 466 465 extern struct pardevice *parport_open (int devnum, const char *name); ··· 467 468 extern ssize_t parport_device_id (int devnum, char *buffer, size_t len); 468 469 extern void parport_daisy_deselect_all (struct parport *port); 469 470 extern int parport_daisy_select (struct parport *port, int daisy, int mode); 470 - 471 - #ifdef CONFIG_PARPORT_1284 472 - extern int daisy_drv_init(void); 473 - extern void daisy_drv_exit(void); 474 - #else 475 - static inline int daisy_drv_init(void) 476 - { 477 - return 0; 478 - } 479 - 480 - static inline void daisy_drv_exit(void) {} 481 - #endif 482 471 483 472 /* Lowlevel drivers _can_ call this support function to handle irqs. */ 484 473 static inline void parport_generic_irq(struct parport *port)