diff options
Diffstat (limited to 'drivers/ide/ide-proc.c')
-rw-r--r-- | drivers/ide/ide-proc.c | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 4b1e43b4118b..4063d2c34e3d 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
@@ -307,17 +307,41 @@ static int proc_ide_read_driver | |||
307 | (char *page, char **start, off_t off, int count, int *eof, void *data) | 307 | (char *page, char **start, off_t off, int count, int *eof, void *data) |
308 | { | 308 | { |
309 | ide_drive_t *drive = (ide_drive_t *) data; | 309 | ide_drive_t *drive = (ide_drive_t *) data; |
310 | ide_driver_t *driver = drive->driver; | 310 | struct device *dev = &drive->gendev; |
311 | ide_driver_t *ide_drv; | ||
311 | int len; | 312 | int len; |
312 | 313 | ||
313 | if (driver) { | 314 | down_read(&dev->bus->subsys.rwsem); |
315 | if (dev->driver) { | ||
316 | ide_drv = container_of(dev->driver, ide_driver_t, gen_driver); | ||
314 | len = sprintf(page, "%s version %s\n", | 317 | len = sprintf(page, "%s version %s\n", |
315 | driver->name, driver->version); | 318 | dev->driver->name, ide_drv->version); |
316 | } else | 319 | } else |
317 | len = sprintf(page, "ide-default version 0.9.newide\n"); | 320 | len = sprintf(page, "ide-default version 0.9.newide\n"); |
321 | up_read(&dev->bus->subsys.rwsem); | ||
318 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 322 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); |
319 | } | 323 | } |
320 | 324 | ||
325 | static int ide_replace_subdriver(ide_drive_t *drive, const char *driver) | ||
326 | { | ||
327 | struct device *dev = &drive->gendev; | ||
328 | int ret = 1; | ||
329 | |||
330 | down_write(&dev->bus->subsys.rwsem); | ||
331 | device_release_driver(dev); | ||
332 | /* FIXME: device can still be in use by previous driver */ | ||
333 | strlcpy(drive->driver_req, driver, sizeof(drive->driver_req)); | ||
334 | device_attach(dev); | ||
335 | drive->driver_req[0] = 0; | ||
336 | if (dev->driver == NULL) | ||
337 | device_attach(dev); | ||
338 | if (dev->driver && !strcmp(dev->driver->name, driver)) | ||
339 | ret = 0; | ||
340 | up_write(&dev->bus->subsys.rwsem); | ||
341 | |||
342 | return ret; | ||
343 | } | ||
344 | |||
321 | static int proc_ide_write_driver | 345 | static int proc_ide_write_driver |
322 | (struct file *file, const char __user *buffer, unsigned long count, void *data) | 346 | (struct file *file, const char __user *buffer, unsigned long count, void *data) |
323 | { | 347 | { |
@@ -488,16 +512,32 @@ void destroy_proc_ide_interface(ide_hwif_t *hwif) | |||
488 | } | 512 | } |
489 | } | 513 | } |
490 | 514 | ||
491 | extern struct seq_operations ide_drivers_op; | 515 | static int proc_print_driver(struct device_driver *drv, void *data) |
516 | { | ||
517 | ide_driver_t *ide_drv = container_of(drv, ide_driver_t, gen_driver); | ||
518 | struct seq_file *s = data; | ||
519 | |||
520 | seq_printf(s, "%s version %s\n", drv->name, ide_drv->version); | ||
521 | |||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | static int ide_drivers_show(struct seq_file *s, void *p) | ||
526 | { | ||
527 | bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver); | ||
528 | return 0; | ||
529 | } | ||
530 | |||
492 | static int ide_drivers_open(struct inode *inode, struct file *file) | 531 | static int ide_drivers_open(struct inode *inode, struct file *file) |
493 | { | 532 | { |
494 | return seq_open(file, &ide_drivers_op); | 533 | return single_open(file, &ide_drivers_show, NULL); |
495 | } | 534 | } |
535 | |||
496 | static struct file_operations ide_drivers_operations = { | 536 | static struct file_operations ide_drivers_operations = { |
497 | .open = ide_drivers_open, | 537 | .open = ide_drivers_open, |
498 | .read = seq_read, | 538 | .read = seq_read, |
499 | .llseek = seq_lseek, | 539 | .llseek = seq_lseek, |
500 | .release = seq_release, | 540 | .release = single_release, |
501 | }; | 541 | }; |
502 | 542 | ||
503 | void proc_ide_create(void) | 543 | void proc_ide_create(void) |