diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-11 18:24:56 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-11 18:24:56 -0500 |
commit | f58df54a54451c5feb2fdc4bc2f4fb12cf79be01 (patch) | |
tree | 930b5892717ce84de93508407ebc35757bbc5ea0 /drivers | |
parent | 748e566b7e24541e05e3e70be311887a1262f2a1 (diff) | |
parent | 3589972e51fac1e02d0aaa576fa47f568cb94d40 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (27 commits)
Driver core: fix race in dev_driver_string
Driver Core: Early platform driver buffer
sysfs: sysfs_setattr remove unnecessary permission check.
sysfs: Factor out sysfs_rename from sysfs_rename_dir and sysfs_move_dir
sysfs: Propagate renames to the vfs on demand
sysfs: Gut sysfs_addrm_start and sysfs_addrm_finish
sysfs: In sysfs_chmod_file lazily propagate the mode change.
sysfs: Implement sysfs_getattr & sysfs_permission
sysfs: Nicely indent sysfs_symlink_inode_operations
sysfs: Update s_iattr on link and unlink.
sysfs: Fix locking and factor out sysfs_sd_setattr
sysfs: Simplify iattr time assignments
sysfs: Simplify sysfs_chmod_file semantics
sysfs: Use dentry_ops instead of directly playing with the dcache
sysfs: Rename sysfs_d_iput to sysfs_dentry_iput
sysfs: Update sysfs_setxattr so it updates secdata under the sysfs_mutex
debugfs: fix create mutex racy fops and private data
Driver core: Don't remove kobjects in device_shutdown.
firmware_class: make request_firmware_nowait more useful
Driver-Core: devtmpfs - set root directory mode to 0755
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/core.c | 14 | ||||
-rw-r--r-- | drivers/base/devtmpfs.c | 100 | ||||
-rw-r--r-- | drivers/base/firmware_class.c | 14 | ||||
-rw-r--r-- | drivers/base/platform.c | 29 | ||||
-rw-r--r-- | drivers/firmware/dell_rbu.c | 9 | ||||
-rw-r--r-- | drivers/misc/hpilo.h | 13 | ||||
-rw-r--r-- | drivers/serial/ucc_uart.c | 8 | ||||
-rw-r--r-- | drivers/staging/comedi/drivers/usbdux.c | 5 | ||||
-rw-r--r-- | drivers/staging/comedi/drivers/usbduxfast.c | 5 | ||||
-rw-r--r-- | drivers/usb/atm/ueagle-atm.c | 7 |
10 files changed, 124 insertions, 80 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 6bee6af8d8e1..f1290cbd1350 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -56,7 +56,14 @@ static inline int device_is_not_partition(struct device *dev) | |||
56 | */ | 56 | */ |
57 | const char *dev_driver_string(const struct device *dev) | 57 | const char *dev_driver_string(const struct device *dev) |
58 | { | 58 | { |
59 | return dev->driver ? dev->driver->name : | 59 | struct device_driver *drv; |
60 | |||
61 | /* dev->driver can change to NULL underneath us because of unbinding, | ||
62 | * so be careful about accessing it. dev->bus and dev->class should | ||
63 | * never change once they are set, so they don't need special care. | ||
64 | */ | ||
65 | drv = ACCESS_ONCE(dev->driver); | ||
66 | return drv ? drv->name : | ||
60 | (dev->bus ? dev->bus->name : | 67 | (dev->bus ? dev->bus->name : |
61 | (dev->class ? dev->class->name : "")); | 68 | (dev->class ? dev->class->name : "")); |
62 | } | 69 | } |
@@ -987,6 +994,8 @@ done: | |||
987 | device_remove_class_symlinks(dev); | 994 | device_remove_class_symlinks(dev); |
988 | SymlinkError: | 995 | SymlinkError: |
989 | if (MAJOR(dev->devt)) | 996 | if (MAJOR(dev->devt)) |
997 | devtmpfs_delete_node(dev); | ||
998 | if (MAJOR(dev->devt)) | ||
990 | device_remove_sys_dev_entry(dev); | 999 | device_remove_sys_dev_entry(dev); |
991 | devtattrError: | 1000 | devtattrError: |
992 | if (MAJOR(dev->devt)) | 1001 | if (MAJOR(dev->devt)) |
@@ -1728,8 +1737,5 @@ void device_shutdown(void) | |||
1728 | dev->driver->shutdown(dev); | 1737 | dev->driver->shutdown(dev); |
1729 | } | 1738 | } |
1730 | } | 1739 | } |
1731 | kobject_put(sysfs_dev_char_kobj); | ||
1732 | kobject_put(sysfs_dev_block_kobj); | ||
1733 | kobject_put(dev_kobj); | ||
1734 | async_synchronize_full(); | 1740 | async_synchronize_full(); |
1735 | } | 1741 | } |
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index a1cb5afe6801..50375bb8e51d 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c | |||
@@ -32,6 +32,8 @@ static int dev_mount = 1; | |||
32 | static int dev_mount; | 32 | static int dev_mount; |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | static rwlock_t dirlock; | ||
36 | |||
35 | static int __init mount_param(char *str) | 37 | static int __init mount_param(char *str) |
36 | { | 38 | { |
37 | dev_mount = simple_strtoul(str, NULL, 0); | 39 | dev_mount = simple_strtoul(str, NULL, 0); |
@@ -74,47 +76,35 @@ static int dev_mkdir(const char *name, mode_t mode) | |||
74 | dentry = lookup_create(&nd, 1); | 76 | dentry = lookup_create(&nd, 1); |
75 | if (!IS_ERR(dentry)) { | 77 | if (!IS_ERR(dentry)) { |
76 | err = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); | 78 | err = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); |
79 | if (!err) | ||
80 | /* mark as kernel-created inode */ | ||
81 | dentry->d_inode->i_private = &dev_mnt; | ||
77 | dput(dentry); | 82 | dput(dentry); |
78 | } else { | 83 | } else { |
79 | err = PTR_ERR(dentry); | 84 | err = PTR_ERR(dentry); |
80 | } | 85 | } |
81 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
82 | 86 | ||
87 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
83 | path_put(&nd.path); | 88 | path_put(&nd.path); |
84 | return err; | 89 | return err; |
85 | } | 90 | } |
86 | 91 | ||
87 | static int create_path(const char *nodepath) | 92 | static int create_path(const char *nodepath) |
88 | { | 93 | { |
89 | char *path; | 94 | int err; |
90 | struct nameidata nd; | ||
91 | int err = 0; | ||
92 | |||
93 | path = kstrdup(nodepath, GFP_KERNEL); | ||
94 | if (!path) | ||
95 | return -ENOMEM; | ||
96 | |||
97 | err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, | ||
98 | path, LOOKUP_PARENT, &nd); | ||
99 | if (err == 0) { | ||
100 | struct dentry *dentry; | ||
101 | |||
102 | /* create directory right away */ | ||
103 | dentry = lookup_create(&nd, 1); | ||
104 | if (!IS_ERR(dentry)) { | ||
105 | err = vfs_mkdir(nd.path.dentry->d_inode, | ||
106 | dentry, 0755); | ||
107 | dput(dentry); | ||
108 | } | ||
109 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
110 | 95 | ||
111 | path_put(&nd.path); | 96 | read_lock(&dirlock); |
112 | } else if (err == -ENOENT) { | 97 | err = dev_mkdir(nodepath, 0755); |
98 | if (err == -ENOENT) { | ||
99 | char *path; | ||
113 | char *s; | 100 | char *s; |
114 | 101 | ||
115 | /* parent directories do not exist, create them */ | 102 | /* parent directories do not exist, create them */ |
103 | path = kstrdup(nodepath, GFP_KERNEL); | ||
104 | if (!path) | ||
105 | return -ENOMEM; | ||
116 | s = path; | 106 | s = path; |
117 | while (1) { | 107 | for (;;) { |
118 | s = strchr(s, '/'); | 108 | s = strchr(s, '/'); |
119 | if (!s) | 109 | if (!s) |
120 | break; | 110 | break; |
@@ -125,9 +115,9 @@ static int create_path(const char *nodepath) | |||
125 | s[0] = '/'; | 115 | s[0] = '/'; |
126 | s++; | 116 | s++; |
127 | } | 117 | } |
118 | kfree(path); | ||
128 | } | 119 | } |
129 | 120 | read_unlock(&dirlock); | |
130 | kfree(path); | ||
131 | return err; | 121 | return err; |
132 | } | 122 | } |
133 | 123 | ||
@@ -156,34 +146,40 @@ int devtmpfs_create_node(struct device *dev) | |||
156 | mode |= S_IFCHR; | 146 | mode |= S_IFCHR; |
157 | 147 | ||
158 | curr_cred = override_creds(&init_cred); | 148 | curr_cred = override_creds(&init_cred); |
149 | |||
159 | err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, | 150 | err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, |
160 | nodename, LOOKUP_PARENT, &nd); | 151 | nodename, LOOKUP_PARENT, &nd); |
161 | if (err == -ENOENT) { | 152 | if (err == -ENOENT) { |
162 | /* create missing parent directories */ | ||
163 | create_path(nodename); | 153 | create_path(nodename); |
164 | err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, | 154 | err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, |
165 | nodename, LOOKUP_PARENT, &nd); | 155 | nodename, LOOKUP_PARENT, &nd); |
166 | if (err) | ||
167 | goto out; | ||
168 | } | 156 | } |
157 | if (err) | ||
158 | goto out; | ||
169 | 159 | ||
170 | dentry = lookup_create(&nd, 0); | 160 | dentry = lookup_create(&nd, 0); |
171 | if (!IS_ERR(dentry)) { | 161 | if (!IS_ERR(dentry)) { |
172 | int umask; | ||
173 | |||
174 | umask = sys_umask(0000); | ||
175 | err = vfs_mknod(nd.path.dentry->d_inode, | 162 | err = vfs_mknod(nd.path.dentry->d_inode, |
176 | dentry, mode, dev->devt); | 163 | dentry, mode, dev->devt); |
177 | sys_umask(umask); | 164 | if (!err) { |
178 | /* mark as kernel created inode */ | 165 | struct iattr newattrs; |
179 | if (!err) | 166 | |
167 | /* fixup possibly umasked mode */ | ||
168 | newattrs.ia_mode = mode; | ||
169 | newattrs.ia_valid = ATTR_MODE; | ||
170 | mutex_lock(&dentry->d_inode->i_mutex); | ||
171 | notify_change(dentry, &newattrs); | ||
172 | mutex_unlock(&dentry->d_inode->i_mutex); | ||
173 | |||
174 | /* mark as kernel-created inode */ | ||
180 | dentry->d_inode->i_private = &dev_mnt; | 175 | dentry->d_inode->i_private = &dev_mnt; |
176 | } | ||
181 | dput(dentry); | 177 | dput(dentry); |
182 | } else { | 178 | } else { |
183 | err = PTR_ERR(dentry); | 179 | err = PTR_ERR(dentry); |
184 | } | 180 | } |
185 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
186 | 181 | ||
182 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
187 | path_put(&nd.path); | 183 | path_put(&nd.path); |
188 | out: | 184 | out: |
189 | kfree(tmp); | 185 | kfree(tmp); |
@@ -205,16 +201,21 @@ static int dev_rmdir(const char *name) | |||
205 | mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); | 201 | mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); |
206 | dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len); | 202 | dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len); |
207 | if (!IS_ERR(dentry)) { | 203 | if (!IS_ERR(dentry)) { |
208 | if (dentry->d_inode) | 204 | if (dentry->d_inode) { |
209 | err = vfs_rmdir(nd.path.dentry->d_inode, dentry); | 205 | if (dentry->d_inode->i_private == &dev_mnt) |
210 | else | 206 | err = vfs_rmdir(nd.path.dentry->d_inode, |
207 | dentry); | ||
208 | else | ||
209 | err = -EPERM; | ||
210 | } else { | ||
211 | err = -ENOENT; | 211 | err = -ENOENT; |
212 | } | ||
212 | dput(dentry); | 213 | dput(dentry); |
213 | } else { | 214 | } else { |
214 | err = PTR_ERR(dentry); | 215 | err = PTR_ERR(dentry); |
215 | } | 216 | } |
216 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
217 | 217 | ||
218 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
218 | path_put(&nd.path); | 219 | path_put(&nd.path); |
219 | return err; | 220 | return err; |
220 | } | 221 | } |
@@ -228,7 +229,8 @@ static int delete_path(const char *nodepath) | |||
228 | if (!path) | 229 | if (!path) |
229 | return -ENOMEM; | 230 | return -ENOMEM; |
230 | 231 | ||
231 | while (1) { | 232 | write_lock(&dirlock); |
233 | for (;;) { | ||
232 | char *base; | 234 | char *base; |
233 | 235 | ||
234 | base = strrchr(path, '/'); | 236 | base = strrchr(path, '/'); |
@@ -239,6 +241,7 @@ static int delete_path(const char *nodepath) | |||
239 | if (err) | 241 | if (err) |
240 | break; | 242 | break; |
241 | } | 243 | } |
244 | write_unlock(&dirlock); | ||
242 | 245 | ||
243 | kfree(path); | 246 | kfree(path); |
244 | return err; | 247 | return err; |
@@ -322,9 +325,8 @@ out: | |||
322 | * If configured, or requested by the commandline, devtmpfs will be | 325 | * If configured, or requested by the commandline, devtmpfs will be |
323 | * auto-mounted after the kernel mounted the root filesystem. | 326 | * auto-mounted after the kernel mounted the root filesystem. |
324 | */ | 327 | */ |
325 | int devtmpfs_mount(const char *mountpoint) | 328 | int devtmpfs_mount(const char *mntdir) |
326 | { | 329 | { |
327 | struct path path; | ||
328 | int err; | 330 | int err; |
329 | 331 | ||
330 | if (!dev_mount) | 332 | if (!dev_mount) |
@@ -333,15 +335,11 @@ int devtmpfs_mount(const char *mountpoint) | |||
333 | if (!dev_mnt) | 335 | if (!dev_mnt) |
334 | return 0; | 336 | return 0; |
335 | 337 | ||
336 | err = kern_path(mountpoint, LOOKUP_FOLLOW, &path); | 338 | err = sys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, NULL); |
337 | if (err) | ||
338 | return err; | ||
339 | err = do_add_mount(dev_mnt, &path, 0, NULL); | ||
340 | if (err) | 339 | if (err) |
341 | printk(KERN_INFO "devtmpfs: error mounting %i\n", err); | 340 | printk(KERN_INFO "devtmpfs: error mounting %i\n", err); |
342 | else | 341 | else |
343 | printk(KERN_INFO "devtmpfs: mounted\n"); | 342 | printk(KERN_INFO "devtmpfs: mounted\n"); |
344 | path_put(&path); | ||
345 | return err; | 343 | return err; |
346 | } | 344 | } |
347 | 345 | ||
@@ -354,6 +352,8 @@ int __init devtmpfs_init(void) | |||
354 | int err; | 352 | int err; |
355 | struct vfsmount *mnt; | 353 | struct vfsmount *mnt; |
356 | 354 | ||
355 | rwlock_init(&dirlock); | ||
356 | |||
357 | err = register_filesystem(&dev_fs_type); | 357 | err = register_filesystem(&dev_fs_type); |
358 | if (err) { | 358 | if (err) { |
359 | printk(KERN_ERR "devtmpfs: unable to register devtmpfs " | 359 | printk(KERN_ERR "devtmpfs: unable to register devtmpfs " |
@@ -361,7 +361,7 @@ int __init devtmpfs_init(void) | |||
361 | return err; | 361 | return err; |
362 | } | 362 | } |
363 | 363 | ||
364 | mnt = kern_mount(&dev_fs_type); | 364 | mnt = kern_mount_data(&dev_fs_type, "mode=0755"); |
365 | if (IS_ERR(mnt)) { | 365 | if (IS_ERR(mnt)) { |
366 | err = PTR_ERR(mnt); | 366 | err = PTR_ERR(mnt); |
367 | printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err); | 367 | printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err); |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 7376367bcb80..a95024166b66 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -601,12 +601,9 @@ request_firmware_work_func(void *arg) | |||
601 | } | 601 | } |
602 | ret = _request_firmware(&fw, fw_work->name, fw_work->device, | 602 | ret = _request_firmware(&fw, fw_work->name, fw_work->device, |
603 | fw_work->uevent); | 603 | fw_work->uevent); |
604 | if (ret < 0) | 604 | |
605 | fw_work->cont(NULL, fw_work->context); | 605 | fw_work->cont(fw, fw_work->context); |
606 | else { | 606 | |
607 | fw_work->cont(fw, fw_work->context); | ||
608 | release_firmware(fw); | ||
609 | } | ||
610 | module_put(fw_work->module); | 607 | module_put(fw_work->module); |
611 | kfree(fw_work); | 608 | kfree(fw_work); |
612 | return ret; | 609 | return ret; |
@@ -619,6 +616,7 @@ request_firmware_work_func(void *arg) | |||
619 | * is non-zero else the firmware copy must be done manually. | 616 | * is non-zero else the firmware copy must be done manually. |
620 | * @name: name of firmware file | 617 | * @name: name of firmware file |
621 | * @device: device for which firmware is being loaded | 618 | * @device: device for which firmware is being loaded |
619 | * @gfp: allocation flags | ||
622 | * @context: will be passed over to @cont, and | 620 | * @context: will be passed over to @cont, and |
623 | * @fw may be %NULL if firmware request fails. | 621 | * @fw may be %NULL if firmware request fails. |
624 | * @cont: function will be called asynchronously when the firmware | 622 | * @cont: function will be called asynchronously when the firmware |
@@ -631,12 +629,12 @@ request_firmware_work_func(void *arg) | |||
631 | int | 629 | int |
632 | request_firmware_nowait( | 630 | request_firmware_nowait( |
633 | struct module *module, int uevent, | 631 | struct module *module, int uevent, |
634 | const char *name, struct device *device, void *context, | 632 | const char *name, struct device *device, gfp_t gfp, void *context, |
635 | void (*cont)(const struct firmware *fw, void *context)) | 633 | void (*cont)(const struct firmware *fw, void *context)) |
636 | { | 634 | { |
637 | struct task_struct *task; | 635 | struct task_struct *task; |
638 | struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work), | 636 | struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work), |
639 | GFP_ATOMIC); | 637 | gfp); |
640 | 638 | ||
641 | if (!fw_work) | 639 | if (!fw_work) |
642 | return -ENOMEM; | 640 | return -ENOMEM; |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 4fa954b07ac4..9d2ee25deaf5 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -1000,7 +1000,7 @@ static __initdata LIST_HEAD(early_platform_device_list); | |||
1000 | int __init early_platform_driver_register(struct early_platform_driver *epdrv, | 1000 | int __init early_platform_driver_register(struct early_platform_driver *epdrv, |
1001 | char *buf) | 1001 | char *buf) |
1002 | { | 1002 | { |
1003 | unsigned long index; | 1003 | char *tmp; |
1004 | int n; | 1004 | int n; |
1005 | 1005 | ||
1006 | /* Simply add the driver to the end of the global list. | 1006 | /* Simply add the driver to the end of the global list. |
@@ -1019,13 +1019,28 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv, | |||
1019 | if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { | 1019 | if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { |
1020 | list_move(&epdrv->list, &early_platform_driver_list); | 1020 | list_move(&epdrv->list, &early_platform_driver_list); |
1021 | 1021 | ||
1022 | if (!strcmp(buf, epdrv->pdrv->driver.name)) | 1022 | /* Allow passing parameters after device name */ |
1023 | if (buf[n] == '\0' || buf[n] == ',') | ||
1023 | epdrv->requested_id = -1; | 1024 | epdrv->requested_id = -1; |
1024 | else if (buf[n] == '.' && strict_strtoul(&buf[n + 1], 10, | 1025 | else { |
1025 | &index) == 0) | 1026 | epdrv->requested_id = simple_strtoul(&buf[n + 1], |
1026 | epdrv->requested_id = index; | 1027 | &tmp, 10); |
1027 | else | 1028 | |
1028 | epdrv->requested_id = EARLY_PLATFORM_ID_ERROR; | 1029 | if (buf[n] != '.' || (tmp == &buf[n + 1])) { |
1030 | epdrv->requested_id = EARLY_PLATFORM_ID_ERROR; | ||
1031 | n = 0; | ||
1032 | } else | ||
1033 | n += strcspn(&buf[n + 1], ",") + 1; | ||
1034 | } | ||
1035 | |||
1036 | if (buf[n] == ',') | ||
1037 | n++; | ||
1038 | |||
1039 | if (epdrv->bufsize) { | ||
1040 | memcpy(epdrv->buffer, &buf[n], | ||
1041 | min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1)); | ||
1042 | epdrv->buffer[epdrv->bufsize - 1] = '\0'; | ||
1043 | } | ||
1029 | } | 1044 | } |
1030 | 1045 | ||
1031 | return 0; | 1046 | return 0; |
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c index b4704e150b28..b3a0cf57442e 100644 --- a/drivers/firmware/dell_rbu.c +++ b/drivers/firmware/dell_rbu.c | |||
@@ -544,9 +544,12 @@ static void callbackfn_rbu(const struct firmware *fw, void *context) | |||
544 | { | 544 | { |
545 | rbu_data.entry_created = 0; | 545 | rbu_data.entry_created = 0; |
546 | 546 | ||
547 | if (!fw || !fw->size) | 547 | if (!fw) |
548 | return; | 548 | return; |
549 | 549 | ||
550 | if (!fw->size) | ||
551 | goto out; | ||
552 | |||
550 | spin_lock(&rbu_data.lock); | 553 | spin_lock(&rbu_data.lock); |
551 | if (!strcmp(image_type, "mono")) { | 554 | if (!strcmp(image_type, "mono")) { |
552 | if (!img_update_realloc(fw->size)) | 555 | if (!img_update_realloc(fw->size)) |
@@ -568,6 +571,8 @@ static void callbackfn_rbu(const struct firmware *fw, void *context) | |||
568 | } else | 571 | } else |
569 | pr_debug("invalid image type specified.\n"); | 572 | pr_debug("invalid image type specified.\n"); |
570 | spin_unlock(&rbu_data.lock); | 573 | spin_unlock(&rbu_data.lock); |
574 | out: | ||
575 | release_firmware(fw); | ||
571 | } | 576 | } |
572 | 577 | ||
573 | static ssize_t read_rbu_image_type(struct kobject *kobj, | 578 | static ssize_t read_rbu_image_type(struct kobject *kobj, |
@@ -615,7 +620,7 @@ static ssize_t write_rbu_image_type(struct kobject *kobj, | |||
615 | spin_unlock(&rbu_data.lock); | 620 | spin_unlock(&rbu_data.lock); |
616 | req_firm_rc = request_firmware_nowait(THIS_MODULE, | 621 | req_firm_rc = request_firmware_nowait(THIS_MODULE, |
617 | FW_ACTION_NOHOTPLUG, "dell_rbu", | 622 | FW_ACTION_NOHOTPLUG, "dell_rbu", |
618 | &rbu_device->dev, &context, | 623 | &rbu_device->dev, GFP_KERNEL, &context, |
619 | callbackfn_rbu); | 624 | callbackfn_rbu); |
620 | if (req_firm_rc) { | 625 | if (req_firm_rc) { |
621 | printk(KERN_ERR | 626 | printk(KERN_ERR |
diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h index 38576050776a..247eb386a973 100644 --- a/drivers/misc/hpilo.h +++ b/drivers/misc/hpilo.h | |||
@@ -44,9 +44,20 @@ struct ilo_hwinfo { | |||
44 | 44 | ||
45 | struct pci_dev *ilo_dev; | 45 | struct pci_dev *ilo_dev; |
46 | 46 | ||
47 | /* | ||
48 | * open_lock serializes ccb_cnt during open and close | ||
49 | * [ irq disabled ] | ||
50 | * -> alloc_lock used when adding/removing/searching ccb_alloc, | ||
51 | * which represents all ccbs open on the device | ||
52 | * --> fifo_lock controls access to fifo queues shared with hw | ||
53 | * | ||
54 | * Locks must be taken in this order, but open_lock and alloc_lock | ||
55 | * are optional, they do not need to be held in order to take a | ||
56 | * lower level lock. | ||
57 | */ | ||
58 | spinlock_t open_lock; | ||
47 | spinlock_t alloc_lock; | 59 | spinlock_t alloc_lock; |
48 | spinlock_t fifo_lock; | 60 | spinlock_t fifo_lock; |
49 | spinlock_t open_lock; | ||
50 | 61 | ||
51 | struct cdev cdev; | 62 | struct cdev cdev; |
52 | }; | 63 | }; |
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c index 46de564aaea0..465f2fae1025 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/serial/ucc_uart.c | |||
@@ -1179,16 +1179,18 @@ static void uart_firmware_cont(const struct firmware *fw, void *context) | |||
1179 | 1179 | ||
1180 | if (firmware->header.length != fw->size) { | 1180 | if (firmware->header.length != fw->size) { |
1181 | dev_err(dev, "invalid firmware\n"); | 1181 | dev_err(dev, "invalid firmware\n"); |
1182 | return; | 1182 | goto out; |
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | ret = qe_upload_firmware(firmware); | 1185 | ret = qe_upload_firmware(firmware); |
1186 | if (ret) { | 1186 | if (ret) { |
1187 | dev_err(dev, "could not load firmware\n"); | 1187 | dev_err(dev, "could not load firmware\n"); |
1188 | return; | 1188 | goto out; |
1189 | } | 1189 | } |
1190 | 1190 | ||
1191 | firmware_loaded = 1; | 1191 | firmware_loaded = 1; |
1192 | out: | ||
1193 | release_firmware(fw); | ||
1192 | } | 1194 | } |
1193 | 1195 | ||
1194 | static int ucc_uart_probe(struct of_device *ofdev, | 1196 | static int ucc_uart_probe(struct of_device *ofdev, |
@@ -1247,7 +1249,7 @@ static int ucc_uart_probe(struct of_device *ofdev, | |||
1247 | */ | 1249 | */ |
1248 | ret = request_firmware_nowait(THIS_MODULE, | 1250 | ret = request_firmware_nowait(THIS_MODULE, |
1249 | FW_ACTION_HOTPLUG, filename, &ofdev->dev, | 1251 | FW_ACTION_HOTPLUG, filename, &ofdev->dev, |
1250 | &ofdev->dev, uart_firmware_cont); | 1252 | GFP_KERNEL, &ofdev->dev, uart_firmware_cont); |
1251 | if (ret) { | 1253 | if (ret) { |
1252 | dev_err(&ofdev->dev, | 1254 | dev_err(&ofdev->dev, |
1253 | "could not load firmware %s\n", | 1255 | "could not load firmware %s\n", |
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index cca4e869f0ec..dfcd12bec86b 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c | |||
@@ -2327,9 +2327,11 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, | |||
2327 | if (ret) { | 2327 | if (ret) { |
2328 | dev_err(&usbdev->dev, | 2328 | dev_err(&usbdev->dev, |
2329 | "Could not upload firmware (err=%d)\n", ret); | 2329 | "Could not upload firmware (err=%d)\n", ret); |
2330 | return; | 2330 | goto out; |
2331 | } | 2331 | } |
2332 | comedi_usb_auto_config(usbdev, BOARDNAME); | 2332 | comedi_usb_auto_config(usbdev, BOARDNAME); |
2333 | out: | ||
2334 | release_firmware(fw); | ||
2333 | } | 2335 | } |
2334 | 2336 | ||
2335 | /* allocate memory for the urbs and initialise them */ | 2337 | /* allocate memory for the urbs and initialise them */ |
@@ -2580,6 +2582,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf, | |||
2580 | FW_ACTION_HOTPLUG, | 2582 | FW_ACTION_HOTPLUG, |
2581 | "usbdux_firmware.bin", | 2583 | "usbdux_firmware.bin", |
2582 | &udev->dev, | 2584 | &udev->dev, |
2585 | GFP_KERNEL, | ||
2583 | usbduxsub + index, | 2586 | usbduxsub + index, |
2584 | usbdux_firmware_request_complete_handler); | 2587 | usbdux_firmware_request_complete_handler); |
2585 | 2588 | ||
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index d143222579c2..2e675cce7dbf 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c | |||
@@ -1451,10 +1451,12 @@ static void usbduxfast_firmware_request_complete_handler(const struct firmware | |||
1451 | if (ret) { | 1451 | if (ret) { |
1452 | dev_err(&usbdev->dev, | 1452 | dev_err(&usbdev->dev, |
1453 | "Could not upload firmware (err=%d)\n", ret); | 1453 | "Could not upload firmware (err=%d)\n", ret); |
1454 | return; | 1454 | goto out; |
1455 | } | 1455 | } |
1456 | 1456 | ||
1457 | comedi_usb_auto_config(usbdev, BOARDNAME); | 1457 | comedi_usb_auto_config(usbdev, BOARDNAME); |
1458 | out: | ||
1459 | release_firmware(fw); | ||
1458 | } | 1460 | } |
1459 | 1461 | ||
1460 | /* | 1462 | /* |
@@ -1569,6 +1571,7 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf, | |||
1569 | FW_ACTION_HOTPLUG, | 1571 | FW_ACTION_HOTPLUG, |
1570 | "usbduxfast_firmware.bin", | 1572 | "usbduxfast_firmware.bin", |
1571 | &udev->dev, | 1573 | &udev->dev, |
1574 | GFP_KERNEL, | ||
1572 | usbduxfastsub + index, | 1575 | usbduxfastsub + index, |
1573 | usbduxfast_firmware_request_complete_handler); | 1576 | usbduxfast_firmware_request_complete_handler); |
1574 | 1577 | ||
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index bba4d3eabe0f..c5395246886d 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c | |||
@@ -667,12 +667,12 @@ static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *conte | |||
667 | else | 667 | else |
668 | uea_info(usb, "firmware uploaded\n"); | 668 | uea_info(usb, "firmware uploaded\n"); |
669 | 669 | ||
670 | uea_leaves(usb); | 670 | goto err; |
671 | return; | ||
672 | 671 | ||
673 | err_fw_corrupted: | 672 | err_fw_corrupted: |
674 | uea_err(usb, "firmware is corrupted\n"); | 673 | uea_err(usb, "firmware is corrupted\n"); |
675 | err: | 674 | err: |
675 | release_firmware(fw_entry); | ||
676 | uea_leaves(usb); | 676 | uea_leaves(usb); |
677 | } | 677 | } |
678 | 678 | ||
@@ -705,7 +705,8 @@ static int uea_load_firmware(struct usb_device *usb, unsigned int ver) | |||
705 | break; | 705 | break; |
706 | } | 706 | } |
707 | 707 | ||
708 | ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware); | 708 | ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, |
709 | GFP_KERNEL, usb, uea_upload_pre_firmware); | ||
709 | if (ret) | 710 | if (ret) |
710 | uea_err(usb, "firmware %s is not available\n", fw_name); | 711 | uea_err(usb, "firmware %s is not available\n", fw_name); |
711 | else | 712 | else |