diff options
| -rw-r--r-- | Documentation/laptops/thinkpad-acpi.txt | 5 | ||||
| -rw-r--r-- | Documentation/spinlocks.txt | 45 | ||||
| -rw-r--r-- | drivers/cpufreq/acpi-cpufreq.c | 2 | ||||
| -rw-r--r-- | drivers/firewire/ohci.c | 6 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath5k/desc.c | 3 | ||||
| -rw-r--r-- | drivers/platform/x86/acer-wmi.c | 47 | ||||
| -rw-r--r-- | drivers/platform/x86/asus-wmi.c | 1 | ||||
| -rw-r--r-- | drivers/platform/x86/compal-laptop.c | 4 | ||||
| -rw-r--r-- | drivers/platform/x86/dell-laptop.c | 30 | ||||
| -rw-r--r-- | drivers/platform/x86/hp-wmi.c | 11 | ||||
| -rw-r--r-- | drivers/platform/x86/intel_oaktrail.c | 1 | ||||
| -rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 72 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.c | 8 | ||||
| -rw-r--r-- | fs/cifs/cifsproto.h | 6 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 116 |
15 files changed, 198 insertions, 159 deletions
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 1565eefd6fd5..61815483efa3 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt | |||
| @@ -534,6 +534,8 @@ Events that are never propagated by the driver: | |||
| 534 | 0x2404 System is waking up from hibernation to undock | 534 | 0x2404 System is waking up from hibernation to undock |
| 535 | 0x2405 System is waking up from hibernation to eject bay | 535 | 0x2405 System is waking up from hibernation to eject bay |
| 536 | 0x5010 Brightness level changed/control event | 536 | 0x5010 Brightness level changed/control event |
| 537 | 0x6000 KEYBOARD: Numlock key pressed | ||
| 538 | 0x6005 KEYBOARD: Fn key pressed (TO BE VERIFIED) | ||
| 537 | 539 | ||
| 538 | Events that are propagated by the driver to userspace: | 540 | Events that are propagated by the driver to userspace: |
| 539 | 541 | ||
| @@ -545,6 +547,8 @@ Events that are propagated by the driver to userspace: | |||
| 545 | 0x3006 Bay hotplug request (hint to power up SATA link when | 547 | 0x3006 Bay hotplug request (hint to power up SATA link when |
| 546 | the optical drive tray is ejected) | 548 | the optical drive tray is ejected) |
| 547 | 0x4003 Undocked (see 0x2x04), can sleep again | 549 | 0x4003 Undocked (see 0x2x04), can sleep again |
| 550 | 0x4010 Docked into hotplug port replicator (non-ACPI dock) | ||
| 551 | 0x4011 Undocked from hotplug port replicator (non-ACPI dock) | ||
| 548 | 0x500B Tablet pen inserted into its storage bay | 552 | 0x500B Tablet pen inserted into its storage bay |
| 549 | 0x500C Tablet pen removed from its storage bay | 553 | 0x500C Tablet pen removed from its storage bay |
| 550 | 0x6011 ALARM: battery is too hot | 554 | 0x6011 ALARM: battery is too hot |
| @@ -552,6 +556,7 @@ Events that are propagated by the driver to userspace: | |||
| 552 | 0x6021 ALARM: a sensor is too hot | 556 | 0x6021 ALARM: a sensor is too hot |
| 553 | 0x6022 ALARM: a sensor is extremely hot | 557 | 0x6022 ALARM: a sensor is extremely hot |
| 554 | 0x6030 System thermal table changed | 558 | 0x6030 System thermal table changed |
| 559 | 0x6040 Nvidia Optimus/AC adapter related (TO BE VERIFIED) | ||
| 555 | 560 | ||
| 556 | Battery nearly empty alarms are a last resort attempt to get the | 561 | Battery nearly empty alarms are a last resort attempt to get the |
| 557 | operating system to hibernate or shutdown cleanly (0x2313), or shutdown | 562 | operating system to hibernate or shutdown cleanly (0x2313), or shutdown |
diff --git a/Documentation/spinlocks.txt b/Documentation/spinlocks.txt index 2e3c64b1a6a5..9dbe885ecd8d 100644 --- a/Documentation/spinlocks.txt +++ b/Documentation/spinlocks.txt | |||
| @@ -13,18 +13,8 @@ static DEFINE_SPINLOCK(xxx_lock); | |||
| 13 | The above is always safe. It will disable interrupts _locally_, but the | 13 | The above is always safe. It will disable interrupts _locally_, but the |
| 14 | spinlock itself will guarantee the global lock, so it will guarantee that | 14 | spinlock itself will guarantee the global lock, so it will guarantee that |
| 15 | there is only one thread-of-control within the region(s) protected by that | 15 | there is only one thread-of-control within the region(s) protected by that |
| 16 | lock. This works well even under UP. The above sequence under UP | 16 | lock. This works well even under UP also, so the code does _not_ need to |
| 17 | essentially is just the same as doing | 17 | worry about UP vs SMP issues: the spinlocks work correctly under both. |
| 18 | |||
| 19 | unsigned long flags; | ||
| 20 | |||
| 21 | save_flags(flags); cli(); | ||
| 22 | ... critical section ... | ||
| 23 | restore_flags(flags); | ||
| 24 | |||
| 25 | so the code does _not_ need to worry about UP vs SMP issues: the spinlocks | ||
| 26 | work correctly under both (and spinlocks are actually more efficient on | ||
| 27 | architectures that allow doing the "save_flags + cli" in one operation). | ||
| 28 | 18 | ||
| 29 | NOTE! Implications of spin_locks for memory are further described in: | 19 | NOTE! Implications of spin_locks for memory are further described in: |
| 30 | 20 | ||
| @@ -36,27 +26,7 @@ The above is usually pretty simple (you usually need and want only one | |||
| 36 | spinlock for most things - using more than one spinlock can make things a | 26 | spinlock for most things - using more than one spinlock can make things a |
| 37 | lot more complex and even slower and is usually worth it only for | 27 | lot more complex and even slower and is usually worth it only for |
| 38 | sequences that you _know_ need to be split up: avoid it at all cost if you | 28 | sequences that you _know_ need to be split up: avoid it at all cost if you |
| 39 | aren't sure). HOWEVER, it _does_ mean that if you have some code that does | 29 | aren't sure). |
| 40 | |||
| 41 | cli(); | ||
| 42 | .. critical section .. | ||
| 43 | sti(); | ||
| 44 | |||
| 45 | and another sequence that does | ||
| 46 | |||
| 47 | spin_lock_irqsave(flags); | ||
| 48 | .. critical section .. | ||
| 49 | spin_unlock_irqrestore(flags); | ||
| 50 | |||
| 51 | then they are NOT mutually exclusive, and the critical regions can happen | ||
| 52 | at the same time on two different CPU's. That's fine per se, but the | ||
| 53 | critical regions had better be critical for different things (ie they | ||
| 54 | can't stomp on each other). | ||
| 55 | |||
| 56 | The above is a problem mainly if you end up mixing code - for example the | ||
| 57 | routines in ll_rw_block() tend to use cli/sti to protect the atomicity of | ||
| 58 | their actions, and if a driver uses spinlocks instead then you should | ||
| 59 | think about issues like the above. | ||
| 60 | 30 | ||
| 61 | This is really the only really hard part about spinlocks: once you start | 31 | This is really the only really hard part about spinlocks: once you start |
| 62 | using spinlocks they tend to expand to areas you might not have noticed | 32 | using spinlocks they tend to expand to areas you might not have noticed |
| @@ -120,11 +90,10 @@ Lesson 3: spinlocks revisited. | |||
| 120 | 90 | ||
| 121 | The single spin-lock primitives above are by no means the only ones. They | 91 | The single spin-lock primitives above are by no means the only ones. They |
| 122 | are the most safe ones, and the ones that work under all circumstances, | 92 | are the most safe ones, and the ones that work under all circumstances, |
| 123 | but partly _because_ they are safe they are also fairly slow. They are | 93 | but partly _because_ they are safe they are also fairly slow. They are slower |
| 124 | much faster than a generic global cli/sti pair, but slower than they'd | 94 | than they'd need to be, because they do have to disable interrupts |
| 125 | need to be, because they do have to disable interrupts (which is just a | 95 | (which is just a single instruction on a x86, but it's an expensive one - |
| 126 | single instruction on a x86, but it's an expensive one - and on other | 96 | and on other architectures it can be worse). |
| 127 | architectures it can be worse). | ||
| 128 | 97 | ||
| 129 | If you have a case where you have to protect a data structure across | 98 | If you have a case where you have to protect a data structure across |
| 130 | several CPU's and you want to use spinlocks you can potentially use | 99 | several CPU's and you want to use spinlocks you can potentially use |
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 4e04e1274388..596d5dd32f41 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
| @@ -759,7 +759,7 @@ static void __exit acpi_cpufreq_exit(void) | |||
| 759 | 759 | ||
| 760 | cpufreq_unregister_driver(&acpi_cpufreq_driver); | 760 | cpufreq_unregister_driver(&acpi_cpufreq_driver); |
| 761 | 761 | ||
| 762 | free_percpu(acpi_perf_data); | 762 | free_acpi_perf_data(); |
| 763 | } | 763 | } |
| 764 | 764 | ||
| 765 | module_param(acpi_pstate_strict, uint, 0644); | 765 | module_param(acpi_pstate_strict, uint, 0644); |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 438e6c831170..ebb897329c1e 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
| @@ -264,6 +264,7 @@ static char ohci_driver_name[] = KBUILD_MODNAME; | |||
| 264 | #define PCI_DEVICE_ID_AGERE_FW643 0x5901 | 264 | #define PCI_DEVICE_ID_AGERE_FW643 0x5901 |
| 265 | #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 | 265 | #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 |
| 266 | #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 | 266 | #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 |
| 267 | #define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd | ||
| 267 | 268 | ||
| 268 | #define QUIRK_CYCLE_TIMER 1 | 269 | #define QUIRK_CYCLE_TIMER 1 |
| 269 | #define QUIRK_RESET_PACKET 2 | 270 | #define QUIRK_RESET_PACKET 2 |
| @@ -3190,6 +3191,11 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
| 3190 | int i, err; | 3191 | int i, err; |
| 3191 | size_t size; | 3192 | size_t size; |
| 3192 | 3193 | ||
| 3194 | if (dev->vendor == PCI_VENDOR_ID_PINNACLE_SYSTEMS) { | ||
| 3195 | dev_err(&dev->dev, "Pinnacle MovieBoard is not yet supported\n"); | ||
| 3196 | return -ENOSYS; | ||
| 3197 | } | ||
| 3198 | |||
| 3193 | ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); | 3199 | ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); |
| 3194 | if (ohci == NULL) { | 3200 | if (ohci == NULL) { |
| 3195 | err = -ENOMEM; | 3201 | err = -ENOMEM; |
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 62172d585723..f82383b3ed30 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c | |||
| @@ -107,10 +107,13 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | |||
| 107 | case AR5K_PKT_TYPE_BEACON: | 107 | case AR5K_PKT_TYPE_BEACON: |
| 108 | case AR5K_PKT_TYPE_PROBE_RESP: | 108 | case AR5K_PKT_TYPE_PROBE_RESP: |
| 109 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY; | 109 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY; |
| 110 | break; | ||
| 110 | case AR5K_PKT_TYPE_PIFS: | 111 | case AR5K_PKT_TYPE_PIFS: |
| 111 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; | 112 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; |
| 113 | break; | ||
| 112 | default: | 114 | default: |
| 113 | frame_type = type; | 115 | frame_type = type; |
| 116 | break; | ||
| 114 | } | 117 | } |
| 115 | 118 | ||
| 116 | tx_ctl->tx_control_0 |= | 119 | tx_ctl->tx_control_0 |= |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 005417bd429e..e1c4938b301b 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
| @@ -1156,9 +1156,9 @@ static acpi_status wmid3_set_device_status(u32 value, u16 device) | |||
| 1156 | struct wmid3_gds_input_param params = { | 1156 | struct wmid3_gds_input_param params = { |
| 1157 | .function_num = 0x1, | 1157 | .function_num = 0x1, |
| 1158 | .hotkey_number = 0x01, | 1158 | .hotkey_number = 0x01, |
| 1159 | .devices = ACER_WMID3_GDS_WIRELESS & | 1159 | .devices = ACER_WMID3_GDS_WIRELESS | |
| 1160 | ACER_WMID3_GDS_THREEG & | 1160 | ACER_WMID3_GDS_THREEG | |
| 1161 | ACER_WMID3_GDS_WIMAX & | 1161 | ACER_WMID3_GDS_WIMAX | |
| 1162 | ACER_WMID3_GDS_BLUETOOTH, | 1162 | ACER_WMID3_GDS_BLUETOOTH, |
| 1163 | }; | 1163 | }; |
| 1164 | struct acpi_buffer input = { | 1164 | struct acpi_buffer input = { |
| @@ -1445,6 +1445,8 @@ static void acer_wmi_notify(u32 value, void *context) | |||
| 1445 | union acpi_object *obj; | 1445 | union acpi_object *obj; |
| 1446 | struct event_return_value return_value; | 1446 | struct event_return_value return_value; |
| 1447 | acpi_status status; | 1447 | acpi_status status; |
| 1448 | u16 device_state; | ||
| 1449 | const struct key_entry *key; | ||
| 1448 | 1450 | ||
| 1449 | status = wmi_get_event_data(value, &response); | 1451 | status = wmi_get_event_data(value, &response); |
| 1450 | if (status != AE_OK) { | 1452 | if (status != AE_OK) { |
| @@ -1472,23 +1474,32 @@ static void acer_wmi_notify(u32 value, void *context) | |||
| 1472 | 1474 | ||
| 1473 | switch (return_value.function) { | 1475 | switch (return_value.function) { |
| 1474 | case WMID_HOTKEY_EVENT: | 1476 | case WMID_HOTKEY_EVENT: |
| 1475 | if (return_value.device_state) { | 1477 | device_state = return_value.device_state; |
| 1476 | u16 device_state = return_value.device_state; | 1478 | pr_debug("device state: 0x%x\n", device_state); |
| 1477 | pr_debug("device state: 0x%x\n", device_state); | 1479 | |
| 1478 | if (has_cap(ACER_CAP_WIRELESS)) | 1480 | key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev, |
| 1479 | rfkill_set_sw_state(wireless_rfkill, | 1481 | return_value.key_num); |
| 1480 | !(device_state & ACER_WMID3_GDS_WIRELESS)); | 1482 | if (!key) { |
| 1481 | if (has_cap(ACER_CAP_BLUETOOTH)) | ||
| 1482 | rfkill_set_sw_state(bluetooth_rfkill, | ||
| 1483 | !(device_state & ACER_WMID3_GDS_BLUETOOTH)); | ||
| 1484 | if (has_cap(ACER_CAP_THREEG)) | ||
| 1485 | rfkill_set_sw_state(threeg_rfkill, | ||
| 1486 | !(device_state & ACER_WMID3_GDS_THREEG)); | ||
| 1487 | } | ||
| 1488 | if (!sparse_keymap_report_event(acer_wmi_input_dev, | ||
| 1489 | return_value.key_num, 1, true)) | ||
| 1490 | pr_warn("Unknown key number - 0x%x\n", | 1483 | pr_warn("Unknown key number - 0x%x\n", |
| 1491 | return_value.key_num); | 1484 | return_value.key_num); |
| 1485 | } else { | ||
| 1486 | switch (key->keycode) { | ||
| 1487 | case KEY_WLAN: | ||
| 1488 | case KEY_BLUETOOTH: | ||
| 1489 | if (has_cap(ACER_CAP_WIRELESS)) | ||
| 1490 | rfkill_set_sw_state(wireless_rfkill, | ||
| 1491 | !(device_state & ACER_WMID3_GDS_WIRELESS)); | ||
| 1492 | if (has_cap(ACER_CAP_THREEG)) | ||
| 1493 | rfkill_set_sw_state(threeg_rfkill, | ||
| 1494 | !(device_state & ACER_WMID3_GDS_THREEG)); | ||
| 1495 | if (has_cap(ACER_CAP_BLUETOOTH)) | ||
| 1496 | rfkill_set_sw_state(bluetooth_rfkill, | ||
| 1497 | !(device_state & ACER_WMID3_GDS_BLUETOOTH)); | ||
| 1498 | break; | ||
| 1499 | } | ||
| 1500 | sparse_keymap_report_entry(acer_wmi_input_dev, key, | ||
| 1501 | 1, true); | ||
| 1502 | } | ||
| 1492 | break; | 1503 | break; |
| 1493 | default: | 1504 | default: |
| 1494 | pr_warn("Unknown function number - %d - %d\n", | 1505 | pr_warn("Unknown function number - %d - %d\n", |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 00460cb9587b..3c7857c71a23 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
| @@ -1025,6 +1025,7 @@ static int asus_wmi_backlight_init(struct asus_wmi *asus) | |||
| 1025 | return power; | 1025 | return power; |
| 1026 | 1026 | ||
| 1027 | memset(&props, 0, sizeof(struct backlight_properties)); | 1027 | memset(&props, 0, sizeof(struct backlight_properties)); |
| 1028 | props.type = BACKLIGHT_PLATFORM; | ||
| 1028 | props.max_brightness = max; | 1029 | props.max_brightness = max; |
| 1029 | bd = backlight_device_register(asus->driver->name, | 1030 | bd = backlight_device_register(asus->driver->name, |
| 1030 | &asus->platform_device->dev, asus, | 1031 | &asus->platform_device->dev, asus, |
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index 3f204fde1b02..8877b836d27c 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c | |||
| @@ -1030,8 +1030,10 @@ static int __devinit compal_probe(struct platform_device *pdev) | |||
| 1030 | initialize_fan_control_data(data); | 1030 | initialize_fan_control_data(data); |
| 1031 | 1031 | ||
| 1032 | err = sysfs_create_group(&pdev->dev.kobj, &compal_attribute_group); | 1032 | err = sysfs_create_group(&pdev->dev.kobj, &compal_attribute_group); |
| 1033 | if (err) | 1033 | if (err) { |
| 1034 | kfree(data); | ||
| 1034 | return err; | 1035 | return err; |
| 1036 | } | ||
| 1035 | 1037 | ||
| 1036 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | 1038 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
| 1037 | if (IS_ERR(data->hwmon_dev)) { | 1039 | if (IS_ERR(data->hwmon_dev)) { |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index d3841de6a8cf..e39ab1d3ed87 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
| @@ -292,12 +292,9 @@ static int dell_rfkill_set(void *data, bool blocked) | |||
| 292 | dell_send_request(buffer, 17, 11); | 292 | dell_send_request(buffer, 17, 11); |
| 293 | 293 | ||
| 294 | /* If the hardware switch controls this radio, and the hardware | 294 | /* If the hardware switch controls this radio, and the hardware |
| 295 | switch is disabled, don't allow changing the software state. | 295 | switch is disabled, don't allow changing the software state */ |
| 296 | If the hardware switch is reported as not supported, always | ||
| 297 | fire the SMI to toggle the killswitch. */ | ||
| 298 | if ((hwswitch_state & BIT(hwswitch_bit)) && | 296 | if ((hwswitch_state & BIT(hwswitch_bit)) && |
| 299 | !(buffer->output[1] & BIT(16)) && | 297 | !(buffer->output[1] & BIT(16))) { |
| 300 | (buffer->output[1] & BIT(0))) { | ||
| 301 | ret = -EINVAL; | 298 | ret = -EINVAL; |
| 302 | goto out; | 299 | goto out; |
| 303 | } | 300 | } |
| @@ -403,23 +400,6 @@ static const struct file_operations dell_debugfs_fops = { | |||
| 403 | 400 | ||
| 404 | static void dell_update_rfkill(struct work_struct *ignored) | 401 | static void dell_update_rfkill(struct work_struct *ignored) |
| 405 | { | 402 | { |
| 406 | int status; | ||
| 407 | |||
| 408 | get_buffer(); | ||
| 409 | dell_send_request(buffer, 17, 11); | ||
| 410 | status = buffer->output[1]; | ||
| 411 | release_buffer(); | ||
| 412 | |||
| 413 | /* if hardware rfkill is not supported, set it explicitly */ | ||
| 414 | if (!(status & BIT(0))) { | ||
| 415 | if (wifi_rfkill) | ||
| 416 | dell_rfkill_set((void *)1, !((status & BIT(17)) >> 17)); | ||
| 417 | if (bluetooth_rfkill) | ||
| 418 | dell_rfkill_set((void *)2, !((status & BIT(18)) >> 18)); | ||
| 419 | if (wwan_rfkill) | ||
| 420 | dell_rfkill_set((void *)3, !((status & BIT(19)) >> 19)); | ||
| 421 | } | ||
| 422 | |||
| 423 | if (wifi_rfkill) | 403 | if (wifi_rfkill) |
| 424 | dell_rfkill_query(wifi_rfkill, (void *)1); | 404 | dell_rfkill_query(wifi_rfkill, (void *)1); |
| 425 | if (bluetooth_rfkill) | 405 | if (bluetooth_rfkill) |
| @@ -560,11 +540,11 @@ static int dell_get_intensity(struct backlight_device *bd) | |||
| 560 | else | 540 | else |
| 561 | dell_send_request(buffer, 0, 1); | 541 | dell_send_request(buffer, 0, 1); |
| 562 | 542 | ||
| 543 | ret = buffer->output[1]; | ||
| 544 | |||
| 563 | out: | 545 | out: |
| 564 | release_buffer(); | 546 | release_buffer(); |
| 565 | if (ret) | 547 | return ret; |
| 566 | return ret; | ||
| 567 | return buffer->output[1]; | ||
| 568 | } | 548 | } |
| 569 | 549 | ||
| 570 | static const struct backlight_ops dell_ops = { | 550 | static const struct backlight_ops dell_ops = { |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index f94017bcdd6e..e2faa3cbb792 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
| @@ -207,6 +207,7 @@ static int hp_wmi_perform_query(int query, int write, void *buffer, | |||
| 207 | }; | 207 | }; |
| 208 | struct acpi_buffer input = { sizeof(struct bios_args), &args }; | 208 | struct acpi_buffer input = { sizeof(struct bios_args), &args }; |
| 209 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | 209 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; |
| 210 | u32 rc; | ||
| 210 | 211 | ||
| 211 | if (WARN_ON(insize > sizeof(args.data))) | 212 | if (WARN_ON(insize > sizeof(args.data))) |
| 212 | return -EINVAL; | 213 | return -EINVAL; |
| @@ -224,13 +225,13 @@ static int hp_wmi_perform_query(int query, int write, void *buffer, | |||
| 224 | } | 225 | } |
| 225 | 226 | ||
| 226 | bios_return = (struct bios_return *)obj->buffer.pointer; | 227 | bios_return = (struct bios_return *)obj->buffer.pointer; |
| 228 | rc = bios_return->return_code; | ||
| 227 | 229 | ||
| 228 | if (bios_return->return_code) { | 230 | if (rc) { |
| 229 | if (bios_return->return_code != HPWMI_RET_UNKNOWN_CMDTYPE) | 231 | if (rc != HPWMI_RET_UNKNOWN_CMDTYPE) |
| 230 | pr_warn("query 0x%x returned error 0x%x\n", | 232 | pr_warn("query 0x%x returned error 0x%x\n", query, rc); |
| 231 | query, bios_return->return_code); | ||
| 232 | kfree(obj); | 233 | kfree(obj); |
| 233 | return bios_return->return_code; | 234 | return rc; |
| 234 | } | 235 | } |
| 235 | 236 | ||
| 236 | if (!outsize) { | 237 | if (!outsize) { |
diff --git a/drivers/platform/x86/intel_oaktrail.c b/drivers/platform/x86/intel_oaktrail.c index e936364a609d..7f88c7923fc6 100644 --- a/drivers/platform/x86/intel_oaktrail.c +++ b/drivers/platform/x86/intel_oaktrail.c | |||
| @@ -250,6 +250,7 @@ static int oaktrail_backlight_init(void) | |||
| 250 | struct backlight_properties props; | 250 | struct backlight_properties props; |
| 251 | 251 | ||
| 252 | memset(&props, 0, sizeof(struct backlight_properties)); | 252 | memset(&props, 0, sizeof(struct backlight_properties)); |
| 253 | props.type = BACKLIGHT_PLATFORM; | ||
| 253 | props.max_brightness = OT_EC_BL_BRIGHTNESS_MAX; | 254 | props.max_brightness = OT_EC_BL_BRIGHTNESS_MAX; |
| 254 | bd = backlight_device_register(DRIVER_NAME, | 255 | bd = backlight_device_register(DRIVER_NAME, |
| 255 | &oaktrail_device->dev, NULL, | 256 | &oaktrail_device->dev, NULL, |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 77f6e707a2a9..26c5b117df22 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
| @@ -184,6 +184,10 @@ enum tpacpi_hkey_event_t { | |||
| 184 | 184 | ||
| 185 | /* Misc bay events */ | 185 | /* Misc bay events */ |
| 186 | TP_HKEY_EV_OPTDRV_EJ = 0x3006, /* opt. drive tray ejected */ | 186 | TP_HKEY_EV_OPTDRV_EJ = 0x3006, /* opt. drive tray ejected */ |
| 187 | TP_HKEY_EV_HOTPLUG_DOCK = 0x4010, /* docked into hotplug dock | ||
| 188 | or port replicator */ | ||
| 189 | TP_HKEY_EV_HOTPLUG_UNDOCK = 0x4011, /* undocked from hotplug | ||
| 190 | dock or port replicator */ | ||
| 187 | 191 | ||
| 188 | /* User-interface events */ | 192 | /* User-interface events */ |
| 189 | TP_HKEY_EV_LID_CLOSE = 0x5001, /* laptop lid closed */ | 193 | TP_HKEY_EV_LID_CLOSE = 0x5001, /* laptop lid closed */ |
| @@ -194,6 +198,10 @@ enum tpacpi_hkey_event_t { | |||
| 194 | TP_HKEY_EV_PEN_REMOVED = 0x500c, /* tablet pen removed */ | 198 | TP_HKEY_EV_PEN_REMOVED = 0x500c, /* tablet pen removed */ |
| 195 | TP_HKEY_EV_BRGHT_CHANGED = 0x5010, /* backlight control event */ | 199 | TP_HKEY_EV_BRGHT_CHANGED = 0x5010, /* backlight control event */ |
| 196 | 200 | ||
| 201 | /* Key-related user-interface events */ | ||
| 202 | TP_HKEY_EV_KEY_NUMLOCK = 0x6000, /* NumLock key pressed */ | ||
| 203 | TP_HKEY_EV_KEY_FN = 0x6005, /* Fn key pressed? E420 */ | ||
| 204 | |||
| 197 | /* Thermal events */ | 205 | /* Thermal events */ |
| 198 | TP_HKEY_EV_ALARM_BAT_HOT = 0x6011, /* battery too hot */ | 206 | TP_HKEY_EV_ALARM_BAT_HOT = 0x6011, /* battery too hot */ |
| 199 | TP_HKEY_EV_ALARM_BAT_XHOT = 0x6012, /* battery critically hot */ | 207 | TP_HKEY_EV_ALARM_BAT_XHOT = 0x6012, /* battery critically hot */ |
| @@ -201,6 +209,10 @@ enum tpacpi_hkey_event_t { | |||
| 201 | TP_HKEY_EV_ALARM_SENSOR_XHOT = 0x6022, /* sensor critically hot */ | 209 | TP_HKEY_EV_ALARM_SENSOR_XHOT = 0x6022, /* sensor critically hot */ |
| 202 | TP_HKEY_EV_THM_TABLE_CHANGED = 0x6030, /* thermal table changed */ | 210 | TP_HKEY_EV_THM_TABLE_CHANGED = 0x6030, /* thermal table changed */ |
| 203 | 211 | ||
| 212 | TP_HKEY_EV_UNK_6040 = 0x6040, /* Related to AC change? | ||
| 213 | some sort of APM hint, | ||
| 214 | W520 */ | ||
| 215 | |||
| 204 | /* Misc */ | 216 | /* Misc */ |
| 205 | TP_HKEY_EV_RFKILL_CHANGED = 0x7000, /* rfkill switch changed */ | 217 | TP_HKEY_EV_RFKILL_CHANGED = 0x7000, /* rfkill switch changed */ |
| 206 | }; | 218 | }; |
| @@ -3513,6 +3525,34 @@ static bool hotkey_notify_wakeup(const u32 hkey, | |||
| 3513 | return true; | 3525 | return true; |
| 3514 | } | 3526 | } |
| 3515 | 3527 | ||
| 3528 | static bool hotkey_notify_dockevent(const u32 hkey, | ||
| 3529 | bool *send_acpi_ev, | ||
| 3530 | bool *ignore_acpi_ev) | ||
| 3531 | { | ||
| 3532 | /* 0x4000-0x4FFF: dock-related events */ | ||
| 3533 | *send_acpi_ev = true; | ||
| 3534 | *ignore_acpi_ev = false; | ||
| 3535 | |||
| 3536 | switch (hkey) { | ||
| 3537 | case TP_HKEY_EV_UNDOCK_ACK: | ||
| 3538 | /* ACPI undock operation completed after wakeup */ | ||
| 3539 | hotkey_autosleep_ack = 1; | ||
| 3540 | pr_info("undocked\n"); | ||
| 3541 | hotkey_wakeup_hotunplug_complete_notify_change(); | ||
| 3542 | return true; | ||
| 3543 | |||
| 3544 | case TP_HKEY_EV_HOTPLUG_DOCK: /* docked to port replicator */ | ||
| 3545 | pr_info("docked into hotplug port replicator\n"); | ||
| 3546 | return true; | ||
| 3547 | case TP_HKEY_EV_HOTPLUG_UNDOCK: /* undocked from port replicator */ | ||
| 3548 | pr_info("undocked from hotplug port replicator\n"); | ||
| 3549 | return true; | ||
| 3550 | |||
| 3551 | default: | ||
| 3552 | return false; | ||
| 3553 | } | ||
| 3554 | } | ||
| 3555 | |||
| 3516 | static bool hotkey_notify_usrevent(const u32 hkey, | 3556 | static bool hotkey_notify_usrevent(const u32 hkey, |
| 3517 | bool *send_acpi_ev, | 3557 | bool *send_acpi_ev, |
| 3518 | bool *ignore_acpi_ev) | 3558 | bool *ignore_acpi_ev) |
| @@ -3547,13 +3587,13 @@ static bool hotkey_notify_usrevent(const u32 hkey, | |||
| 3547 | 3587 | ||
| 3548 | static void thermal_dump_all_sensors(void); | 3588 | static void thermal_dump_all_sensors(void); |
| 3549 | 3589 | ||
| 3550 | static bool hotkey_notify_thermal(const u32 hkey, | 3590 | static bool hotkey_notify_6xxx(const u32 hkey, |
| 3551 | bool *send_acpi_ev, | 3591 | bool *send_acpi_ev, |
| 3552 | bool *ignore_acpi_ev) | 3592 | bool *ignore_acpi_ev) |
| 3553 | { | 3593 | { |
| 3554 | bool known = true; | 3594 | bool known = true; |
| 3555 | 3595 | ||
| 3556 | /* 0x6000-0x6FFF: thermal alarms */ | 3596 | /* 0x6000-0x6FFF: thermal alarms/notices and keyboard events */ |
| 3557 | *send_acpi_ev = true; | 3597 | *send_acpi_ev = true; |
| 3558 | *ignore_acpi_ev = false; | 3598 | *ignore_acpi_ev = false; |
| 3559 | 3599 | ||
| @@ -3582,8 +3622,17 @@ static bool hotkey_notify_thermal(const u32 hkey, | |||
| 3582 | "a sensor reports something is extremely hot!\n"); | 3622 | "a sensor reports something is extremely hot!\n"); |
| 3583 | /* recommended action: immediate sleep/hibernate */ | 3623 | /* recommended action: immediate sleep/hibernate */ |
| 3584 | break; | 3624 | break; |
| 3625 | |||
| 3626 | case TP_HKEY_EV_KEY_NUMLOCK: | ||
| 3627 | case TP_HKEY_EV_KEY_FN: | ||
| 3628 | /* key press events, we just ignore them as long as the EC | ||
| 3629 | * is still reporting them in the normal keyboard stream */ | ||
| 3630 | *send_acpi_ev = false; | ||
| 3631 | *ignore_acpi_ev = true; | ||
| 3632 | return true; | ||
| 3633 | |||
| 3585 | default: | 3634 | default: |
| 3586 | pr_alert("THERMAL ALERT: unknown thermal alarm received\n"); | 3635 | pr_warn("unknown possible thermal alarm or keyboard event received\n"); |
| 3587 | known = false; | 3636 | known = false; |
| 3588 | } | 3637 | } |
| 3589 | 3638 | ||
| @@ -3652,15 +3701,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
| 3652 | } | 3701 | } |
| 3653 | break; | 3702 | break; |
| 3654 | case 4: | 3703 | case 4: |
| 3655 | /* 0x4000-0x4FFF: dock-related wakeups */ | 3704 | /* 0x4000-0x4FFF: dock-related events */ |
| 3656 | if (hkey == TP_HKEY_EV_UNDOCK_ACK) { | 3705 | known_ev = hotkey_notify_dockevent(hkey, &send_acpi_ev, |
| 3657 | hotkey_autosleep_ack = 1; | 3706 | &ignore_acpi_ev); |
| 3658 | pr_info("undocked\n"); | ||
| 3659 | hotkey_wakeup_hotunplug_complete_notify_change(); | ||
| 3660 | known_ev = true; | ||
| 3661 | } else { | ||
| 3662 | known_ev = false; | ||
| 3663 | } | ||
| 3664 | break; | 3707 | break; |
| 3665 | case 5: | 3708 | case 5: |
| 3666 | /* 0x5000-0x5FFF: human interface helpers */ | 3709 | /* 0x5000-0x5FFF: human interface helpers */ |
| @@ -3668,8 +3711,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
| 3668 | &ignore_acpi_ev); | 3711 | &ignore_acpi_ev); |
| 3669 | break; | 3712 | break; |
| 3670 | case 6: | 3713 | case 6: |
| 3671 | /* 0x6000-0x6FFF: thermal alarms */ | 3714 | /* 0x6000-0x6FFF: thermal alarms/notices and |
| 3672 | known_ev = hotkey_notify_thermal(hkey, &send_acpi_ev, | 3715 | * keyboard events */ |
| 3716 | known_ev = hotkey_notify_6xxx(hkey, &send_acpi_ev, | ||
| 3673 | &ignore_acpi_ev); | 3717 | &ignore_acpi_ev); |
| 3674 | break; | 3718 | break; |
| 3675 | case 7: | 3719 | case 7: |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 35f9154615fa..3e2989976297 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -649,9 +649,9 @@ cifs_do_mount(struct file_system_type *fs_type, | |||
| 649 | 649 | ||
| 650 | cFYI(1, "Devname: %s flags: %d ", dev_name, flags); | 650 | cFYI(1, "Devname: %s flags: %d ", dev_name, flags); |
| 651 | 651 | ||
| 652 | rc = cifs_setup_volume_info(&volume_info, (char *)data, dev_name); | 652 | volume_info = cifs_get_volume_info((char *)data, dev_name); |
| 653 | if (rc) | 653 | if (IS_ERR(volume_info)) |
| 654 | return ERR_PTR(rc); | 654 | return ERR_CAST(volume_info); |
| 655 | 655 | ||
| 656 | cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); | 656 | cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); |
| 657 | if (cifs_sb == NULL) { | 657 | if (cifs_sb == NULL) { |
| @@ -713,7 +713,7 @@ cifs_do_mount(struct file_system_type *fs_type, | |||
| 713 | out_super: | 713 | out_super: |
| 714 | deactivate_locked_super(sb); | 714 | deactivate_locked_super(sb); |
| 715 | out: | 715 | out: |
| 716 | cifs_cleanup_volume_info(&volume_info); | 716 | cifs_cleanup_volume_info(volume_info); |
| 717 | return root; | 717 | return root; |
| 718 | 718 | ||
| 719 | out_mountdata: | 719 | out_mountdata: |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 257f312ede42..8df28e925e5b 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -154,9 +154,9 @@ extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, | |||
| 154 | extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | 154 | extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, |
| 155 | struct cifs_sb_info *cifs_sb); | 155 | struct cifs_sb_info *cifs_sb); |
| 156 | extern int cifs_match_super(struct super_block *, void *); | 156 | extern int cifs_match_super(struct super_block *, void *); |
| 157 | extern void cifs_cleanup_volume_info(struct smb_vol **pvolume_info); | 157 | extern void cifs_cleanup_volume_info(struct smb_vol *pvolume_info); |
| 158 | extern int cifs_setup_volume_info(struct smb_vol **pvolume_info, | 158 | extern struct smb_vol *cifs_get_volume_info(char *mount_data, |
| 159 | char *mount_data, const char *devname); | 159 | const char *devname); |
| 160 | extern int cifs_mount(struct cifs_sb_info *, struct smb_vol *); | 160 | extern int cifs_mount(struct cifs_sb_info *, struct smb_vol *); |
| 161 | extern void cifs_umount(struct cifs_sb_info *); | 161 | extern void cifs_umount(struct cifs_sb_info *); |
| 162 | extern void cifs_dfs_release_automount_timer(void); | 162 | extern void cifs_dfs_release_automount_timer(void); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index c8cb83ef6f6f..dbd669cc5bc7 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -65,6 +65,8 @@ static int ip_connect(struct TCP_Server_Info *server); | |||
| 65 | static int generic_ip_connect(struct TCP_Server_Info *server); | 65 | static int generic_ip_connect(struct TCP_Server_Info *server); |
| 66 | static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); | 66 | static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); |
| 67 | static void cifs_prune_tlinks(struct work_struct *work); | 67 | static void cifs_prune_tlinks(struct work_struct *work); |
| 68 | static int cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data, | ||
| 69 | const char *devname); | ||
| 68 | 70 | ||
| 69 | /* | 71 | /* |
| 70 | * cifs tcp session reconnection | 72 | * cifs tcp session reconnection |
| @@ -2240,8 +2242,8 @@ cifs_match_super(struct super_block *sb, void *data) | |||
| 2240 | 2242 | ||
| 2241 | rc = compare_mount_options(sb, mnt_data); | 2243 | rc = compare_mount_options(sb, mnt_data); |
| 2242 | out: | 2244 | out: |
| 2243 | cifs_put_tlink(tlink); | ||
| 2244 | spin_unlock(&cifs_tcp_ses_lock); | 2245 | spin_unlock(&cifs_tcp_ses_lock); |
| 2246 | cifs_put_tlink(tlink); | ||
| 2245 | return rc; | 2247 | return rc; |
| 2246 | } | 2248 | } |
| 2247 | 2249 | ||
| @@ -2830,15 +2832,9 @@ is_path_accessible(int xid, struct cifs_tcon *tcon, | |||
| 2830 | return rc; | 2832 | return rc; |
| 2831 | } | 2833 | } |
| 2832 | 2834 | ||
| 2833 | void | 2835 | static void |
| 2834 | cifs_cleanup_volume_info(struct smb_vol **pvolume_info) | 2836 | cleanup_volume_info_contents(struct smb_vol *volume_info) |
| 2835 | { | 2837 | { |
| 2836 | struct smb_vol *volume_info; | ||
| 2837 | |||
| 2838 | if (!pvolume_info || !*pvolume_info) | ||
| 2839 | return; | ||
| 2840 | |||
| 2841 | volume_info = *pvolume_info; | ||
| 2842 | kfree(volume_info->username); | 2838 | kfree(volume_info->username); |
| 2843 | kzfree(volume_info->password); | 2839 | kzfree(volume_info->password); |
| 2844 | kfree(volume_info->UNC); | 2840 | kfree(volume_info->UNC); |
| @@ -2846,28 +2842,44 @@ cifs_cleanup_volume_info(struct smb_vol **pvolume_info) | |||
| 2846 | kfree(volume_info->domainname); | 2842 | kfree(volume_info->domainname); |
| 2847 | kfree(volume_info->iocharset); | 2843 | kfree(volume_info->iocharset); |
| 2848 | kfree(volume_info->prepath); | 2844 | kfree(volume_info->prepath); |
| 2845 | } | ||
| 2846 | |||
| 2847 | void | ||
| 2848 | cifs_cleanup_volume_info(struct smb_vol *volume_info) | ||
| 2849 | { | ||
| 2850 | if (!volume_info) | ||
| 2851 | return; | ||
| 2852 | cleanup_volume_info_contents(volume_info); | ||
| 2849 | kfree(volume_info); | 2853 | kfree(volume_info); |
| 2850 | *pvolume_info = NULL; | ||
| 2851 | return; | ||
| 2852 | } | 2854 | } |
| 2853 | 2855 | ||
| 2856 | |||
| 2854 | #ifdef CONFIG_CIFS_DFS_UPCALL | 2857 | #ifdef CONFIG_CIFS_DFS_UPCALL |
| 2855 | /* build_path_to_root returns full path to root when | 2858 | /* build_path_to_root returns full path to root when |
| 2856 | * we do not have an exiting connection (tcon) */ | 2859 | * we do not have an exiting connection (tcon) */ |
| 2857 | static char * | 2860 | static char * |
| 2858 | build_unc_path_to_root(const struct smb_vol *volume_info, | 2861 | build_unc_path_to_root(const struct smb_vol *vol, |
| 2859 | const struct cifs_sb_info *cifs_sb) | 2862 | const struct cifs_sb_info *cifs_sb) |
| 2860 | { | 2863 | { |
| 2861 | char *full_path; | 2864 | char *full_path, *pos; |
| 2865 | unsigned int pplen = vol->prepath ? strlen(vol->prepath) : 0; | ||
| 2866 | unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1); | ||
| 2862 | 2867 | ||
| 2863 | int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1); | 2868 | full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL); |
| 2864 | full_path = kmalloc(unc_len + 1, GFP_KERNEL); | ||
| 2865 | if (full_path == NULL) | 2869 | if (full_path == NULL) |
| 2866 | return ERR_PTR(-ENOMEM); | 2870 | return ERR_PTR(-ENOMEM); |
| 2867 | 2871 | ||
| 2868 | strncpy(full_path, volume_info->UNC, unc_len); | 2872 | strncpy(full_path, vol->UNC, unc_len); |
| 2869 | full_path[unc_len] = 0; /* add trailing null */ | 2873 | pos = full_path + unc_len; |
| 2874 | |||
| 2875 | if (pplen) { | ||
| 2876 | strncpy(pos, vol->prepath, pplen); | ||
| 2877 | pos += pplen; | ||
| 2878 | } | ||
| 2879 | |||
| 2880 | *pos = '\0'; /* add trailing null */ | ||
| 2870 | convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); | 2881 | convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); |
| 2882 | cFYI(1, "%s: full_path=%s", __func__, full_path); | ||
| 2871 | return full_path; | 2883 | return full_path; |
| 2872 | } | 2884 | } |
| 2873 | 2885 | ||
| @@ -2910,15 +2922,18 @@ expand_dfs_referral(int xid, struct cifs_ses *pSesInfo, | |||
| 2910 | &fake_devname); | 2922 | &fake_devname); |
| 2911 | 2923 | ||
| 2912 | free_dfs_info_array(referrals, num_referrals); | 2924 | free_dfs_info_array(referrals, num_referrals); |
| 2913 | kfree(fake_devname); | ||
| 2914 | |||
| 2915 | if (cifs_sb->mountdata != NULL) | ||
| 2916 | kfree(cifs_sb->mountdata); | ||
| 2917 | 2925 | ||
| 2918 | if (IS_ERR(mdata)) { | 2926 | if (IS_ERR(mdata)) { |
| 2919 | rc = PTR_ERR(mdata); | 2927 | rc = PTR_ERR(mdata); |
| 2920 | mdata = NULL; | 2928 | mdata = NULL; |
| 2929 | } else { | ||
| 2930 | cleanup_volume_info_contents(volume_info); | ||
| 2931 | memset(volume_info, '\0', sizeof(*volume_info)); | ||
| 2932 | rc = cifs_setup_volume_info(volume_info, mdata, | ||
| 2933 | fake_devname); | ||
| 2921 | } | 2934 | } |
| 2935 | kfree(fake_devname); | ||
| 2936 | kfree(cifs_sb->mountdata); | ||
| 2922 | cifs_sb->mountdata = mdata; | 2937 | cifs_sb->mountdata = mdata; |
| 2923 | } | 2938 | } |
| 2924 | kfree(full_path); | 2939 | kfree(full_path); |
| @@ -2926,33 +2941,20 @@ expand_dfs_referral(int xid, struct cifs_ses *pSesInfo, | |||
| 2926 | } | 2941 | } |
| 2927 | #endif | 2942 | #endif |
| 2928 | 2943 | ||
| 2929 | int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data, | 2944 | static int |
| 2930 | const char *devname) | 2945 | cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data, |
| 2946 | const char *devname) | ||
| 2931 | { | 2947 | { |
| 2932 | struct smb_vol *volume_info; | ||
| 2933 | int rc = 0; | 2948 | int rc = 0; |
| 2934 | 2949 | ||
| 2935 | *pvolume_info = NULL; | 2950 | if (cifs_parse_mount_options(mount_data, devname, volume_info)) |
| 2936 | 2951 | return -EINVAL; | |
| 2937 | volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL); | ||
| 2938 | if (!volume_info) { | ||
| 2939 | rc = -ENOMEM; | ||
| 2940 | goto out; | ||
| 2941 | } | ||
| 2942 | |||
| 2943 | if (cifs_parse_mount_options(mount_data, devname, | ||
| 2944 | volume_info)) { | ||
| 2945 | rc = -EINVAL; | ||
| 2946 | goto out; | ||
| 2947 | } | ||
| 2948 | 2952 | ||
| 2949 | if (volume_info->nullauth) { | 2953 | if (volume_info->nullauth) { |
| 2950 | cFYI(1, "null user"); | 2954 | cFYI(1, "null user"); |
| 2951 | volume_info->username = kzalloc(1, GFP_KERNEL); | 2955 | volume_info->username = kzalloc(1, GFP_KERNEL); |
| 2952 | if (volume_info->username == NULL) { | 2956 | if (volume_info->username == NULL) |
| 2953 | rc = -ENOMEM; | 2957 | return -ENOMEM; |
| 2954 | goto out; | ||
| 2955 | } | ||
| 2956 | } else if (volume_info->username) { | 2958 | } else if (volume_info->username) { |
| 2957 | /* BB fixme parse for domain name here */ | 2959 | /* BB fixme parse for domain name here */ |
| 2958 | cFYI(1, "Username: %s", volume_info->username); | 2960 | cFYI(1, "Username: %s", volume_info->username); |
| @@ -2960,8 +2962,7 @@ int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data, | |||
| 2960 | cifserror("No username specified"); | 2962 | cifserror("No username specified"); |
| 2961 | /* In userspace mount helper we can get user name from alternate | 2963 | /* In userspace mount helper we can get user name from alternate |
| 2962 | locations such as env variables and files on disk */ | 2964 | locations such as env variables and files on disk */ |
| 2963 | rc = -EINVAL; | 2965 | return -EINVAL; |
| 2964 | goto out; | ||
| 2965 | } | 2966 | } |
| 2966 | 2967 | ||
| 2967 | /* this is needed for ASCII cp to Unicode converts */ | 2968 | /* this is needed for ASCII cp to Unicode converts */ |
| @@ -2973,18 +2974,32 @@ int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data, | |||
| 2973 | if (volume_info->local_nls == NULL) { | 2974 | if (volume_info->local_nls == NULL) { |
| 2974 | cERROR(1, "CIFS mount error: iocharset %s not found", | 2975 | cERROR(1, "CIFS mount error: iocharset %s not found", |
| 2975 | volume_info->iocharset); | 2976 | volume_info->iocharset); |
| 2976 | rc = -ELIBACC; | 2977 | return -ELIBACC; |
| 2977 | goto out; | ||
| 2978 | } | 2978 | } |
| 2979 | } | 2979 | } |
| 2980 | 2980 | ||
| 2981 | *pvolume_info = volume_info; | ||
| 2982 | return rc; | ||
| 2983 | out: | ||
| 2984 | cifs_cleanup_volume_info(&volume_info); | ||
| 2985 | return rc; | 2981 | return rc; |
| 2986 | } | 2982 | } |
| 2987 | 2983 | ||
| 2984 | struct smb_vol * | ||
| 2985 | cifs_get_volume_info(char *mount_data, const char *devname) | ||
| 2986 | { | ||
| 2987 | int rc; | ||
| 2988 | struct smb_vol *volume_info; | ||
| 2989 | |||
| 2990 | volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL); | ||
| 2991 | if (!volume_info) | ||
| 2992 | return ERR_PTR(-ENOMEM); | ||
| 2993 | |||
| 2994 | rc = cifs_setup_volume_info(volume_info, mount_data, devname); | ||
| 2995 | if (rc) { | ||
| 2996 | cifs_cleanup_volume_info(volume_info); | ||
| 2997 | volume_info = ERR_PTR(rc); | ||
| 2998 | } | ||
| 2999 | |||
| 3000 | return volume_info; | ||
| 3001 | } | ||
| 3002 | |||
| 2988 | int | 3003 | int |
| 2989 | cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) | 3004 | cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) |
| 2990 | { | 3005 | { |
| @@ -2997,6 +3012,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) | |||
| 2997 | struct tcon_link *tlink; | 3012 | struct tcon_link *tlink; |
| 2998 | #ifdef CONFIG_CIFS_DFS_UPCALL | 3013 | #ifdef CONFIG_CIFS_DFS_UPCALL |
| 2999 | int referral_walks_count = 0; | 3014 | int referral_walks_count = 0; |
| 3015 | #endif | ||
| 3000 | 3016 | ||
| 3001 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); | 3017 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); |
| 3002 | if (rc) | 3018 | if (rc) |
| @@ -3004,6 +3020,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) | |||
| 3004 | 3020 | ||
| 3005 | cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; | 3021 | cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; |
| 3006 | 3022 | ||
| 3023 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
| 3007 | try_mount_again: | 3024 | try_mount_again: |
| 3008 | /* cleanup activities if we're chasing a referral */ | 3025 | /* cleanup activities if we're chasing a referral */ |
| 3009 | if (referral_walks_count) { | 3026 | if (referral_walks_count) { |
| @@ -3012,7 +3029,6 @@ try_mount_again: | |||
| 3012 | else if (pSesInfo) | 3029 | else if (pSesInfo) |
| 3013 | cifs_put_smb_ses(pSesInfo); | 3030 | cifs_put_smb_ses(pSesInfo); |
| 3014 | 3031 | ||
| 3015 | cifs_cleanup_volume_info(&volume_info); | ||
| 3016 | FreeXid(xid); | 3032 | FreeXid(xid); |
| 3017 | } | 3033 | } |
| 3018 | #endif | 3034 | #endif |
