aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/acpica/hwsleep.c43
-rw-r--r--drivers/acpi/acpica/hwvalid.c86
-rw-r--r--drivers/acpi/acpica/rscreate.c27
-rw-r--r--drivers/acpi/button.c140
-rw-r--r--drivers/acpi/ec.c1
-rw-r--r--drivers/acpi/osl.c4
-rw-r--r--drivers/acpi/processor_idle.c28
-rw-r--r--drivers/acpi/sleep.c27
-rw-r--r--drivers/acpi/system.c11
-rw-r--r--drivers/acpi/thermal.c2
-rw-r--r--drivers/acpi/video.c51
-rw-r--r--drivers/block/umem.c1
-rw-r--r--drivers/char/hw_random/virtio-rng.c4
-rw-r--r--drivers/gpu/drm/i915/i915_opregion.c9
-rw-r--r--drivers/ide/ide-cd.c2
-rw-r--r--drivers/ide/ide-gd.c17
-rw-r--r--drivers/ide/palm_bk3710.c93
-rw-r--r--drivers/input/mouse/maplemouse.c43
-rw-r--r--drivers/macintosh/Kconfig2
-rw-r--r--drivers/macintosh/mediabay.c3
-rw-r--r--drivers/media/radio/radio-si470x.c2
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c238
-rw-r--r--drivers/mtd/nand/cafe_nand.c2
-rw-r--r--drivers/net/8139too.c10
-rw-r--r--drivers/net/Kconfig4
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c44
-rw-r--r--drivers/net/cxgb3/t3_hw.c11
-rw-r--r--drivers/net/e1000/e1000_main.c6
-rw-r--r--drivers/net/e1000e/netdev.c8
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.c28
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c54
-rw-r--r--drivers/net/macb.c28
-rw-r--r--drivers/net/macvlan.c9
-rw-r--r--drivers/net/mlx4/en_main.c5
-rw-r--r--drivers/net/mlx4/en_netdev.c21
-rw-r--r--drivers/net/mlx4/en_port.c45
-rw-r--r--drivers/net/mlx4/en_resources.c6
-rw-r--r--drivers/net/mlx4/en_rx.c12
-rw-r--r--drivers/net/mlx4/en_tx.c1
-rw-r--r--drivers/net/mlx4/mlx4_en.h1
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c2
-rw-r--r--drivers/net/ps3_gelic_wireless.c3
-rw-r--r--drivers/net/tg3.c26
-rw-r--r--drivers/net/tun.c47
-rw-r--r--drivers/net/ucc_geth.c3
-rw-r--r--drivers/net/usb/pegasus.c1
-rw-r--r--drivers/net/wireless/airo.c2
-rw-r--r--drivers/net/wireless/ar9170/hw.h8
-rw-r--r--drivers/net/wireless/ar9170/usb.c114
-rw-r--r--drivers/net/wireless/at76c50x-usb.c2
-rw-r--r--drivers/net/wireless/ath9k/recv.c4
-rw-r--r--drivers/net/wireless/atmel.c1
-rw-r--r--drivers/net/wireless/b43/dma.c50
-rw-r--r--drivers/net/wireless/b43/main.c5
-rw-r--r--drivers/net/wireless/b43/phy_common.c16
-rw-r--r--drivers/net/wireless/b43/phy_common.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c99
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c152
-rw-r--r--drivers/net/wireless/libertas/rx.c2
-rw-r--r--drivers/net/wireless/mwl8k.c7
-rw-r--r--drivers/net/wireless/orinoco/hw.c8
-rw-r--r--drivers/net/wireless/p54/p54.h12
-rw-r--r--drivers/net/wireless/p54/p54common.c2
-rw-r--r--drivers/net/wireless/p54/p54spi.c25
-rw-r--r--drivers/net/wireless/p54/p54usb.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c18
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c18
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c2
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c3
-rw-r--r--drivers/platform/x86/sony-laptop.c27
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c81
-rw-r--r--drivers/s390/char/tape.h2
-rw-r--r--drivers/s390/char/tape_34xx.c8
-rw-r--r--drivers/s390/char/tape_3590.c8
-rw-r--r--drivers/s390/char/tape_core.c5
-rw-r--r--drivers/scsi/a4000t.c2
-rw-r--r--drivers/serial/8250_pci.c2
-rw-r--r--drivers/usb/class/cdc-wdm.c27
-rw-r--r--drivers/usb/core/buffer.c2
-rw-r--r--drivers/usb/gadget/ci13xxx_udc.c5
-rw-r--r--drivers/usb/gadget/file_storage.c20
-rw-r--r--drivers/usb/gadget/omap_udc.c3
-rw-r--r--drivers/usb/host/ehci-sched.c2
-rw-r--r--drivers/usb/musb/musb_core.c2
-rw-r--r--drivers/usb/musb/omap2430.c1
-rw-r--r--drivers/usb/musb/tusb6010.c1
-rw-r--r--drivers/usb/musb/tusb6010.h1
-rw-r--r--drivers/usb/otg/otg.c3
-rw-r--r--drivers/usb/serial/cyberjack.c7
-rw-r--r--drivers/usb/serial/cypress_m8.c4
-rw-r--r--drivers/usb/serial/empeg.c6
-rw-r--r--drivers/usb/serial/garmin_gps.c8
-rw-r--r--drivers/usb/serial/generic.c6
-rw-r--r--drivers/usb/serial/io_edgeport.c8
-rw-r--r--drivers/usb/serial/io_ti.c8
-rw-r--r--drivers/usb/serial/ipaq.c6
-rw-r--r--drivers/usb/serial/ipw.c3
-rw-r--r--drivers/usb/serial/iuu_phoenix.c1
-rw-r--r--drivers/usb/serial/kobil_sct.c6
-rw-r--r--drivers/usb/serial/mos7720.c7
-rw-r--r--drivers/usb/serial/mos7840.c43
-rw-r--r--drivers/usb/serial/opticon.c8
-rw-r--r--drivers/usb/serial/option.c3
-rw-r--r--drivers/usb/serial/sierra.c24
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c14
-rw-r--r--drivers/usb/serial/usb-serial.c104
-rw-r--r--drivers/usb/serial/visor.c8
-rw-r--r--drivers/usb/storage/unusual_devs.h6
-rw-r--r--drivers/watchdog/orion5x_wdt.c1
115 files changed, 1268 insertions, 1005 deletions
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c
index baa5fc05e12..db307a356f0 100644
--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -211,6 +211,12 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
+static unsigned int gts, bfs;
+module_param(gts, uint, 0644);
+module_param(bfs, uint, 0644);
+MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend.");
+MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".);
+
/*******************************************************************************
*
* FUNCTION: acpi_enter_sleep_state
@@ -278,16 +284,18 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
return_ACPI_STATUS(status);
}
- /* Execute the _GTS method */
+ if (gts) {
+ /* Execute the _GTS method */
- arg_list.count = 1;
- arg_list.pointer = &arg;
- arg.type = ACPI_TYPE_INTEGER;
- arg.integer.value = sleep_state;
+ arg_list.count = 1;
+ arg_list.pointer = &arg;
+ arg.type = ACPI_TYPE_INTEGER;
+ arg.integer.value = sleep_state;
- status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
- if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
- return_ACPI_STATUS(status);
+ status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ return_ACPI_STATUS(status);
+ }
}
/* Get current value of PM1A control */
@@ -513,18 +521,19 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
}
}
- /* Execute the _BFS method */
+ if (bfs) {
+ /* Execute the _BFS method */
- arg_list.count = 1;
- arg_list.pointer = &arg;
- arg.type = ACPI_TYPE_INTEGER;
- arg.integer.value = sleep_state;
+ arg_list.count = 1;
+ arg_list.pointer = &arg;
+ arg.type = ACPI_TYPE_INTEGER;
+ arg.integer.value = sleep_state;
- status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
- if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
- ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
+ status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
+ }
}
-
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c
index 7737afb157c..ec33f270c5b 100644
--- a/drivers/acpi/acpica/hwvalid.c
+++ b/drivers/acpi/acpica/hwvalid.c
@@ -90,6 +90,7 @@ static const struct acpi_port_info acpi_protected_ports[] = {
{"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP},
{"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP},
{"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP},
+ {"DMA1", 0x0081, 0x0083, ACPI_OSI_WIN_XP},
{"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP},
{"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP},
{"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP},
@@ -151,7 +152,7 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
ACPI_ERROR((AE_INFO,
"Illegal I/O port address/length above 64K: 0x%p/%X",
ACPI_CAST_PTR(void, address), byte_width));
- return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
+ return_ACPI_STATUS(AE_LIMIT);
}
/* Exit if requested address is not within the protected port table */
@@ -178,11 +179,12 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
/* Port illegality may depend on the _OSI calls made by the BIOS */
if (acpi_gbl_osi_data >= port_info->osi_dependency) {
- ACPI_ERROR((AE_INFO,
- "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)",
- ACPI_CAST_PTR(void, address),
- byte_width, port_info->name,
- port_info->start, port_info->end));
+ ACPI_DEBUG_PRINT((ACPI_DB_IO,
+ "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)",
+ ACPI_CAST_PTR(void, address),
+ byte_width, port_info->name,
+ port_info->start,
+ port_info->end));
return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
}
@@ -206,7 +208,7 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
* Value Where value is placed
* Width Number of bits
*
- * RETURN: Value read from port
+ * RETURN: Status and value read from port
*
* DESCRIPTION: Read data from an I/O port or register. This is a front-end
* to acpi_os_read_port that performs validation on both the port
@@ -217,14 +219,43 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
{
acpi_status status;
+ u32 one_byte;
+ u32 i;
+
+ /* Validate the entire request and perform the I/O */
status = acpi_hw_validate_io_request(address, width);
- if (ACPI_FAILURE(status)) {
+ if (ACPI_SUCCESS(status)) {
+ status = acpi_os_read_port(address, value, width);
return status;
}
- status = acpi_os_read_port(address, value, width);
- return status;
+ if (status != AE_AML_ILLEGAL_ADDRESS) {
+ return status;
+ }
+
+ /*
+ * There has been a protection violation within the request. Fall
+ * back to byte granularity port I/O and ignore the failing bytes.
+ * This provides Windows compatibility.
+ */
+ for (i = 0, *value = 0; i < width; i += 8) {
+
+ /* Validate and read one byte */
+
+ if (acpi_hw_validate_io_request(address, 8) == AE_OK) {
+ status = acpi_os_read_port(address, &one_byte, 8);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ *value |= (one_byte << i);
+ }
+
+ address++;
+ }
+
+ return AE_OK;
}
/******************************************************************************
@@ -235,7 +266,7 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
* Value Value to write
* Width Number of bits
*
- * RETURN: None
+ * RETURN: Status
*
* DESCRIPTION: Write data to an I/O port or register. This is a front-end
* to acpi_os_write_port that performs validation on both the port
@@ -246,12 +277,39 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)
{
acpi_status status;
+ u32 i;
+
+ /* Validate the entire request and perform the I/O */
status = acpi_hw_validate_io_request(address, width);
- if (ACPI_FAILURE(status)) {
+ if (ACPI_SUCCESS(status)) {
+ status = acpi_os_write_port(address, value, width);
return status;
}
- status = acpi_os_write_port(address, value, width);
- return status;
+ if (status != AE_AML_ILLEGAL_ADDRESS) {
+ return status;
+ }
+
+ /*
+ * There has been a protection violation within the request. Fall
+ * back to byte granularity port I/O and ignore the failing bytes.
+ * This provides Windows compatibility.
+ */
+ for (i = 0; i < width; i += 8) {
+
+ /* Validate and write one byte */
+
+ if (acpi_hw_validate_io_request(address, 8) == AE_OK) {
+ status =
+ acpi_os_write_port(address, (value >> i) & 0xFF, 8);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+ }
+
+ address++;
+ }
+
+ return AE_OK;
}
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c
index 663f692fffc..a3c23d686d5 100644
--- a/drivers/acpi/acpica/rscreate.c
+++ b/drivers/acpi/acpica/rscreate.c
@@ -191,8 +191,6 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
for (index = 0; index < number_of_elements; index++) {
- int source_name_index = 2;
- int source_index_index = 3;
/*
* Point user_prt past this current structure
@@ -261,27 +259,6 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
return_ACPI_STATUS(AE_BAD_DATA);
}
- /*
- * If BIOS erroneously reversed the _PRT source_name and source_index,
- * then reverse them back.
- */
- if ((sub_object_list[3])->common.type !=
- ACPI_TYPE_INTEGER) {
- if (acpi_gbl_enable_interpreter_slack) {
- source_name_index = 3;
- source_index_index = 2;
- printk(KERN_WARNING
- "ACPI: Handling Garbled _PRT entry\n");
- } else {
- ACPI_ERROR((AE_INFO,
- "(PRT[%X].source_index) Need Integer, found %s",
- index,
- acpi_ut_get_object_type_name
- (sub_object_list[3])));
- return_ACPI_STATUS(AE_BAD_DATA);
- }
- }
-
user_prt->pin = (u32) obj_desc->integer.value;
/*
@@ -304,7 +281,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
* 3) Third subobject: Dereference the PRT.source_name
* The name may be unresolved (slack mode), so allow a null object
*/
- obj_desc = sub_object_list[source_name_index];
+ obj_desc = sub_object_list[2];
if (obj_desc) {
switch (obj_desc->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
@@ -378,7 +355,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 4) Fourth subobject: Dereference the PRT.source_index */
- obj_desc = sub_object_list[source_index_index];
+ obj_desc = sub_object_list[3];
if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].SourceIndex) Need Integer, found %s",
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index d73c94b8441..9195deba9d9 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -1,5 +1,5 @@
/*
- * acpi_button.c - ACPI Button Driver ($Revision: 30 $)
+ * button.c - ACPI Button Driver
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
@@ -41,17 +41,13 @@
#define ACPI_BUTTON_SUBCLASS_POWER "power"
#define ACPI_BUTTON_HID_POWER "PNP0C0C"
-#define ACPI_BUTTON_DEVICE_NAME_POWER "Power Button (CM)"
-#define ACPI_BUTTON_DEVICE_NAME_POWERF "Power Button (FF)"
+#define ACPI_BUTTON_DEVICE_NAME_POWER "Power Button"
#define ACPI_BUTTON_TYPE_POWER 0x01
-#define ACPI_BUTTON_TYPE_POWERF 0x02
#define ACPI_BUTTON_SUBCLASS_SLEEP "sleep"
#define ACPI_BUTTON_HID_SLEEP "PNP0C0E"
-#define ACPI_BUTTON_DEVICE_NAME_SLEEP "Sleep Button (CM)"
-#define ACPI_BUTTON_DEVICE_NAME_SLEEPF "Sleep Button (FF)"
+#define ACPI_BUTTON_DEVICE_NAME_SLEEP "Sleep Button"
#define ACPI_BUTTON_TYPE_SLEEP 0x03
-#define ACPI_BUTTON_TYPE_SLEEPF 0x04
#define ACPI_BUTTON_SUBCLASS_LID "lid"
#define ACPI_BUTTON_HID_LID "PNP0C0D"
@@ -95,7 +91,6 @@ static struct acpi_driver acpi_button_driver = {
};
struct acpi_button {
- struct acpi_device *device; /* Fixed button kludge */
unsigned int type;
struct input_dev *input;
char phys[32]; /* for input device */
@@ -126,14 +121,10 @@ static struct proc_dir_entry *acpi_button_dir;
static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_button *button = seq->private;
-
- if (!button || !button->device)
- return 0;
+ struct acpi_device *device = seq->private;
seq_printf(seq, "type: %s\n",
- acpi_device_name(button->device));
-
+ acpi_device_name(device));
return 0;
}
@@ -144,14 +135,11 @@ static int acpi_button_info_open_fs(struct inode *inode, struct file *file)
static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_button *button = seq->private;
+ struct acpi_device *device = seq->private;
acpi_status status;
unsigned long long state;
- if (!button || !button->device)
- return 0;
-
- status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, &state);
+ status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state);
seq_printf(seq, "state: %s\n",
ACPI_FAILURE(status) ? "unsupported" :
(state ? "open" : "closed"));
@@ -169,24 +157,17 @@ static struct proc_dir_entry *acpi_lid_dir;
static int acpi_button_add_fs(struct acpi_device *device)
{
+ struct acpi_button *button = acpi_driver_data(device);
struct proc_dir_entry *entry = NULL;
- struct acpi_button *button;
-
- if (!device || !acpi_driver_data(device))
- return -EINVAL;
-
- button = acpi_driver_data(device);
switch (button->type) {
case ACPI_BUTTON_TYPE_POWER:
- case ACPI_BUTTON_TYPE_POWERF:
if (!acpi_power_dir)
acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER,
acpi_button_dir);
entry = acpi_power_dir;
break;
case ACPI_BUTTON_TYPE_SLEEP:
- case ACPI_BUTTON_TYPE_SLEEPF:
if (!acpi_sleep_dir)
acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP,
acpi_button_dir);
@@ -210,8 +191,7 @@ static int acpi_button_add_fs(struct acpi_device *device)
/* 'info' [R] */
entry = proc_create_data(ACPI_BUTTON_FILE_INFO,
S_IRUGO, acpi_device_dir(device),
- &acpi_button_info_fops,
- acpi_driver_data(device));
+ &acpi_button_info_fops, device);
if (!entry)
return -ENODEV;
@@ -219,8 +199,7 @@ static int acpi_button_add_fs(struct acpi_device *device)
if (button->type == ACPI_BUTTON_TYPE_LID) {
entry = proc_create_data(ACPI_BUTTON_FILE_STATE,
S_IRUGO, acpi_device_dir(device),
- &acpi_button_state_fops,
- acpi_driver_data(device));
+ &acpi_button_state_fops, device);
if (!entry)
return -ENODEV;
}
@@ -250,15 +229,16 @@ static int acpi_button_remove_fs(struct acpi_device *device)
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
-static int acpi_lid_send_state(struct acpi_button *button)
+static int acpi_lid_send_state(struct acpi_device *device)
{
+ struct acpi_button *button = acpi_driver_data(device);
unsigned long long state;
acpi_status status;
- status = acpi_evaluate_integer(button->device->handle, "_LID", NULL,
- &state);
+ status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state);
if (ACPI_FAILURE(status))
return -ENODEV;
+
/* input layer checks if event is redundant */
input_report_switch(button->input, SW_LID, !state);
input_sync(button->input);
@@ -270,9 +250,6 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
struct acpi_button *button = acpi_driver_data(device);
struct input_dev *input;
- if (!button || !button->device)
- return;
-
switch (event) {
case ACPI_FIXED_HARDWARE_EVENT:
event = ACPI_BUTTON_NOTIFY_STATUS;
@@ -280,7 +257,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
case ACPI_BUTTON_NOTIFY_STATUS:
input = button->input;
if (button->type == ACPI_BUTTON_TYPE_LID) {
- acpi_lid_send_state(button);
+ acpi_lid_send_state(device);
} else {
int keycode = test_bit(KEY_SLEEP, input->keybit) ?
KEY_SLEEP : KEY_POWER;
@@ -291,43 +268,35 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
input_sync(input);
}
- acpi_bus_generate_proc_event(button->device, event,
- ++button->pushed);
+ acpi_bus_generate_proc_event(device, event, ++button->pushed);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
break;
}
-
- return;
}
static int acpi_button_resume(struct acpi_device *device)
{
- struct acpi_button *button;
- if (!device)
- return -EINVAL;
- button = acpi_driver_data(device);
- if (button && button->type == ACPI_BUTTON_TYPE_LID)
- return acpi_lid_send_state(button);
+ struct acpi_button *button = acpi_driver_data(device);
+
+ if (button->type == ACPI_BUTTON_TYPE_LID)
+ return acpi_lid_send_state(device);
return 0;
}
static int acpi_button_add(struct acpi_device *device)
{
- int error;
struct acpi_button *button;
struct input_dev *input;
-
- if (!device)
- return -EINVAL;
+ char *hid, *name, *class;
+ int error;
button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
if (!button)
return -ENOMEM;
- button->device = device;
device->driver_data = button;
button->input = input = input_allocate_device();
@@ -336,40 +305,29 @@ static int acpi_button_add(struct acpi_device *device)
goto err_free_button;
}
- /*
- * Determine the button type (via hid), as fixed-feature buttons
- * need to be handled a bit differently than generic-space.
- */
- if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWER)) {
+ hid = acpi_device_hid(device);
+ name = acpi_device_name(device);
+ class = acpi_device_class(device);
+
+ if (!strcmp(hid, ACPI_BUTTON_HID_POWER) ||
+ !strcmp(hid, ACPI_BUTTON_HID_POWERF)) {
button->type = ACPI_BUTTON_TYPE_POWER;
- strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_POWER);
- sprintf(acpi_device_class(device), "%s/%s",
- ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
- } else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF)) {
- button->type = ACPI_BUTTON_TYPE_POWERF;
- strcpy(acpi_device_name(device),
- ACPI_BUTTON_DEVICE_NAME_POWERF);
- sprintf(acpi_device_class(device), "%s/%s",
+ strcpy(name, ACPI_BUTTON_DEVICE_NAME_POWER);
+ sprintf(class, "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
- } else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEP)) {
+ } else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEP) ||
+ !strcmp(hid, ACPI_BUTTON_HID_SLEEPF)) {
button->type = ACPI_BUTTON_TYPE_SLEEP;
- strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_SLEEP);
- sprintf(acpi_device_class(device), "%s/%s",
- ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
- } else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF)) {
- button->type = ACPI_BUTTON_TYPE_SLEEPF;
- strcpy(acpi_device_name(device),
- ACPI_BUTTON_DEVICE_NAME_SLEEPF);
- sprintf(acpi_device_class(device), "%s/%s",
+ strcpy(name, ACPI_BUTTON_DEVICE_NAME_SLEEP);
+ sprintf(class, "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
- } else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_LID)) {
+ } else if (!strcmp(hid, ACPI_BUTTON_HID_LID)) {
button->type = ACPI_BUTTON_TYPE_LID;
- strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_LID);
- sprintf(acpi_device_class(device), "%s/%s",
+ strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID);
+ sprintf(class, "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID);
} else {
- printk(KERN_ERR PREFIX "Unsupported hid [%s]\n",
- acpi_device_hid(device));
+ printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid);
error = -ENODEV;
goto err_free_input;
}
@@ -378,10 +336,9 @@ static int acpi_button_add(struct acpi_device *device)
if (error)
goto err_free_input;
- snprintf(button->phys, sizeof(button->phys),
- "%s/button/input0", acpi_device_hid(device));
+ snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid);
- input->name = acpi_device_name(device);
+ input->name = name;
input->phys = button->phys;
input->id.bustype = BUS_HOST;
input->id.product = button->type;
@@ -389,13 +346,11 @@ static int acpi_button_add(struct acpi_device *device)
switch (button->type) {
case ACPI_BUTTON_TYPE_POWER:
- case ACPI_BUTTON_TYPE_POWERF:
input->evbit[0] = BIT_MASK(EV_KEY);
set_bit(KEY_POWER, input->keybit);
break;
case ACPI_BUTTON_TYPE_SLEEP:
- case ACPI_BUTTON_TYPE_SLEEPF:
input->evbit[0] = BIT_MASK(EV_KEY);
set_bit(KEY_SLEEP, input->keybit);
break;
@@ -410,7 +365,7 @@ static int acpi_button_add(struct acpi_device *device)
if (error)
goto err_remove_fs;
if (button->type == ACPI_BUTTON_TYPE_LID)
- acpi_lid_send_state(button);
+ acpi_lid_send_state(device);
if (device->wakeup.flags.valid) {
/* Button's GPE is run-wake GPE */
@@ -422,9 +377,7 @@ static int acpi_button_add(struct acpi_device *device)
device->wakeup.state.enabled = 1;
}
- printk(KERN_INFO PREFIX "%s [%s]\n",
- acpi_device_name(device), acpi_device_bid(device));
-
+ printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
return 0;
err_remove_fs:
@@ -438,17 +391,11 @@ static int acpi_button_add(struct acpi_device *device)
static int acpi_button_remove(struct acpi_device *device, int type)
{
- struct acpi_button *button;
-
- if (!device || !acpi_driver_data(device))
- return -EINVAL;
-
- button = acpi_driver_data(device);
+ struct acpi_button *button = acpi_driver_data(device);
acpi_button_remove_fs(device);
input_unregister_device(button->input);
kfree(button);
-
return 0;
}
@@ -459,6 +406,7 @@ static int __init acpi_button_init(void)
acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
if (!acpi_button_dir)
return -ENODEV;
+
result = acpi_bus_register_driver(&acpi_button_driver);
if (result < 0) {
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 04e90443eff..391f331674c 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1065,6 +1065,7 @@ static int acpi_ec_resume(struct acpi_device *device)
struct acpi_ec *ec = acpi_driver_data(device);
/* Enable use of GPE back */
clear_bit(EC_FLAGS_NO_GPE, &ec->flags);
+ set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
acpi_enable_gpe(NULL, ec->gpe);
return 0;
}
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index d59f08ecaf1..d916bea729f 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -353,8 +353,10 @@ static irqreturn_t acpi_irq(int irq, void *dev_id)
if (handled) {
acpi_irq_handled++;
return IRQ_HANDLED;
- } else
+ } else {
+ acpi_irq_not_handled++;
return IRQ_NONE;
+ }
}
acpi_status
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 6fe121434ff..f7ca8c55956 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -581,6 +581,11 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
struct acpi_processor_cx *cx = &pr->power.states[i];
+#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
+ /* TSC could halt in idle, so notify users */
+ if (tsc_halts_in_c(cx->type))
+ mark_tsc_unstable("TSC halts in idle");;
+#endif
switch (cx->type) {
case ACPI_STATE_C1:
cx->valid = 1;
@@ -657,11 +662,9 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
seq_printf(seq, "active state: C%zd\n"
"max_cstate: C%d\n"
- "bus master activity: %08x\n"
"maximum allowed latency: %d usec\n",
pr->power.state ? pr->power.state - pr->power.states : 0,
- max_cstate, (unsigned)pr->power.bm_activity,
- pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
+ max_cstate, pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
seq_puts(seq, "states:\n");
@@ -871,11 +874,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
kt2 = ktime_get_real();
idle_time = ktime_to_us(ktime_sub(kt2, kt1));
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
- /* TSC could halt in idle, so notify users */
- if (tsc_halts_in_c(cx->type))
- mark_tsc_unstable("TSC halts in idle");;
-#endif
sleep_ticks = us_to_pm_timer_ticks(idle_time);
/* Tell the scheduler how much we idled: */
@@ -955,6 +953,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
*/
acpi_state_timer_broadcast(pr, cx, 1);
+ kt1 = ktime_get_real();
/*
* disable bus master
* bm_check implies we need ARB_DIS
@@ -976,10 +975,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
ACPI_FLUSH_CPU_CACHE();
}
- kt1 = ktime_get_real();
acpi_idle_do_entry(cx);
- kt2 = ktime_get_real();
- idle_time = ktime_to_us(ktime_sub(kt2, kt1));
/* Re-enable bus master arbitration */
if (pr->flags.bm_check && pr->flags.bm_control) {
@@ -988,12 +984,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
c3_cpu_count--;
spin_unlock(&c3_lock);
}
+ kt2 = ktime_get_real();
+ idle_time = ktime_to_us(ktime_sub(kt2, kt1));
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
- /* TSC could halt in idle, so notify users */
- if (tsc_halts_in_c(ACPI_STATE_C3))
- mark_tsc_unstable("TSC halts in idle");
-#endif
sleep_ticks = us_to_pm_timer_ticks(idle_time);
/* Tell the scheduler how much we idled: */
sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
@@ -1037,6 +1030,9 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
dev->states[i].desc[0] = '\0';
}
+ if (max_cstate == 0)
+ max_cstate = 1;
+
for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
cx = &pr->power.states[i];
state = &dev->states[count];
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index d060e6fd7fd..01574a06653 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -713,6 +713,32 @@ static void acpi_power_off(void)
acpi_enter_sleep_state(ACPI_STATE_S5);
}
+/*
+ * ACPI 2.0 created the optional _GTS and _BFS,
+ * but industry adoption has been neither rapid nor broad.
+ *
+ * Linux gets into trouble when it executes poorly validated
+ * paths through the BIOS, so disable _GTS and _BFS by default,
+ * but do speak up and offer the option to enable them.
+ */
+void __init acpi_gts_bfs_check(void)
+{
+ acpi_handle dummy;
+
+ if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__GTS, &dummy)))
+ {
+ printk(KERN_NOTICE PREFIX "BIOS offers _GTS\n");
+ printk(KERN_NOTICE PREFIX "If \"acpi.gts=1\" improves suspend, "
+ "please notify linux-acpi@vger.kernel.org\n");
+ }
+ if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__BFS, &dummy)))
+ {
+ printk(KERN_NOTICE PREFIX "BIOS offers _BFS\n");
+ printk(KERN_NOTICE PREFIX "If \"acpi.bfs=1\" improves resume, "
+ "please notify linux-acpi@vger.kernel.org\n");
+ }
+}
+
int __init acpi_sleep_init(void)
{
acpi_status status;
@@ -771,5 +797,6 @@ int __init acpi_sleep_init(void)
* object can also be evaluated when the system enters S5.
*/
register_reboot_notifier(&tts_notifier);
+ acpi_gts_bfs_check();
return 0;
}
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index da51f05ef8d..0944daec064 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -38,6 +38,7 @@ ACPI_MODULE_NAME("system");
#define ACPI_SYSTEM_DEVICE_NAME "System"
u32 acpi_irq_handled;
+u32 acpi_irq_not_handled;
/*
* Make ACPICA version work as module param
@@ -214,8 +215,9 @@ err:
#define COUNT_GPE 0
#define COUNT_SCI 1 /* acpi_irq_handled */
-#define COUNT_ERROR 2 /* other */
-#define NUM_COUNTERS_EXTRA 3
+#define COUNT_SCI_NOT 2 /* acpi_irq_not_handled */
+#define COUNT_ERROR 3 /* other */
+#define NUM_COUNTERS_EXTRA 4
struct event_counter {
u32 count;
@@ -317,6 +319,8 @@ static ssize_t counter_show(struct kobject *kobj,
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count =
acpi_irq_handled;
+ all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count =
+ acpi_irq_not_handled;
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count =
acpi_gpe_count;
@@ -363,6 +367,7 @@ static ssize_t counter_set(struct kobject *kobj,
all_counters[i].count = 0;
acpi_gpe_count = 0;
acpi_irq_handled = 0;
+ acpi_irq_not_handled = 0;
goto end;
}
@@ -456,6 +461,8 @@ void acpi_irq_stats_init(void)
sprintf(buffer, "gpe_all");
else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI)
sprintf(buffer, "sci");
+ else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT)
+ sprintf(buffer, "sci_not");
else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR)
sprintf(buffer, "error");
else
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 9cd15e8c893..564ea142428 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -909,7 +909,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
thermal_zone_device_register("acpitz", trips, tz,
&acpi_thermal_zone_ops,
0, 0, 0,
- tz->polling_frequency);
+ tz->polling_frequency*100);
if (IS_ERR(tz->thermal_zone))
return -ENODEV;
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index cd4fb7543a9..1705d947ea0 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -770,10 +770,12 @@ acpi_video_init_brightness(struct acpi_video_device *device)
* In this case, the first two elements in _BCL packages
* are also supported brightness levels that OS should take care of.
*/
- for (i = 2; i < count; i++)
- if (br->levels[i] == br->levels[0] ||
- br->levels[i] == br->levels[1])
+ for (i = 2; i < count; i++) {
+ if (br->levels[i] == br->levels[0])
level_ac_battery++;
+ if (br->levels[i] == br->levels[1])
+ level_ac_battery++;
+ }
if (level_ac_battery < 2) {
level_ac_battery = 2 - level_ac_battery;
@@ -807,12 +809,19 @@ acpi_video_init_brightness(struct acpi_video_device *device)
br->flags._BCM_use_index = br->flags._BCL_use_index;
/* _BQC uses INDEX while _BCL uses VALUE in some laptops */
- br->curr = max_level;
+ br->curr = level_old = max_level;
+
+ if (!device->cap._BQC)
+ goto set_level;
+
result = acpi_video_device_lcd_get_level_current(device, &level_old);
if (result)
goto out_free_levels;
- result = acpi_video_device_lcd_set_level(device, br->curr);
+ /*
+ * Set the level to maximum and check if _BQC uses indexed value
+ */
+ result = acpi_video_device_lcd_set_level(device, max_level);
if (result)
goto out_free_levels;
@@ -820,25 +829,19 @@ acpi_video_init_brightness(struct acpi_video_device *device)
if (result)
goto out_free_levels;
- if ((level != level_old) && !br->flags._BCM_use_index) {
- /* Note:
- * This piece of code does not work correctly if the current
- * brightness levels is 0.
- * But I guess boxes that boot with such a dark screen are rare
- * and no more code is needed to cover this specifial case.
- */
-
- if (level_ac_battery != 2) {
- /*
- * For now, we don't support the _BCL like this:
- * 16, 15, 0, 1, 2, 3, ..., 14, 15, 16
- * because we may mess up the index returned by _BQC.
- * Plus: we have not got a box like this.
- */
- ACPI_ERROR((AE_INFO, "_BCL not supported\n"));
- }
- br->flags._BQC_use_index = 1;
- }
+ br->flags._BQC_use_index = (level == max_level ? 0 : 1);
+
+ if (!br->flags._BQC_use_index)
+ goto set_level;
+
+ if (br->flags._BCL_reversed)
+ level_old = (br->count - 1) - level_old;
+ level_old = br->levels[level_old];
+
+set_level:
+ result = acpi_video_device_lcd_set_level(device, level_old);
+ if (result)
+ goto out_free_levels;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"found %d brightness levels\n", count - 2));
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 9744d59a69f..858c34dd032 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -906,6 +906,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev,
goto failed_alloc;
blk_queue_make_request(card->queue, mm_make_request);
+ card->queue->queue_lock = &card->lock;
card->queue->queuedata = card;
card->queue->unplug_fn = mm_unplug_device;
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index d0e563e4fc3..86e83f88313 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -37,9 +37,9 @@ static void random_recv_done(struct virtqueue *vq)
{
int len;
- /* We never get spurious callbacks. */
+ /* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */
if (!vq->vq_ops->get_buf(vq, &len))
- BUG();
+ return;
data_left = len / sizeof(random_data[0]);
complete(&have_data);
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index 69427722d20..8dc1fd3115c 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -370,11 +370,8 @@ int intel_opregion_init(struct drm_device *dev, int resume)
if (mboxes & MBOX_ACPI) {
DRM_DEBUG("Public ACPI methods supported\n");
opregion->acpi = base + OPREGION_ACPI_OFFSET;
- if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
intel_didl_outputs(dev);
- if (!resume)
- acpi_video_register();
- }
} else {
DRM_DEBUG("Public ACPI methods not supported\n");
err = -ENOTSUPP;
@@ -391,6 +388,10 @@ int intel_opregion_init(struct drm_device *dev, int resume)
opregion->asle = base + OPREGION_ASLE_OFFSET;
}
+ if (!resume)
+ acpi_video_register();
+
+
/* Notify BIOS we are ready to handle ACPI video ext notifs.
* Right now, all the events are handled by the ACPI video module.
* We don't actually need to do anything with them. */
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 3aec19d1fdf..3d4e0996976 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -609,7 +609,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
struct request *rq = hwif->rq;
ide_expiry_t *expiry = NULL;
int dma_error = 0, dma, thislen, uptodate = 0;
- int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc, nsectors;
+ int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0, nsectors;
int sense = blk_sense_request(rq);
unsigned int timeout;
u16 len;
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index 1aebdf1a4f5..4b6b71e2cdf 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -7,6 +7,7 @@
#include <linux/mutex.h>
#include <linux/ide.h>
#include <linux/hdreg.h>
+#include <linux/dmi.h>
#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
#define IDE_DISK_MINORS (1 << PARTN_BITS)
@@ -99,6 +100,19 @@ static void ide_gd_resume(ide_drive_t *drive)
(void)drive->disk_ops->get_capacity(drive);
}
+static const struct dmi_system_id ide_coldreboot_table[] = {
+ {
+ /* Acer TravelMate 66x cuts power during reboot */
+ .ident = "Acer TravelMate 660",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
+ },
+ },
+
+ { } /* terminate list */
+};
+
static void ide_gd_shutdown(ide_drive_t *drive)
{
#ifdef CONFIG_ALPHA
@@ -115,7 +129,8 @@ static void ide_gd_shutdown(ide_drive_t *drive)
the disk to expire its write cache. */
if (system_state != SYSTEM_POWER_OFF) {
#else
- if (system_state == SYSTEM_RESTART) {
+ if (system_state == SYSTEM_RESTART &&
+ !dmi_check_system(ide_coldreboot_table)) {
#endif
drive->disk_ops->flush(drive);
return;
diff --git a/drivers/ide/palm_bk3710.c b/drivers/ide/palm_bk3710.c
index c7acca0b873..09d813d313f 100644
--- a/drivers/ide/palm_bk3710.c
+++ b/drivers/ide/palm_bk3710.c
@@ -39,27 +39,12 @@
/* Primary Control Offset */
#define IDE_PALM_ATA_PRI_CTL_OFFSET 0x3F6
-/*
- * PalmChip 3710 IDE Controller UDMA timing structure Definition
- */
-struct palm_bk3710_udmatiming {
- unsigned int rptime; /* Ready to pause time */
- unsigned int cycletime; /* Cycle Time */
-};
-
#define BK3710_BMICP 0x00
#define BK3710_BMISP 0x02
#define BK3710_BMIDTP 0x04
-#define BK3710_BMICS 0x08
-#define BK3710_BMISS 0x0A
-#define BK3710_BMIDTS 0x0C
#define BK3710_IDETIMP 0x40
-#define BK3710_IDETIMS 0x42
-#define BK3710_SIDETIM 0x44
-#define BK3710_SLEWCTL 0x45
#define BK3710_IDESTATUS 0x47
#define BK3710_UDMACTL 0x48
-#define BK3710_UDMATIM 0x4A
#define BK3710_MISCCTL 0x50
#define BK3710_REGSTB 0x54
#define BK3710_REGRCVR 0x58
@@ -71,17 +56,22 @@ struct palm_bk3710_udmatiming {
#define BK3710_UDMATRP 0x70
#define BK3710_UDMAENV 0x74
#define BK3710_IORDYTMP 0x78
-#define BK3710_IORDYTMS 0x7C
static unsigned ideclk_period; /* in nanoseconds */
+struct palm_bk3710_udmatiming {
+ unsigned int rptime; /* tRP -- Ready to pause time (nsec) */
+ unsigned int cycletime; /* tCYCTYP2/2 -- avg Cycle Time (nsec) */
+ /* tENV is always a minimum of 20 nsec */
+};
+
static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = {
- {160, 240}, /* UDMA Mode 0 */
- {125, 160}, /* UDMA Mode 1 */
- {100, 120}, /* UDMA Mode 2 */
- {100, 90}, /* UDMA Mode 3 */
- {100, 60}, /* UDMA Mode 4 */
- {85, 40}, /* UDMA Mode 5 */
+ { 160, 240 / 2 }, /* UDMA Mode 0 */
+ { 125, 160 / 2 }, /* UDMA Mode 1 */
+ { 100, 120 / 2 }, /* UDMA Mode 2 */
+ { 100, 90 / 2 }, /* UDMA Mode 3 */
+ { 100, 60 / 2 }, /* UDMA Mode 4 */
+ { 85, 40 / 2 }, /* UDMA Mode 5 */
};
static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev,
@@ -98,11 +88,6 @@ static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev,
trp = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].rptime,
ideclk_period) - 1;
- /* udmatim Register */
- val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0);
- val16 |= (mode << (dev ? 4 : 0));
- writew(val16, base + BK3710_UDMATIM);
-
/* udmastb Ultra DMA Access Strobe Width */
val32 = readl(base + BK3710_UDMASTB) & (0xFF << (dev ? 0 : 8));
val32 |= (t0 << (dev ? 8 : 0));
@@ -163,10 +148,11 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
u32 val32;
struct ide_timing *t;
+ t = ide_timing_find_mode(XFER_PIO_0 + mode);
+
/* PIO Data Setup */
t0 = DIV_ROUND_UP(cycletime, ideclk_period);
- t2 = DIV_ROUND_UP(ide_timing_find_mode(XFER_PIO_0 + mode)->active,
- ideclk_period);
+ t2 = DIV_ROUND_UP(t->active, ideclk_period);
t2i = t0 - t2 - 1;
t2 -= 1;
@@ -187,7 +173,6 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
}
/* TASKFILE Setup */
- t = ide_timing_find_mode(XFER_PIO_0 + mode);
t0 = DIV_ROUND_UP(t->cyc8b, ideclk_period);
t2 = DIV_ROUND_UP(t->act8b, ideclk_period);
@@ -236,42 +221,23 @@ static void palm_bk3710_set_pio_mode(ide_drive_t *drive, u8 pio)
static void __devinit palm_bk3710_chipinit(void __iomem *base)
{
/*
- * enable the reset_en of ATA controller so that when ata signals
- * are brought out, by writing into device config. at that
- * time por_n signal should not be 'Z' and have a stable value.
+ * REVISIT: the ATA reset signal needs to be managed through a
+ * GPIO, which means it should come from platform_data. Until
+ * we get and use such information, we have to trust that things
+ * have been reset before we get here.
*/
- writel(0x0300, base + BK3710_MISCCTL);
-
- /* wait for some time and deassert the reset of ATA Device. */
- mdelay(100);
-
- /* Deassert the Reset */
- writel(0x0200, base + BK3710_MISCCTL);
/*
* Program the IDETIMP Register Value based on the following assumptions
*
* (ATA_IDETIMP_IDEEN , ENABLE ) |
- * (ATA_IDETIMP_SLVTIMEN , DISABLE) |
- * (ATA_IDETIMP_RDYSMPL , 70NS) |
- * (ATA_IDETIMP_RDYRCVRY , 50NS) |
- * (ATA_IDETIMP_DMAFTIM1 , PIOCOMP) |
* (ATA_IDETIMP_PREPOST1 , DISABLE) |
- * (ATA_IDETIMP_RDYSEN1 , DISABLE) |
- * (ATA_IDETIMP_PIOFTIM1 , DISABLE) |
- * (ATA_IDETIMP_DMAFTIM0 , PIOCOMP) |
* (ATA_IDETIMP_PREPOST0 , DISABLE) |
- * (ATA_IDETIMP_RDYSEN0 , DISABLE) |
- * (ATA_IDETIMP_PIOFTIM0 , DISABLE)
- */
- writew(0xB388, base + BK3710_IDETIMP);
-
- /*
- * Configure SIDETIM Register
- * (ATA_SIDETIM_RDYSMPS1 ,120NS ) |
- * (ATA_SIDETIM_RDYRCYS1 ,120NS )
+ *
+ * DM6446 silicon rev 2.1 and earlier have no observed net benefit
+ * from enabling prefetch/postwrite.
*/
- writeb(0, base + BK3710_SIDETIM);
+ writew(BIT(15), base + BK3710_IDETIMP);
/*
* UDMACTL Ultra-ATA DMA Control
@@ -283,11 +249,11 @@ static void __devinit palm_bk3710_chipinit(void __iomem *base)
/*
* MISCCTL Miscellaneous Conrol Register
- * (ATA_MISCCTL_RSTMODEP , 1) |
- * (ATA_MISCCTL_RESETP , 0) |
+ * (ATA_MISCCTL_HWNHLD1P , 1 cycle)
+ * (ATA_MISCCTL_HWNHLD0P , 1 cycle)
* (ATA_MISCCTL_TIMORIDE , 1)
*/
- writel(0x201, base + BK3710_MISCCTL);
+ writel(0x001, base + BK3710_MISCCTL);
/*
* IORDYTMP IORDY Timer for Primary Register
@@ -357,10 +323,9 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
clk_enable(clk);
rate = clk_get_rate(clk);
- ideclk_period = 1000000000UL / rate;
- /* Register the IDE interface with Linux ATA Interface */
- memset(&hw, 0, sizeof(hw));
+ /* NOTE: round *down* to meet minimum timings; we count in clocks */
+ ideclk_period = 1000000000UL / rate;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (mem == NULL) {
@@ -390,6 +355,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
/* Configure the Palm Chip controller */
palm_bk3710_chipinit(base);
+ memset(&hw, 0, sizeof(hw));
for (i = 0; i < IDE_NR_PORTS - 2; i++)
hw.io_ports_array[i] = (unsigned long)
(base + IDE_PALM_ATA_PRI_REG_OFFSET + i);
@@ -402,6 +368,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
palm_bk3710_port_info.udma_mask = rate < 100000000 ? ATA_UDMA4 :
ATA_UDMA5;
+ /* Register the IDE interface with Linux */
rc = ide_host_add(&palm_bk3710_port_info, hws, NULL);
if (rc)
goto out;
diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c
index d196abfb68b..5f278176eb9 100644
--- a/drivers/input/mouse/maplemouse.c
+++ b/drivers/input/mouse/maplemouse.c
@@ -2,8 +2,8 @@
* SEGA Dreamcast mouse driver
* Based on drivers/usb/usbmouse.c
*
- * Copyright Yaegashi Takeshi, 2001
- * Adrian McMenamin, 2008
+ * Copyright (c) Yaegashi Takeshi, 2001
+ * Copyright (c) Adrian McMenamin, 2008 - 2009
*/
#include <linux/kernel.h>
@@ -29,7 +29,7 @@ static void dc_mouse_callback(struct mapleq *mq)
struct maple_device *mapledev = mq->dev;
struct dc_mouse *mse = maple_get_drvdata(mapledev);
struct input_dev *dev = mse->dev;
- unsigned char *res = mq->recvbuf;
+ unsigned char *res = mq->recvbuf->buf;
buttons = ~res[8];
relx = *(unsigned short *)(res + 12) - 512;
@@ -47,7 +47,7 @@ static void dc_mouse_callback(struct mapleq *mq)
static int dc_mouse_open(struct input_dev *dev)
{
- struct dc_mouse *mse = dev->dev.platform_data;
+ struct dc_mouse *mse = maple_get_drvdata(to_maple_dev(&dev->dev));
maple_getcond_callback(mse->mdev, dc_mouse_callback, HZ/50,
MAPLE_FUNC_MOUSE);
@@ -57,29 +57,33 @@ static int dc_mouse_open(struct input_dev *dev)
static void dc_mouse_close(struct input_dev *dev)
{
- struct dc_mouse *mse = dev->dev.platform_data;
+ struct dc_mouse *mse = maple_get_drvdata(to_maple_dev(&dev->dev));
maple_getcond_callback(mse->mdev, dc_mouse_callback, 0,
MAPLE_FUNC_MOUSE);
}
-
+/* allow the mouse to be used */
static int __devinit probe_maple_mouse(struct device *dev)
{
struct maple_device *mdev = to_maple_dev(dev);
struct maple_driver *mdrv = to_maple_driver(dev->driver);
+ int error;
struct input_dev *input_dev;
struct dc_mouse *mse;
- int error;
mse = kzalloc(sizeof(struct dc_mouse), GFP_KERNEL);
- input_dev = input_allocate_device();
-
- if (!mse || !input_dev) {
+ if (!mse) {
error = -ENOMEM;
goto fail;
}
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ error = -ENOMEM;
+ goto fail_nomem;
+ }
+
mse->dev = input_dev;
mse->mdev = mdev;
@@ -89,25 +93,24 @@ static int __devinit probe_maple_mouse(struct device *dev)
BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y) |
BIT_MASK(REL_WHEEL);
- input_dev->name = mdev->product_name;
- input_dev->id.bustype = BUS_HOST;
input_dev->open = dc_mouse_open;
input_dev->close = dc_mouse_close;
+ input_dev->name = mdev->product_name;
+ input_dev->id.bustype = BUS_HOST;
+ error = input_register_device(input_dev);
+ if (error)
+ goto fail_register;
mdev->driver = mdrv;
maple_set_drvdata(mdev, mse);
- error = input_register_device(input_dev);
- if (error)
- goto fail;
-
- return 0;
+ return error;
-fail:
+fail_register:
input_free_device(input_dev);
- maple_set_drvdata(mdev, NULL);
+fail_nomem:
kfree(mse);
- mdev->driver = NULL;
+fail:
return error;
}
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 173cf55c64d..3d906833948 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -123,7 +123,7 @@ config PMAC_APM_EMU
config PMAC_MEDIABAY
bool "Support PowerBook hotswap media bay"
- depends on PPC_PMAC && PPC32
+ depends on PPC_PMAC && PPC32 && BLOCK
help
This option adds support for older PowerBook's hotswap media bay
that can contains batteries, floppy drives, or IDE devices. PCI
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index d7e46d345d9..029ad8ce8a7 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -18,7 +18,6 @@
#include <linux/timer.h>
#include <linux/stddef.h>
#include <linux/init.h>
-#include <linux/ide.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <asm/prom.h>
@@ -447,6 +446,7 @@ int check_media_bay_by_base(unsigned long base, int what)
return -ENODEV;
}
+EXPORT_SYMBOL_GPL(check_media_bay_by_base);
int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
int irq, ide_hwif_t *hwif)
@@ -486,6 +486,7 @@ int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
return -ENODEV;
}
+EXPORT_SYMBOL_GPL(media_bay_set_ide_infos);
#endif /* CONFIG_BLK_DEV_IDE_PMAC */
static void media_bay_step(int i)
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index 92c297796a9..bd945d04dc9 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -1200,7 +1200,7 @@ static int si470x_fops_release(struct file *file)
video_unregister_device(radio->videodev);
kfree(radio->buffer);
kfree(radio);
- goto unlock;
+ goto done;
}
/* stop rds reception */
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index f9fbe02e0f6..50b415e07ed 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -159,35 +159,67 @@ static void pwc_set_image_buffer_size(struct pwc_device *pdev);
/****************************************************************************/
+static int _send_control_msg(struct pwc_device *pdev,
+ u8 request, u16 value, int index, void *buf, int buflen, int timeout)
+{
+ int rc;
+ void *kbuf = NULL;
+
+ if (buflen) {
+ kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
+ if (kbuf == NULL)
+ return -ENOMEM;
+ memcpy(kbuf, buf, buflen);
+ }
-#define SendControlMsg(request, value, buflen) \
- usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), \
- request, \
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
- value, \
- pdev->vcinterface, \
- &buf, buflen, 500)
+ rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
+ request,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value,
+ index,
+ kbuf, buflen, timeout);
-#define RecvControlMsg(request, value, buflen) \
- usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), \
- request, \
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
- value, \
- pdev->vcinterface, \
- &buf, buflen, 500)
+ kfree(kbuf);
+ return rc;
+}
+static int recv_control_msg(struct pwc_device *pdev,
+ u8 request, u16 value, void *buf, int buflen)
+{
+ int rc;
+ void *kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
+
+ if (kbuf == NULL)
+ return -ENOMEM;
+
+ rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+ request,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value,
+ pdev->vcinterface,
+ kbuf, buflen, 500);
+ memcpy(buf, kbuf, buflen);
+ kfree(kbuf);
+ return rc;
+}
-static int send_video_command(struct usb_device *udev, int index, void *buf, int buflen)
+static inline int send_video_command(struct pwc_device *pdev,
+ int index, void *buf, int buflen)
{
- return usb_control_msg(udev,
- usb_sndctrlpipe(udev, 0),
+ return _send_control_msg(pdev,
SET_EP_STREAM_CTL,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
VIDEO_OUTPUT_CONTROL_FORMATTER,
index,
buf, buflen, 1000);
}
+static inline int send_control_msg(struct pwc_device *pdev,
+ u8 request, u16 value, void *buf, int buflen)
+{
+ return _send_control_msg(pdev,
+ request, value, pdev->vcinterface, buf, buflen, 500);
+}
+
static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
@@ -224,7 +256,7 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
return -EINVAL;
memcpy(buf, pEntry->mode, 3);
- ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3);
+ ret = send_video_command(pdev, pdev->vendpoint, buf, 3);
if (ret < 0) {
PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret);
return ret;
@@ -285,7 +317,7 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, i
memcpy(buf, pChoose->mode, 13);
if (snapshot)
buf[0] |= 0x80;
- ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 13);
+ ret = send_video_command(pdev, pdev->vendpoint, buf, 13);
if (ret < 0)
return ret;
@@ -358,7 +390,7 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, i
buf[0] |= 0x80;
/* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */
- ret = send_video_command(pdev->udev, 4 /* pdev->vendpoint */, buf, 12);
+ ret = send_video_command(pdev, 4 /* pdev->vendpoint */, buf, 12);
if (ret < 0)
return ret;
@@ -530,7 +562,8 @@ int pwc_get_brightness(struct pwc_device *pdev)
char buf;
int ret;
- ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_LUM_CTL, BRIGHTNESS_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
return buf;
@@ -545,7 +578,8 @@ int pwc_set_brightness(struct pwc_device *pdev, int value)
if (value > 0xffff)
value = 0xffff;
buf = (value >> 9) & 0x7f;
- return SendControlMsg(SET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
+ return send_control_msg(pdev,
+ SET_LUM_CTL, BRIGHTNESS_FORMATTER, &buf, sizeof(buf));
}
/* CONTRAST */
@@ -555,7 +589,8 @@ int pwc_get_contrast(struct pwc_device *pdev)
char buf;
int ret;
- ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_LUM_CTL, CONTRAST_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
return buf;
@@ -570,7 +605,8 @@ int pwc_set_contrast(struct pwc_device *pdev, int value)
if (value > 0xffff)
value = 0xffff;
buf = (value >> 10) & 0x3f;
- return SendControlMsg(SET_LUM_CTL, CONTRAST_FORMATTER, 1);
+ return send_control_msg(pdev,
+ SET_LUM_CTL, CONTRAST_FORMATTER, &buf, sizeof(buf));
}
/* GAMMA */
@@ -580,7 +616,8 @@ int pwc_get_gamma(struct pwc_device *pdev)
char buf;
int ret;
- ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_LUM_CTL, GAMMA_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
return buf;
@@ -595,7 +632,8 @@ int pwc_set_gamma(struct pwc_device *pdev, int value)
if (value > 0xffff)
value = 0xffff;
buf = (value >> 11) & 0x1f;
- return SendControlMsg(SET_LUM_CTL, GAMMA_FORMATTER, 1);
+ return send_control_msg(pdev,
+ SET_LUM_CTL, GAMMA_FORMATTER, &buf, sizeof(buf));
}
@@ -613,7 +651,8 @@ int pwc_get_saturation(struct pwc_device *pdev, int *value)
saturation_register = SATURATION_MODE_FORMATTER2;
else
saturation_register = SATURATION_MODE_FORMATTER1;
- ret = RecvControlMsg(GET_CHROM_CTL, saturation_register, 1);
+ ret = recv_control_msg(pdev,
+ GET_CHROM_CTL, saturation_register, &buf, sizeof(buf));
if (ret < 0)
return ret;
*value = (signed)buf;
@@ -636,7 +675,8 @@ int pwc_set_saturation(struct pwc_device *pdev, int value)
saturation_register = SATURATION_MODE_FORMATTER2;
else
saturation_register = SATURATION_MODE_FORMATTER1;
- return SendControlMsg(SET_CHROM_CTL, saturation_register, 1);
+ return send_control_msg(pdev,
+ SET_CHROM_CTL, saturation_register, &buf, sizeof(buf));
}
/* AGC */
@@ -651,7 +691,8 @@ int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
else
buf = 0xff; /* fixed */
- ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1);
+ ret = send_control_msg(pdev,
+ SET_LUM_CTL, AGC_MODE_FORMATTER, &buf, sizeof(buf));
if (!mode && ret >= 0) {
if (value < 0)
@@ -659,7 +700,8 @@ int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
if (value > 0xffff)
value = 0xffff;
buf = (value >> 10) & 0x3F;
- ret = SendControlMsg(SET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
+ ret = send_control_msg(pdev,
+ SET_LUM_CTL, PRESET_AGC_FORMATTER, &buf, sizeof(buf));
}
if (ret < 0)
return ret;
@@ -671,12 +713,14 @@ int pwc_get_agc(struct pwc_device *pdev, int *value)
unsigned char buf;
int ret;
- ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_LUM_CTL, AGC_MODE_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
if (buf != 0) { /* fixed */
- ret = RecvControlMsg(GET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_LUM_CTL, PRESET_AGC_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
if (buf > 0x3F)
@@ -684,7 +728,8 @@ int pwc_get_agc(struct pwc_device *pdev, int *value)
*value = (buf << 10);
}
else { /* auto */
- ret = RecvControlMsg(GET_STATUS_CTL, READ_AGC_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_STATUS_CTL, READ_AGC_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
/* Gah... this value ranges from 0x00 ... 0x9F */
@@ -707,7 +752,8 @@ int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value)
else
buf[0] = 0xff; /* fixed */
- ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1);
+ ret = send_control_msg(pdev,
+ SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, sizeof(buf));
if (!mode && ret >= 0) {
if (value < 0)
@@ -726,7 +772,9 @@ int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value)
buf[0] = value >> 8;
}
- ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2);
+ ret = send_control_msg(pdev,
+ SET_LUM_CTL, PRESET_SHUTTER_FORMATTER,
+ &buf, sizeof(buf));
}
return ret;
}
@@ -737,7 +785,8 @@ int pwc_get_shutter_speed(struct pwc_device *pdev, int *value)
unsigned char buf[2];
int ret;
- ret = RecvControlMsg(GET_STATUS_CTL, READ_SHUTTER_FORMATTER, 2);
+ ret = recv_control_msg(pdev,
+ GET_STATUS_CTL, READ_SHUTTER_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
*value = buf[0] + (buf[1] << 8);
@@ -764,7 +813,9 @@ int pwc_camera_power(struct pwc_device *pdev, int power)
buf = 0x00; /* active */
else
buf = 0xFF; /* power save */
- return SendControlMsg(SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, 1);
+ return send_control_msg(pdev,
+ SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER,
+ &buf, sizeof(buf));
}
@@ -773,20 +824,20 @@ int pwc_camera_power(struct pwc_device *pdev, int power)
int pwc_restore_user(struct pwc_device *pdev)
{
- char buf; /* dummy */
- return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0);
+ return send_control_msg(pdev,
+ SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, NULL, 0);
}
int pwc_save_user(struct pwc_device *pdev)
{
- char buf; /* dummy */
- return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0);
+ return send_control_msg(pdev,
+ SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, NULL, 0);
}
int pwc_restore_factory(struct pwc_device *pdev)
{
- char buf; /* dummy */
- return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0);
+ return send_control_msg(pdev,
+ SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, NULL, 0);
}
/* ************************************************* */
@@ -814,7 +865,8 @@ int pwc_set_awb(struct pwc_device *pdev, int mode)
buf = mode & 0x07; /* just the lowest three bits */
- ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1);
+ ret = send_control_msg(pdev,
+ SET_CHROM_CTL, WB_MODE_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
@@ -826,7 +878,8 @@ int pwc_get_awb(struct pwc_device *pdev)
unsigned char buf;
int ret;
- ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_CHROM_CTL, WB_MODE_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
@@ -843,7 +896,9 @@ int pwc_set_red_gain(struct pwc_device *pdev, int value)
value = 0xffff;
/* only the msb is considered */
buf = value >> 8;
- return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
+ return send_control_msg(pdev,
+ SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER,
+ &buf, sizeof(buf));
}
int pwc_get_red_gain(struct pwc_device *pdev, int *value)
@@ -851,7 +906,9 @@ int pwc_get_red_gain(struct pwc_device *pdev, int *value)
unsigned char buf;
int ret;
- ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER,
+ &buf, sizeof(buf));
if (ret < 0)
return ret;
*value = buf << 8;
@@ -869,7 +926,9 @@ int pwc_set_blue_gain(struct pwc_device *pdev, int value)
value = 0xffff;
/* only the msb is considered */
buf = value >> 8;
- return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
+ return send_control_msg(pdev,
+ SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER,
+ &buf, sizeof(buf));
}
int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
@@ -877,7 +936,9 @@ int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
unsigned char buf;
int ret;
- ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER,
+ &buf, sizeof(buf));
if (ret < 0)
return ret;
*value = buf << 8;
@@ -894,7 +955,8 @@ static int pwc_read_red_gain(struct pwc_device *pdev, int *value)
unsigned char buf;
int ret;
- ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
*value = buf << 8;
@@ -906,7 +968,8 @@ static int pwc_read_blue_gain(struct pwc_device *pdev, int *value)
unsigned char buf;
int ret;
- ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
*value = buf << 8;
@@ -920,7 +983,8 @@ static int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
/* useful range is 0x01..0x20 */
buf = speed / 0x7f0;
- return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
+ return send_control_msg(pdev,
+ SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
}
static int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
@@ -928,7 +992,8 @@ static int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
unsigned char buf;
int ret;
- ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
*value = buf * 0x7f0;
@@ -942,7 +1007,8 @@ static int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
/* useful range is 0x01..0x3F */
buf = (delay >> 10);
- return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
+ return send_control_msg(pdev,
+ SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
}
static int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
@@ -950,7 +1016,8 @@ static int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
unsigned char buf;
int ret;
- ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
*value = buf << 10;
@@ -978,7 +1045,8 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
buf[0] = on_value;
buf[1] = off_value;
- return SendControlMsg(SET_STATUS_CTL, LED_FORMATTER, 2);
+ return send_control_msg(pdev,
+ SET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
}
static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
@@ -992,7 +1060,8 @@ static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
return 0;
}
- ret = RecvControlMsg(GET_STATUS_CTL, LED_FORMATTER, 2);
+ ret = recv_control_msg(pdev,
+ GET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
*on_value = buf[0] * 100;
@@ -1009,7 +1078,8 @@ int pwc_set_contour(struct pwc_device *pdev, int contour)
buf = 0xff; /* auto contour on */
else
buf = 0x0; /* auto contour off */
- ret = SendControlMsg(SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
+ ret = send_control_msg(pdev,
+ SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
@@ -1019,7 +1089,8 @@ int pwc_set_contour(struct pwc_device *pdev, int contour)
contour = 0xffff;
buf = (contour >> 10); /* contour preset is [0..3f] */
- ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
+ ret = send_control_msg(pdev,
+ SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
return 0;
@@ -1030,13 +1101,16 @@ int pwc_get_contour(struct pwc_device *pdev, int *contour)
unsigned char buf;
int ret;
- ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
if (buf == 0) {
/* auto mode off, query current preset value */
- ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_LUM_CTL, PRESET_CONTOUR_FORMATTER,
+ &buf, sizeof(buf));
if (ret < 0)
return ret;
*contour = buf << 10;
@@ -1055,7 +1129,9 @@ int pwc_set_backlight(struct pwc_device *pdev, int backlight)
buf = 0xff;
else
buf = 0x0;
- return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
+ return send_control_msg(pdev,
+ SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER,
+ &buf, sizeof(buf));
}
int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
@@ -1063,7 +1139,9 @@ int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
int ret;
unsigned char buf;
- ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER,
+ &buf, sizeof(buf));
if (ret < 0)
return ret;
*backlight = !!buf;
@@ -1078,7 +1156,8 @@ int pwc_set_colour_mode(struct pwc_device *pdev, int colour)
buf = 0xff;
else
buf = 0x0;
- return SendControlMsg(SET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1);
+ return send_control_msg(pdev,
+ SET_CHROM_CTL, COLOUR_MODE_FORMATTER, &buf, sizeof(buf));
}
int pwc_get_colour_mode(struct pwc_device *pdev, int *colour)
@@ -1086,7 +1165,8 @@ int pwc_get_colour_mode(struct pwc_device *pdev, int *colour)
int ret;
unsigned char buf;
- ret = RecvControlMsg(GET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_CHROM_CTL, COLOUR_MODE_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
*colour = !!buf;
@@ -1102,7 +1182,8 @@ int pwc_set_flicker(struct pwc_device *pdev, int flicker)
buf = 0xff;
else
buf = 0x0;
- return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
+ return send_control_msg(pdev,
+ SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, &buf, sizeof(buf));
}
int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
@@ -1110,7 +1191,8 @@ int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
int ret;
unsigned char buf;
- ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
*flicker = !!buf;
@@ -1126,7 +1208,9 @@ int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
if (noise > 3)
noise = 3;
buf = noise;
- return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
+ return send_control_msg(pdev,
+ SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER,
+ &buf, sizeof(buf));
}
int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
@@ -1134,7 +1218,9 @@ int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
int ret;
unsigned char buf;
- ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
+ ret = recv_control_msg(pdev,
+ GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER,
+ &buf, sizeof(buf));
if (ret < 0)
return ret;
*noise = buf;
@@ -1146,7 +1232,8 @@ static int _pwc_mpt_reset(struct pwc_device *pdev, int flags)
unsigned char buf;
buf = flags & 0x03; // only lower two bits are currently used
- return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1);
+ return send_control_msg(pdev,
+ SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, &buf, sizeof(buf));
}
int pwc_mpt_reset(struct pwc_device *pdev, int flags)
@@ -1175,7 +1262,8 @@ static int _pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
buf[1] = (pan >> 8) & 0xFF;
buf[2] = tilt & 0xFF;
buf[3] = (tilt >> 8) & 0xFF;
- return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4);
+ return send_control_msg(pdev,
+ SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, &buf, sizeof(buf));
}
int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
@@ -1211,7 +1299,8 @@ static int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *st
int ret;
unsigned char buf[5];
- ret = RecvControlMsg(GET_MPT_CTL, PT_STATUS_FORMATTER, 5);
+ ret = recv_control_msg(pdev,
+ GET_MPT_CTL, PT_STATUS_FORMATTER, &buf, sizeof(buf));
if (ret < 0)
return ret;
status->status = buf[0] & 0x7; // 3 bits are used for reporting
@@ -1233,7 +1322,8 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
else
request = SENSOR_TYPE_FORMATTER2;
- ret = RecvControlMsg(GET_STATUS_CTL, request, 1);
+ ret = recv_control_msg(pdev,
+ GET_STATUS_CTL, request, &buf, sizeof(buf));
if (ret < 0)
return ret;
if (pdev->type < 675)
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index 7c5b257ce8e..29acd06b1c3 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -332,7 +332,7 @@ static void cafe_select_chip(struct mtd_info *mtd, int chipnr)
cafe->ctl1 &= ~CTRL1_CHIPSELECT;
}
-static int cafe_nand_interrupt(int irq, void *id)
+static irqreturn_t cafe_nand_interrupt(int irq, void *id)
{
struct mtd_info *mtd = id;
struct cafe_priv *cafe = mtd->priv;
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 29df398b772..1fc45431a62 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -1383,6 +1383,11 @@ static void rtl8139_hw_start (struct net_device *dev)
RTL_W32_F (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
RTL_W32_F (MAC0 + 4, le16_to_cpu (*(__le16 *) (dev->dev_addr + 4)));
+ tp->cur_rx = 0;
+
+ /* init Rx ring buffer DMA address */
+ RTL_W32_F (RxBuf, tp->rx_ring_dma);
+
/* Must enable Tx/Rx before setting transfer thresholds! */
RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
@@ -1390,8 +1395,6 @@ static void rtl8139_hw_start (struct net_device *dev)
RTL_W32 (RxConfig, tp->rx_config);
RTL_W32 (TxConfig, rtl8139_tx_config);
- tp->cur_rx = 0;
-
rtl_check_media (dev, 1);
if (tp->chipset >= CH_8139B) {
@@ -1406,9 +1409,6 @@ static void rtl8139_hw_start (struct net_device *dev)
/* Lock Config[01234] and BMCR register writes */
RTL_W8 (Cfg9346, Cfg9346_Lock);
- /* init Rx ring buffer DMA address */
- RTL_W32_F (RxBuf, tp->rx_ring_dma);
-
/* init Tx buffer DMA addresses */
for (i = 0; i < NUM_TX_DESC; i++)
RTL_W32_F (TxAddr0 + (i * 4), tp->tx_bufs_dma + (tp->tx_buf[i] - tp->tx_bufs));
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9e921544ba2..214a92d1ef7 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -28,9 +28,9 @@ if NETDEVICES
config COMPAT_NET_DEV_OPS
default y
- bool "Enable older network device API compatiablity"
+ bool "Enable older network device API compatibility"
---help---
- This option enables kernel compatiability with older network devices
+ This option enables kernel compatibility with older network devices
that do not use net_device_ops interface.
If unsure, say Y.
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index ab0e5febef8..7ea48414c6c 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1117,8 +1117,8 @@ static void cxgb_down(struct adapter *adapter)
spin_unlock_irq(&adapter->work_lock);
free_irq_resources(adapter);
- flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */
quiesce_rx(adapter);
+ flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */
}
static void schedule_chk_task(struct adapter *adap)
@@ -1187,6 +1187,9 @@ static int offload_close(struct t3cdev *tdev)
sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group);
+ /* Flush work scheduled while releasing TIDs */
+ flush_scheduled_work();
+
tdev->lldev = NULL;
cxgb3_set_dummy_ops(tdev);
t3_tp_set_offload_mode(adapter, 0);
@@ -1232,6 +1235,10 @@ static int cxgb_close(struct net_device *dev)
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
+
+ if (!adapter->open_device_map)
+ return 0;
+
/* Stop link fault interrupts */
t3_xgm_intr_disable(adapter, pi->port_id);
t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
@@ -1247,8 +1254,7 @@ static int cxgb_close(struct net_device *dev)
spin_unlock_irq(&adapter->work_lock);
if (!(adapter->open_device_map & PORT_MASK))
- cancel_rearming_delayed_workqueue(cxgb3_wq,
- &adapter->adap_check_task);
+ cancel_delayed_work_sync(&adapter->adap_check_task);
if (!adapter->open_device_map)
cxgb_down(adapter);
@@ -2493,6 +2499,7 @@ static void check_link_status(struct adapter *adapter)
spin_lock_irq(&adapter->work_lock);
if (p->link_fault) {
+ t3_link_fault(adapter, i);
spin_unlock_irq(&adapter->work_lock);
continue;
}
@@ -2554,9 +2561,7 @@ static void t3_adap_check_task(struct work_struct *work)
adapter->check_task_cnt++;
- /* Check link status for PHYs without interrupts */
- if (p->linkpoll_period)
- check_link_status(adapter);
+ check_link_status(adapter);
/* Accumulate MAC stats if needed */
if (!p->linkpoll_period ||
@@ -2680,21 +2685,6 @@ void t3_os_ext_intr_handler(struct adapter *adapter)
spin_unlock(&adapter->work_lock);
}
-static void link_fault_task(struct work_struct *work)
-{
- struct adapter *adapter = container_of(work, struct adapter,
- link_fault_handler_task);
- int i;
-
- for_each_port(adapter, i) {
- struct net_device *netdev = adapter->port[i];
- struct port_info *pi = netdev_priv(netdev);
-
- if (pi->link_fault)
- t3_link_fault(adapter, i);
- }
-}
-
void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
{
struct net_device *netdev = adapter->port[port_id];
@@ -2702,7 +2692,6 @@ void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
spin_lock(&adapter->work_lock);
pi->link_fault = 1;
- queue_work(cxgb3_wq, &adapter->link_fault_handler_task);
spin_unlock(&adapter->work_lock);
}
@@ -2838,6 +2827,9 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
struct adapter *adapter = pci_get_drvdata(pdev);
int ret;
+ if (state == pci_channel_io_perm_failure)
+ return PCI_ERS_RESULT_DISCONNECT;
+
ret = t3_adapter_error(adapter, 0);
/* Request a slot reset. */
@@ -2932,8 +2924,13 @@ static int __devinit cxgb_enable_msix(struct adapter *adap)
while ((err = pci_enable_msix(adap->pdev, entries, vectors)) > 0)
vectors = err;
- if (!err && vectors < (adap->params.nports + 1))
+ if (err < 0)
+ pci_disable_msix(adap->pdev);
+
+ if (!err && vectors < (adap->params.nports + 1)) {
+ pci_disable_msix(adap->pdev);
err = -1;
+ }
if (!err) {
for (i = 0; i < vectors; ++i)
@@ -3082,7 +3079,6 @@ static int __devinit init_one(struct pci_dev *pdev,
INIT_LIST_HEAD(&adapter->adapter_list);
INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task);
- INIT_WORK(&adapter->link_fault_handler_task, link_fault_task);
INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task);
INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task);
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 31ed31a3428..e1bd690ff83 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -1202,7 +1202,6 @@ void t3_link_changed(struct adapter *adapter, int port_id)
struct cphy *phy = &pi->phy;
struct cmac *mac = &pi->mac;
struct link_config *lc = &pi->link_config;
- int force_link_down = 0;
phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
@@ -1218,14 +1217,9 @@ void t3_link_changed(struct adapter *adapter, int port_id)
status = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset);
if (status & F_LINKFAULTCHANGE) {
mac->stats.link_faults++;
- force_link_down = 1;
+ pi->link_fault = 1;
}
t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low);
-
- if (force_link_down) {
- t3_os_link_fault_handler(adapter, port_id);
- return;
- }
}
if (lc->requested_fc & PAUSE_AUTONEG)
@@ -1292,9 +1286,6 @@ void t3_link_fault(struct adapter *adapter, int port_id)
/* Account link faults only when the phy reports a link up */
if (link_ok)
mac->stats.link_faults++;
-
- msleep(1000);
- t3_os_link_fault_handler(adapter, port_id);
} else {
if (link_ok)
t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset,
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index ef12931d302..6a46ceed943 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3834,7 +3834,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
struct e1000_buffer *buffer_info;
unsigned int i, eop;
unsigned int count = 0;
- bool cleaned = false;
unsigned int total_tx_bytes=0, total_tx_packets=0;
i = tx_ring->next_to_clean;
@@ -3843,7 +3842,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
(count < tx_ring->count)) {
- for (cleaned = false; !cleaned; count++) {
+ bool cleaned = false;
+ for ( ; !cleaned; count++) {
tx_desc = E1000_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
cleaned = (i == eop);
@@ -3871,7 +3871,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
tx_ring->next_to_clean = i;
#define TX_WAKE_THRESHOLD 32
- if (unlikely(cleaned && netif_carrier_ok(netdev) &&
+ if (unlikely(count && netif_carrier_ok(netdev) &&
E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
/* Make sure that anybody stopping the queue after this
* sees the new next_to_clean.
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 1693ed116b1..ca82f19a7ed 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -621,7 +621,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
struct e1000_buffer *buffer_info;
unsigned int i, eop;
unsigned int count = 0;
- bool cleaned = false;
unsigned int total_tx_bytes = 0, total_tx_packets = 0;
i = tx_ring->next_to_clean;
@@ -630,7 +629,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
(count < tx_ring->count)) {
- for (cleaned = 0; !cleaned; count++) {
+ bool cleaned = false;
+ for (; !cleaned; count++) {
tx_desc = E1000_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
cleaned = (i == eop);
@@ -661,8 +661,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
tx_ring->next_to_clean = i;
#define TX_WAKE_THRESHOLD 32
- if (cleaned && netif_carrier_ok(netdev) &&
- e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
+ if (count && netif_carrier_ok(netdev) &&
+ e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
/* Make sure that anybody stopping the queue after this
* sees the new next_to_clean.
*/
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c
index 470b676c1da..f4417fc3b0f 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c
@@ -290,7 +290,7 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
{
- u32 i, reg;
+ u32 i, reg, rx_pba_size;
/* If PFC is disabled globally then fall back to LFC. */
if (!dcb_config->pfc_mode_enable) {
@@ -301,17 +301,23 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
/* Configure PFC Tx thresholds per TC */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
- /* Config and remember Tx */
+ if (dcb_config->rx_pba_cfg == pba_equal)
+ rx_pba_size = IXGBE_RXPBSIZE_64KB;
+ else
+ rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB
+ : IXGBE_RXPBSIZE_48KB;
+
+ reg = ((rx_pba_size >> 5) & 0xFFE0);
if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
- dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) {
- reg = hw->fc.high_water | IXGBE_FCRTH_FCEN;
- IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
- reg = hw->fc.low_water | IXGBE_FCRTL_XONE;
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);
- } else {
- IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), 0);
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
- }
+ dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx)
+ reg |= IXGBE_FCRTL_XONE;
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);
+
+ reg = ((rx_pba_size >> 2) & 0xFFE0);
+ if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
+ dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx)
+ reg |= IXGBE_FCRTH_FCEN;
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
}
/* Configure pause time (2 TCs per register) */
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index febde45cf9f..01884256f4c 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -2841,11 +2841,55 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter)
}
ret = true;
} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- for (i = 0; i < dcb_i; i++) {
- adapter->rx_ring[i].reg_idx = i << 4;
- adapter->tx_ring[i].reg_idx = i << 4;
+ if (dcb_i == 8) {
+ /*
+ * Tx TC0 starts at: descriptor queue 0
+ * Tx TC1 starts at: descriptor queue 32
+ * Tx TC2 starts at: descriptor queue 64
+ * Tx TC3 starts at: descriptor queue 80
+ * Tx TC4 starts at: descriptor queue 96
+ * Tx TC5 starts at: descriptor queue 104
+ * Tx TC6 starts at: descriptor queue 112
+ * Tx TC7 starts at: descriptor queue 120
+ *
+ * Rx TC0-TC7 are offset by 16 queues each
+ */
+ for (i = 0; i < 3; i++) {
+ adapter->tx_ring[i].reg_idx = i << 5;
+ adapter->rx_ring[i].reg_idx = i << 4;
+ }
+ for ( ; i < 5; i++) {
+ adapter->tx_ring[i].reg_idx =
+ ((i + 2) << 4);
+ adapter->rx_ring[i].reg_idx = i << 4;
+ }
+ for ( ; i < dcb_i; i++) {
+ adapter->tx_ring[i].reg_idx =
+ ((i + 8) << 3);
+ adapter->rx_ring[i].reg_idx = i << 4;
+ }
+
+ ret = true;
+ } else if (dcb_i == 4) {
+ /*
+ * Tx TC0 starts at: descriptor queue 0
+ * Tx TC1 starts at: descriptor queue 64
+ * Tx TC2 starts at: descriptor queue 96
+ * Tx TC3 starts at: descriptor queue 112
+ *
+ * Rx TC0-TC3 are offset by 32 queues each
+ */
+ adapter->tx_ring[0].reg_idx = 0;
+ adapter->tx_ring[1].reg_idx = 64;
+ adapter->tx_ring[2].reg_idx = 96;
+ adapter->tx_ring[3].reg_idx = 112;
+ for (i = 0 ; i < dcb_i; i++)
+ adapter->rx_ring[i].reg_idx = i << 5;
+
+ ret = true;
+ } else {
+ ret = false;
}
- ret = true;
} else {
ret = false;
}
@@ -3946,7 +3990,7 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work)
}
hw->mac.ops.setup_sfp(hw);
- if (!adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)
+ if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
/* This will also work for DA Twinax connections */
schedule_work(&adapter->multispeed_fiber_task);
adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK;
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 46073de290c..e82aee41d77 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -316,10 +316,11 @@ static void macb_tx(struct macb *bp)
dev_dbg(&bp->pdev->dev, "macb_tx status = %02lx\n",
(unsigned long)status);
- if (status & MACB_BIT(UND)) {
+ if (status & (MACB_BIT(UND) | MACB_BIT(TSR_RLE))) {
int i;
- printk(KERN_ERR "%s: TX underrun, resetting buffers\n",
- bp->dev->name);
+ printk(KERN_ERR "%s: TX %s, resetting buffers\n",
+ bp->dev->name, status & MACB_BIT(UND) ?
+ "underrun" : "retry limit exceeded");
/* Transfer ongoing, disable transmitter, to avoid confusion */
if (status & MACB_BIT(TGO))
@@ -520,27 +521,10 @@ static int macb_poll(struct napi_struct *napi, int budget)
macb_writel(bp, RSR, status);
work_done = 0;
- if (!status) {
- /*
- * This may happen if an interrupt was pending before
- * this function was called last time, and no packets
- * have been received since.
- */
- napi_complete(napi);
- goto out;
- }
dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n",
(unsigned long)status, budget);
- if (!(status & MACB_BIT(REC))) {
- dev_warn(&bp->pdev->dev,
- "No RX buffers complete, status = %02lx\n",
- (unsigned long)status);
- napi_complete(napi);
- goto out;
- }
-
work_done = macb_rx(bp, budget);
if (work_done < budget)
napi_complete(napi);
@@ -549,7 +533,6 @@ static int macb_poll(struct napi_struct *napi, int budget)
* We've done what we can to clean the buffers. Make sure we
* get notified when new packets arrive.
*/
-out:
macb_writel(bp, IER, MACB_RX_INT_FLAGS);
/* TODO: Handle errors */
@@ -590,7 +573,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
}
}
- if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND)))
+ if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND) |
+ MACB_BIT(ISR_RLE)))
macb_tx(bp);
/*
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 70d3ef4a2c5..214a8cf2b70 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -376,7 +376,8 @@ static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev)
const struct macvlan_dev *vlan = netdev_priv(dev);
struct net_device *lowerdev = vlan->lowerdev;
- if (lowerdev->ethtool_ops->get_rx_csum == NULL)
+ if (lowerdev->ethtool_ops == NULL ||
+ lowerdev->ethtool_ops->get_rx_csum == NULL)
return 0;
return lowerdev->ethtool_ops->get_rx_csum(lowerdev);
}
@@ -387,7 +388,8 @@ static int macvlan_ethtool_get_settings(struct net_device *dev,
const struct macvlan_dev *vlan = netdev_priv(dev);
struct net_device *lowerdev = vlan->lowerdev;
- if (!lowerdev->ethtool_ops->get_settings)
+ if (!lowerdev->ethtool_ops ||
+ !lowerdev->ethtool_ops->get_settings)
return -EOPNOTSUPP;
return lowerdev->ethtool_ops->get_settings(lowerdev, cmd);
@@ -398,7 +400,8 @@ static u32 macvlan_ethtool_get_flags(struct net_device *dev)
const struct macvlan_dev *vlan = netdev_priv(dev);
struct net_device *lowerdev = vlan->lowerdev;
- if (!lowerdev->ethtool_ops->get_flags)
+ if (!lowerdev->ethtool_ops ||
+ !lowerdev->ethtool_ops->get_flags)
return 0;
return lowerdev->ethtool_ops->get_flags(lowerdev);
}
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c
index eda72dd2120..510633fd57f 100644
--- a/drivers/net/mlx4/en_main.c
+++ b/drivers/net/mlx4/en_main.c
@@ -181,7 +181,7 @@ static void *mlx4_en_add(struct mlx4_dev *dev)
mdev->workqueue = create_singlethread_workqueue("mlx4_en");
if (!mdev->workqueue) {
err = -ENOMEM;
- goto err_close_nic;
+ goto err_mr;
}
/* At this stage all non-port specific tasks are complete:
@@ -214,9 +214,8 @@ err_free_netdev:
flush_workqueue(mdev->workqueue);
/* Stop event queue before we drop down to release shared SW state */
-
-err_close_nic:
destroy_workqueue(mdev->workqueue);
+
err_mr:
mlx4_mr_free(dev, &mdev->mr);
err_uar:
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index 303c23de6ca..438678ab2a1 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -348,11 +348,9 @@ static void mlx4_en_tx_timeout(struct net_device *dev)
if (netif_msg_timer(priv))
mlx4_warn(mdev, "Tx timeout called on port:%d\n", priv->port);
- if (netif_carrier_ok(dev)) {
- priv->port_stats.tx_timeout++;
- mlx4_dbg(DRV, priv, "Scheduling watchdog\n");
- queue_work(mdev->workqueue, &priv->watchdog_task);
- }
+ priv->port_stats.tx_timeout++;
+ mlx4_dbg(DRV, priv, "Scheduling watchdog\n");
+ queue_work(mdev->workqueue, &priv->watchdog_task);
}
@@ -761,9 +759,14 @@ static void mlx4_en_restart(struct work_struct *work)
struct net_device *dev = priv->dev;
mlx4_dbg(DRV, priv, "Watchdog task called for port %d\n", priv->port);
- mlx4_en_stop_port(dev);
- if (mlx4_en_start_port(dev))
- mlx4_err(mdev, "Failed restarting port %d\n", priv->port);
+
+ mutex_lock(&mdev->state_lock);
+ if (priv->port_up) {
+ mlx4_en_stop_port(dev);
+ if (mlx4_en_start_port(dev))
+ mlx4_err(mdev, "Failed restarting port %d\n", priv->port);
+ }
+ mutex_unlock(&mdev->state_lock);
}
@@ -1054,7 +1057,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
* Set driver features
*/
dev->features |= NETIF_F_SG;
- dev->features |= NETIF_F_HW_CSUM;
+ dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
dev->features |= NETIF_F_HIGHDMA;
dev->features |= NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c
index c5a4c038975..a29abe845d2 100644
--- a/drivers/net/mlx4/en_port.c
+++ b/drivers/net/mlx4/en_port.c
@@ -151,6 +151,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
struct mlx4_cmd_mailbox *mailbox;
u64 in_mod = reset << 8 | port;
int err;
+ int i;
mailbox = mlx4_alloc_cmd_mailbox(mdev->dev);
if (IS_ERR(mailbox))
@@ -165,38 +166,18 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
spin_lock_bh(&priv->stats_lock);
- stats->rx_packets = be32_to_cpu(mlx4_en_stats->RTOTFRMS) -
- be32_to_cpu(mlx4_en_stats->RDROP);
- stats->tx_packets = be64_to_cpu(mlx4_en_stats->TTOT_prio_0) +
- be64_to_cpu(mlx4_en_stats->TTOT_prio_1) +
- be64_to_cpu(mlx4_en_stats->TTOT_prio_2) +
- be64_to_cpu(mlx4_en_stats->TTOT_prio_3) +
- be64_to_cpu(mlx4_en_stats->TTOT_prio_4) +
- be64_to_cpu(mlx4_en_stats->TTOT_prio_5) +
- be64_to_cpu(mlx4_en_stats->TTOT_prio_6) +
- be64_to_cpu(mlx4_en_stats->TTOT_prio_7) +
- be64_to_cpu(mlx4_en_stats->TTOT_novlan) +
- be64_to_cpu(mlx4_en_stats->TTOT_loopbk);
- stats->rx_bytes = be64_to_cpu(mlx4_en_stats->ROCT_prio_0) +
- be64_to_cpu(mlx4_en_stats->ROCT_prio_1) +
- be64_to_cpu(mlx4_en_stats->ROCT_prio_2) +
- be64_to_cpu(mlx4_en_stats->ROCT_prio_3) +
- be64_to_cpu(mlx4_en_stats->ROCT_prio_4) +
- be64_to_cpu(mlx4_en_stats->ROCT_prio_5) +
- be64_to_cpu(mlx4_en_stats->ROCT_prio_6) +
- be64_to_cpu(mlx4_en_stats->ROCT_prio_7) +
- be64_to_cpu(mlx4_en_stats->ROCT_novlan);
-
- stats->tx_bytes = be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_0) +
- be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_1) +
- be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_2) +
- be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_3) +
- be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_4) +
- be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_5) +
- be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_6) +
- be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_7) +
- be64_to_cpu(mlx4_en_stats->TTTLOCT_novlan) +
- be64_to_cpu(mlx4_en_stats->TTTLOCT_loopbk);
+ stats->rx_packets = 0;
+ stats->rx_bytes = 0;
+ for (i = 0; i < priv->rx_ring_num; i++) {
+ stats->rx_packets += priv->rx_ring[i].packets;
+ stats->rx_bytes += priv->rx_ring[i].bytes;
+ }
+ stats->tx_packets = 0;
+ stats->tx_bytes = 0;
+ for (i = 0; i <= priv->tx_ring_num; i++) {
+ stats->tx_packets += priv->tx_ring[i].packets;
+ stats->tx_bytes += priv->tx_ring[i].bytes;
+ }
stats->rx_errors = be64_to_cpu(mlx4_en_stats->PCS) +
be32_to_cpu(mlx4_en_stats->RdropLength) +
diff --git a/drivers/net/mlx4/en_resources.c b/drivers/net/mlx4/en_resources.c
index a0545209e50..65ca706c04b 100644
--- a/drivers/net/mlx4/en_resources.c
+++ b/drivers/net/mlx4/en_resources.c
@@ -94,3 +94,9 @@ void mlx4_en_unmap_buffer(struct mlx4_buf *buf)
vunmap(buf->direct.buf);
}
+
+void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event)
+{
+ return;
+}
+
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index 7e40741fb7d..0cbb78ca7b2 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -436,8 +436,9 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
/* Initialize page allocators */
err = mlx4_en_init_allocator(priv, ring);
if (err) {
- mlx4_err(mdev, "Failed initializing ring allocator\n");
- goto err_allocator;
+ mlx4_err(mdev, "Failed initializing ring allocator\n");
+ ring_ind--;
+ goto err_allocator;
}
/* Fill Rx buffers */
@@ -467,6 +468,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
ring->wqres.db.dma, &ring->srq);
if (err){
mlx4_err(mdev, "Failed to allocate srq\n");
+ ring_ind--;
goto err_srq;
}
ring->srq.event = mlx4_en_srq_event;
@@ -926,12 +928,6 @@ void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv,
}
}
-static void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event)
-{
- return;
-}
-
-
static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv,
int qpn, int srqn, int cqn,
enum mlx4_qp_state *state,
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
index 4afd5993e31..ac6fc499b28 100644
--- a/drivers/net/mlx4/en_tx.c
+++ b/drivers/net/mlx4/en_tx.c
@@ -112,6 +112,7 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
mlx4_err(mdev, "Failed allocating qp %d\n", ring->qpn);
goto err_reserve;
}
+ ring->qp.event = mlx4_en_sqp_event;
return 0;
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
index e9af32d41ca..ef840abbcd3 100644
--- a/drivers/net/mlx4/mlx4_en.h
+++ b/drivers/net/mlx4/mlx4_en.h
@@ -538,6 +538,7 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget);
void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
int is_tx, int rss, int qpn, int cqn, int srqn,
struct mlx4_qp_context *context);
+void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event);
int mlx4_en_map_buffer(struct mlx4_buf *buf);
void mlx4_en_unmap_buffer(struct mlx4_buf *buf);
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 2fbf9f9ddd3..652a3688836 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -1758,7 +1758,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "DP83903.cis"),
- PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "LA-PCM.cis"),
+ PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "NE2K.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"),
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index a5ac2bd58b5..4f3ada622f9 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -2101,6 +2101,9 @@ static int gelic_wl_associate_bss(struct gelic_wl_info *wl,
if (ret) {
pr_debug("%s: WEP/WPA setup failed %d\n", __func__,
ret);
+ ret = -EPERM;
+ gelic_wl_send_iwap_event(wl, NULL);
+ goto out;
}
/* start association */
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 7a837c46596..201be425643 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -2190,7 +2190,14 @@ static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
if (!(tmp & EEPROM_ADDR_COMPLETE))
return -EBUSY;
- *val = tr32(GRC_EEPROM_DATA);
+ tmp = tr32(GRC_EEPROM_DATA);
+
+ /*
+ * The data will always be opposite the native endian
+ * format. Perform a blind byteswap to compensate.
+ */
+ *val = swab32(tmp);
+
return 0;
}
@@ -10663,7 +10670,13 @@ static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
memcpy(&data, buf + i, 4);
- tw32(GRC_EEPROM_DATA, be32_to_cpu(data));
+ /*
+ * The SEEPROM interface expects the data to always be opposite
+ * the native endian format. We accomplish this by reversing
+ * all the operations that would have been performed on the
+ * data from a call to tg3_nvram_read_be32().
+ */
+ tw32(GRC_EEPROM_DATA, swab32(be32_to_cpu(data)));
val = tr32(GRC_EEPROM_ADDR);
tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE);
@@ -12443,13 +12456,8 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
/* Next, try NVRAM. */
if (!tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
!tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) {
- dev->dev_addr[0] = ((hi >> 16) & 0xff);
- dev->dev_addr[1] = ((hi >> 24) & 0xff);
- dev->dev_addr[2] = ((lo >> 0) & 0xff);
- dev->dev_addr[3] = ((lo >> 8) & 0xff);
- dev->dev_addr[4] = ((lo >> 16) & 0xff);
- dev->dev_addr[5] = ((lo >> 24) & 0xff);
-
+ memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2);
+ memcpy(&dev->dev_addr[2], (char *)&lo, sizeof(lo));
}
/* Finally just fetch it out of the MAC control regs. */
else {
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 16716aef184..735bf41c654 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -93,7 +93,6 @@ struct tun_file {
atomic_t count;
struct tun_struct *tun;
struct net *net;
- wait_queue_head_t read_wait;
};
struct tun_sock;
@@ -156,6 +155,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
tfile->tun = tun;
tun->tfile = tfile;
dev_hold(tun->dev);
+ sock_hold(tun->sk);
atomic_inc(&tfile->count);
out:
@@ -165,11 +165,8 @@ out:
static void __tun_detach(struct tun_struct *tun)
{
- struct tun_file *tfile = tun->tfile;
-
/* Detach from net device */
netif_tx_lock_bh(tun->dev);
- tfile->tun = NULL;
tun->tfile = NULL;
netif_tx_unlock_bh(tun->dev);
@@ -333,12 +330,19 @@ static void tun_net_uninit(struct net_device *dev)
/* Inform the methods they need to stop using the dev.
*/
if (tfile) {
- wake_up_all(&tfile->read_wait);
+ wake_up_all(&tun->socket.wait);
if (atomic_dec_and_test(&tfile->count))
__tun_detach(tun);
}
}
+static void tun_free_netdev(struct net_device *dev)
+{
+ struct tun_struct *tun = netdev_priv(dev);
+
+ sock_put(tun->sk);
+}
+
/* Net device open. */
static int tun_net_open(struct net_device *dev)
{
@@ -393,7 +397,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
/* Notify and wake up reader process */
if (tun->flags & TUN_FASYNC)
kill_fasync(&tun->fasync, SIGIO, POLL_IN);
- wake_up_interruptible(&tun->tfile->read_wait);
+ wake_up_interruptible(&tun->socket.wait);
return 0;
drop:
@@ -490,7 +494,7 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name);
- poll_wait(file, &tfile->read_wait, wait);
+ poll_wait(file, &tun->socket.wait, wait);
if (!skb_queue_empty(&tun->readq))
mask |= POLLIN | POLLRDNORM;
@@ -763,7 +767,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
goto out;
}
- add_wait_queue(&tfile->read_wait, &wait);
+ add_wait_queue(&tun->socket.wait, &wait);
while (len) {
current->state = TASK_INTERRUPTIBLE;
@@ -794,7 +798,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
}
current->state = TASK_RUNNING;
- remove_wait_queue(&tfile->read_wait, &wait);
+ remove_wait_queue(&tun->socket.wait, &wait);
out:
tun_put(tun);
@@ -811,7 +815,7 @@ static void tun_setup(struct net_device *dev)
tun->group = -1;
dev->ethtool_ops = &tun_ethtool_ops;
- dev->destructor = free_netdev;
+ dev->destructor = tun_free_netdev;
}
/* Trivial set of netlink ops to allow deleting tun or tap
@@ -848,7 +852,7 @@ static void tun_sock_write_space(struct sock *sk)
static void tun_sock_destruct(struct sock *sk)
{
- dev_put(container_of(sk, struct tun_sock, sk)->tun->dev);
+ free_netdev(container_of(sk, struct tun_sock, sk)->tun->dev);
}
static struct proto tun_proto = {
@@ -862,7 +866,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
struct sock *sk;
struct tun_struct *tun;
struct net_device *dev;
- struct tun_file *tfile = file->private_data;
int err;
dev = __dev_get_by_name(net, ifr->ifr_name);
@@ -920,13 +923,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
if (!sk)
goto err_free_dev;
- /* This ref count is for tun->sk. */
- dev_hold(dev);
+ init_waitqueue_head(&tun->socket.wait);
sock_init_data(&tun->socket, sk);
sk->sk_write_space = tun_sock_write_space;
- sk->sk_destruct = tun_sock_destruct;
sk->sk_sndbuf = INT_MAX;
- sk->sk_sleep = &tfile->read_wait;
tun->sk = sk;
container_of(sk, struct tun_sock, sk)->tun = tun;
@@ -942,11 +942,13 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
err = -EINVAL;
err = register_netdevice(tun->dev);
if (err < 0)
- goto err_free_dev;
+ goto err_free_sk;
+
+ sk->sk_destruct = tun_sock_destruct;
err = tun_attach(tun, file);
if (err < 0)
- goto err_free_dev;
+ goto failed;
}
DBG(KERN_INFO "%s: tun_set_iff\n", tun->dev->name);
@@ -1266,7 +1268,6 @@ static int tun_chr_open(struct inode *inode, struct file * file)
atomic_set(&tfile->count, 0);
tfile->tun = NULL;
tfile->net = get_net(current->nsproxy->net_ns);
- init_waitqueue_head(&tfile->read_wait);
file->private_data = tfile;
return 0;
}
@@ -1284,14 +1285,16 @@ static int tun_chr_close(struct inode *inode, struct file *file)
__tun_detach(tun);
/* If desireable, unregister the netdevice. */
- if (!(tun->flags & TUN_PERSIST)) {
- sock_put(tun->sk);
+ if (!(tun->flags & TUN_PERSIST))
unregister_netdevice(tun->dev);
- }
rtnl_unlock();
}
+ tun = tfile->tun;
+ if (tun)
+ sock_put(tun->sk);
+
put_net(tfile->net);
kfree(tfile);
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index d3f39e86eb9..44f8392da11 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -1394,7 +1394,8 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
(ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
- upsmr |= UCC_GETH_UPSMR_RPM;
+ if (ugeth->phy_interface != PHY_INTERFACE_MODE_RMII)
+ upsmr |= UCC_GETH_UPSMR_RPM;
switch (ugeth->max_speed) {
case SPEED_10:
upsmr |= UCC_GETH_UPSMR_R10M;
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index a8228d87c8c..2138535f233 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -899,6 +899,7 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
/* cleanup should already have been scheduled */
break;
case -ENODEV: /* disconnect() upcoming */
+ case -EPERM:
netif_device_detach(pegasus->net);
break;
default:
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index f21a6171c69..c36d3a3d655 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -6713,11 +6713,11 @@ static int airo_set_auth(struct net_device *dev,
local->config.authType = AUTH_ENCRYPT;
} else
return -EINVAL;
- break;
/* Commit the changes to flags if needed */
if (local->config.authType != currentAuthType)
set_bit (FLAG_COMMIT, &local->flags);
+ break;
}
case IW_AUTH_WPA_ENABLED:
diff --git a/drivers/net/wireless/ar9170/hw.h b/drivers/net/wireless/ar9170/hw.h
index 13091bd9d81..53e250a4278 100644
--- a/drivers/net/wireless/ar9170/hw.h
+++ b/drivers/net/wireless/ar9170/hw.h
@@ -310,7 +310,7 @@ struct ar9170_tx_control {
struct ar9170_rx_head {
u8 plcp[12];
-};
+} __packed;
struct ar9170_rx_tail {
union {
@@ -318,16 +318,16 @@ struct ar9170_rx_tail {
u8 rssi_ant0, rssi_ant1, rssi_ant2,
rssi_ant0x, rssi_ant1x, rssi_ant2x,
rssi_combined;
- };
+ } __packed;
u8 rssi[7];
- };
+ } __packed;
u8 evm_stream0[6], evm_stream1[6];
u8 phy_err;
u8 SAidx, DAidx;
u8 error;
u8 status;
-};
+} __packed;
#define AR9170_ENC_ALG_NONE 0x0
#define AR9170_ENC_ALG_WEP64 0x1
diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ar9170/usb.c
index ad296840893..fddda477095 100644
--- a/drivers/net/wireless/ar9170/usb.c
+++ b/drivers/net/wireless/ar9170/usb.c
@@ -59,6 +59,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
{ USB_DEVICE(0x0cf3, 0x9170) },
/* Atheros TG121N */
{ USB_DEVICE(0x0cf3, 0x1001) },
+ /* Cace Airpcap NX */
+ { USB_DEVICE(0xcace, 0x0300) },
/* D-Link DWA 160A */
{ USB_DEVICE(0x07d1, 0x3c10) },
/* Netgear WNDA3100 */
@@ -67,6 +69,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
{ USB_DEVICE(0x0846, 0x9001) },
/* Zydas ZD1221 */
{ USB_DEVICE(0x0ace, 0x1221) },
+ /* ZyXEL NWD271N */
+ { USB_DEVICE(0x0586, 0x3417) },
/* Z-Com UB81 BG */
{ USB_DEVICE(0x0cde, 0x0023) },
/* Z-Com UB82 ABG */
@@ -619,6 +623,39 @@ static int ar9170_usb_open(struct ar9170 *ar)
return 0;
}
+static int ar9170_usb_init_device(struct ar9170_usb *aru)
+{
+ int err;
+
+ err = ar9170_usb_alloc_rx_irq_urb(aru);
+ if (err)
+ goto err_out;
+
+ err = ar9170_usb_alloc_rx_bulk_urbs(aru);
+ if (err)
+ goto err_unrx;
+
+ err = ar9170_usb_upload_firmware(aru);
+ if (err) {
+ err = ar9170_echo_test(&aru->common, 0x60d43110);
+ if (err) {
+ /* force user invention, by disabling the device */
+ err = usb_driver_set_configuration(aru->udev, -1);
+ dev_err(&aru->udev->dev, "device is in a bad state. "
+ "please reconnect it!\n");
+ goto err_unrx;
+ }
+ }
+
+ return 0;
+
+err_unrx:
+ ar9170_usb_cancel_urbs(aru);
+
+err_out:
+ return err;
+}
+
static int ar9170_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
@@ -654,32 +691,16 @@ static int ar9170_usb_probe(struct usb_interface *intf,
err = ar9170_usb_reset(aru);
if (err)
- goto err_unlock;
+ goto err_freehw;
err = ar9170_usb_request_firmware(aru);
if (err)
- goto err_unlock;
+ goto err_freehw;
- err = ar9170_usb_alloc_rx_irq_urb(aru);
+ err = ar9170_usb_init_device(aru);
if (err)
goto err_freefw;
- err = ar9170_usb_alloc_rx_bulk_urbs(aru);
- if (err)
- goto err_unrx;
-
- err = ar9170_usb_upload_firmware(aru);
- if (err) {
- err = ar9170_echo_test(&aru->common, 0x60d43110);
- if (err) {
- /* force user invention, by disabling the device */
- err = usb_driver_set_configuration(aru->udev, -1);
- dev_err(&aru->udev->dev, "device is in a bad state. "
- "please reconnect it!\n");
- goto err_unrx;
- }
- }
-
err = ar9170_usb_open(ar);
if (err)
goto err_unrx;
@@ -699,7 +720,7 @@ err_freefw:
release_firmware(aru->init_values);
release_firmware(aru->firmware);
-err_unlock:
+err_freehw:
usb_set_intfdata(intf, NULL);
usb_put_dev(udev);
ieee80211_free_hw(ar->hw);
@@ -726,12 +747,65 @@ static void ar9170_usb_disconnect(struct usb_interface *intf)
ieee80211_free_hw(aru->common.hw);
}
+#ifdef CONFIG_PM
+static int ar9170_suspend(struct usb_interface *intf,
+ pm_message_t message)
+{
+ struct ar9170_usb *aru = usb_get_intfdata(intf);
+
+ if (!aru)
+ return -ENODEV;
+
+ aru->common.state = AR9170_IDLE;
+ ar9170_usb_cancel_urbs(aru);
+
+ return 0;
+}
+
+static int ar9170_resume(struct usb_interface *intf)
+{
+ struct ar9170_usb *aru = usb_get_intfdata(intf);
+ int err;
+
+ if (!aru)
+ return -ENODEV;
+
+ usb_unpoison_anchored_urbs(&aru->rx_submitted);
+ usb_unpoison_anchored_urbs(&aru->tx_submitted);
+
+ /*
+ * FIXME: firmware upload will fail on resume.
+ * but this is better than a hang!
+ */
+
+ err = ar9170_usb_init_device(aru);
+ if (err)
+ goto err_unrx;
+
+ err = ar9170_usb_open(&aru->common);
+ if (err)
+ goto err_unrx;
+
+ return 0;
+
+err_unrx:
+ aru->common.state = AR9170_IDLE;
+ ar9170_usb_cancel_urbs(aru);
+
+ return err;
+}
+#endif /* CONFIG_PM */
+
static struct usb_driver ar9170_driver = {
.name = "ar9170usb",
.probe = ar9170_usb_probe,
.disconnect = ar9170_usb_disconnect,
.id_table = ar9170_usb_ids,
.soft_unbind = 1,
+#ifdef CONFIG_PM
+ .suspend = ar9170_suspend,
+ .resume = ar9170_resume,
+#endif /* CONFIG_PM */
};
static int __init ar9170_init(void)
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 0c02f1c2bd9..744f4f4dd3d 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -250,6 +250,8 @@ static struct usb_device_id dev_table[] = {
{ USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) },
/* Siemens Gigaset USB WLAN Adapter 11 */
{ USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) },
+ /* OQO Model 01+ Internal Wi-Fi */
+ { USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A) },
/*
* at76c505amx-rfmd
*/
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 71cb18d6757..dd1f3015674 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -493,6 +493,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
int hdrlen, padsize, retval;
bool decrypt_error = false;
u8 keyix;
+ __le16 fc;
spin_lock_bh(&sc->rx.rxbuflock);
@@ -606,6 +607,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
/* see if any padding is done by the hw and remove it */
hdr = (struct ieee80211_hdr *)skb->data;
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+ fc = hdr->frame_control;
/* The MAC header is padded to have 32-bit boundary if the
* packet payload is non-zero. The general calculation for
@@ -690,7 +692,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
sc->rx.rxotherant = 0;
}
- if (ieee80211_is_beacon(hdr->frame_control) &&
+ if (ieee80211_is_beacon(fc) &&
(sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) {
sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 857d84148b1..27eef8fb710 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -1502,7 +1502,6 @@ static const struct net_device_ops atmel_netdev_ops = {
.ndo_set_mac_address = atmel_set_mac_address,
.ndo_start_xmit = start_tx,
.ndo_do_ioctl = atmel_ioctl,
- .ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index e228c1de6e1..eae680b5305 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -555,11 +555,32 @@ address_error:
return 1;
}
+static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb)
+{
+ unsigned char *f = skb->data + ring->frameoffset;
+
+ return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) == 0xFF);
+}
+
+static void b43_poison_rx_buffer(struct b43_dmaring *ring, struct sk_buff *skb)
+{
+ struct b43_rxhdr_fw4 *rxhdr;
+ unsigned char *frame;
+
+ /* This poisons the RX buffer to detect DMA failures. */
+
+ rxhdr = (struct b43_rxhdr_fw4 *)(skb->data);
+ rxhdr->frame_len = 0;
+
+ B43_WARN_ON(ring->rx_buffersize < ring->frameoffset + sizeof(struct b43_plcp_hdr6) + 2);
+ frame = skb->data + ring->frameoffset;
+ memset(frame, 0xFF, sizeof(struct b43_plcp_hdr6) + 2 /* padding */);
+}
+
static int setup_rx_descbuffer(struct b43_dmaring *ring,
struct b43_dmadesc_generic *desc,
struct b43_dmadesc_meta *meta, gfp_t gfp_flags)
{
- struct b43_rxhdr_fw4 *rxhdr;
dma_addr_t dmaaddr;
struct sk_buff *skb;
@@ -568,6 +589,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
if (unlikely(!skb))
return -ENOMEM;
+ b43_poison_rx_buffer(ring, skb);
dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
/* ugh. try to realloc in zone_dma */
@@ -578,6 +600,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
if (unlikely(!skb))
return -ENOMEM;
+ b43_poison_rx_buffer(ring, skb);
dmaaddr = map_descbuffer(ring, skb->data,
ring->rx_buffersize, 0);
if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
@@ -592,9 +615,6 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
ring->ops->fill_descriptor(ring, desc, dmaaddr,
ring->rx_buffersize, 0, 0, 0);
- rxhdr = (struct b43_rxhdr_fw4 *)(skb->data);
- rxhdr->frame_len = 0;
-
return 0;
}
@@ -1483,12 +1503,17 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
len = le16_to_cpu(rxhdr->frame_len);
} while (len == 0 && i++ < 5);
if (unlikely(len == 0)) {
- /* recycle the descriptor buffer. */
- sync_descbuffer_for_device(ring, meta->dmaaddr,
- ring->rx_buffersize);
- goto drop;
+ dmaaddr = meta->dmaaddr;
+ goto drop_recycle_buffer;
}
}
+ if (unlikely(b43_rx_buffer_is_poisoned(ring, skb))) {
+ /* Something went wrong with the DMA.
+ * The device did not touch the buffer and did not overwrite the poison. */
+ b43dbg(ring->dev->wl, "DMA RX: Dropping poisoned buffer.\n");
+ dmaaddr = meta->dmaaddr;
+ goto drop_recycle_buffer;
+ }
if (unlikely(len > ring->rx_buffersize)) {
/* The data did not fit into one descriptor buffer
* and is split over multiple buffers.
@@ -1501,6 +1526,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
while (1) {
desc = ops->idx2desc(ring, *slot, &meta);
/* recycle the descriptor buffer. */
+ b43_poison_rx_buffer(ring, meta->skb);
sync_descbuffer_for_device(ring, meta->dmaaddr,
ring->rx_buffersize);
*slot = next_slot(ring, *slot);
@@ -1519,8 +1545,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC);
if (unlikely(err)) {
b43dbg(ring->dev->wl, "DMA RX: setup_rx_descbuffer() failed\n");
- sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize);
- goto drop;
+ goto drop_recycle_buffer;
}
unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
@@ -1530,6 +1555,11 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
b43_rx(ring->dev, skb, rxhdr);
drop:
return;
+
+drop_recycle_buffer:
+ /* Poison and recycle the RX buffer. */
+ b43_poison_rx_buffer(ring, skb);
+ sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize);
}
void b43_dma_rx(struct b43_dmaring *ring)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 4896e083111..79b685e300c 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3974,6 +3974,11 @@ static void setup_struct_phy_for_init(struct b43_wldev *dev,
phy->next_txpwr_check_time = jiffies;
/* PHY TX errors counter. */
atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
+
+#if B43_DEBUG
+ phy->phy_locked = 0;
+ phy->radio_locked = 0;
+#endif
}
static void setup_struct_wldev_for_init(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 026b61c03fb..e176b6e0d9c 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -131,12 +131,16 @@ void b43_radio_lock(struct b43_wldev *dev)
{
u32 macctl;
+#if B43_DEBUG
+ B43_WARN_ON(dev->phy.radio_locked);
+ dev->phy.radio_locked = 1;
+#endif
+
macctl = b43_read32(dev, B43_MMIO_MACCTL);
- B43_WARN_ON(macctl & B43_MACCTL_RADIOLOCK);
macctl |= B43_MACCTL_RADIOLOCK;
b43_write32(dev, B43_MMIO_MACCTL, macctl);
- /* Commit the write and wait for the device
- * to exit any radio register access. */
+ /* Commit the write and wait for the firmware
+ * to finish any radio register access. */
b43_read32(dev, B43_MMIO_MACCTL);
udelay(10);
}
@@ -145,11 +149,15 @@ void b43_radio_unlock(struct b43_wldev *dev)
{
u32 macctl;
+#if B43_DEBUG
+ B43_WARN_ON(!dev->phy.radio_locked);
+ dev->phy.radio_locked = 0;
+#endif
+
/* Commit any write */
b43_read16(dev, B43_MMIO_PHY_VER);
/* unlock */
macctl = b43_read32(dev, B43_MMIO_MACCTL);
- B43_WARN_ON(!(macctl & B43_MACCTL_RADIOLOCK));
macctl &= ~B43_MACCTL_RADIOLOCK;
b43_write32(dev, B43_MMIO_MACCTL, macctl);
}
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index c9f5430d1d7..b2d99101947 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -245,8 +245,10 @@ struct b43_phy {
atomic_t txerr_cnt;
#ifdef CONFIG_B43_DEBUG
- /* PHY registers locked by b43_phy_lock()? */
+ /* PHY registers locked (w.r.t. firmware) */
bool phy_locked;
+ /* Radio registers locked (w.r.t. firmware) */
+ bool radio_locked;
#endif /* B43_DEBUG */
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 2399328e8de..527525cc091 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1192,7 +1192,7 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
return -ENOMEM;
}
} else
- iwl_rx_queue_reset(priv, rxq);
+ iwl3945_rx_queue_reset(priv, rxq);
iwl3945_rx_replenish(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index ab7aaf6872c..55188844657 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -215,6 +215,7 @@ extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm);
extern int iwl3945_tx_queue_init(struct iwl_priv *priv,
struct iwl_tx_queue *txq, int count, u32 id);
extern void iwl3945_rx_replenish(void *data);
+extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq);
extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len,
const void *data);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 3889158b359..1ef4192207a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -976,11 +976,9 @@ void iwl_rx_handle(struct iwl_priv *priv)
rxq->queue[i] = NULL;
- dma_sync_single_range_for_cpu(
- &priv->pci_dev->dev, rxb->real_dma_addr,
- rxb->aligned_dma_addr - rxb->real_dma_addr,
- priv->hw_params.rx_buf_size,
- PCI_DMA_FROMDEVICE);
+ pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
+ priv->hw_params.rx_buf_size + 256,
+ PCI_DMA_FROMDEVICE);
pkt = (struct iwl_rx_packet *)rxb->skb->data;
/* Reclaim a command buffer only if this packet is a response
@@ -1031,9 +1029,6 @@ void iwl_rx_handle(struct iwl_priv *priv)
rxb->skb = NULL;
}
- pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
- priv->hw_params.rx_buf_size + 256,
- PCI_DMA_FROMDEVICE);
spin_lock_irqsave(&rxq->lock, flags);
list_add_tail(&rxb->list, &priv->rxq.rx_used);
spin_unlock_irqrestore(&rxq->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 2f1242447b3..6e983149b83 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -223,7 +223,7 @@
#define CSR_EEPROM_REG_MSK_DATA (0xFFFF0000)
/* EEPROM GP */
-#define CSR_EEPROM_GP_VALID_MSK (0x00000006)
+#define CSR_EEPROM_GP_VALID_MSK (0x00000007)
#define CSR_EEPROM_GP_BAD_SIGNATURE (0x00000000)
#define CSR_EEPROM_GP_IF_OWNER_MSK (0x00000180)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index ec9a13846ed..cf7f0db58fc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -360,12 +360,16 @@ struct iwl_host_cmd {
/**
* struct iwl_rx_queue - Rx queue
+ * @bd: driver's pointer to buffer of receive buffer descriptors (rbd)
+ * @dma_addr: bus address of buffer of receive buffer descriptors (rbd)
* @read: Shared index to newest available Rx buffer
* @write: Shared index to oldest written Rx packet
* @free_count: Number of pre-allocated buffers in rx_free
* @rx_free: list of free SKBs for use
* @rx_used: List of Rx buffers with no SKB
* @need_update: flag to indicate we need to update read/write index
+ * @rb_stts: driver's pointer to receive buffer status
+ * @rb_stts_dma: bus address of receive buffer status
*
* NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers
*/
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 1f117a49c56..71d5b8a1a73 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -799,6 +799,22 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Copy MAC header from skb into command buffer */
memcpy(tx_cmd->hdr, hdr, hdr_len);
+
+ /* Total # bytes to be transmitted */
+ len = (u16)skb->len;
+ tx_cmd->len = cpu_to_le16(len);
+
+ if (info->control.hw_key)
+ iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
+
+ /* TODO need this for burst mode later on */
+ iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
+
+ /* set is_hcca to 0; it probably will never be implemented */
+ iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);
+
+ iwl_update_tx_stats(priv, le16_to_cpu(fc), len);
+
/*
* Use the first empty entry in this queue's command buffer array
* to contain the Tx command and MAC header concatenated together
@@ -819,21 +835,30 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
else
len_org = 0;
+ /* Tell NIC about any 2-byte padding after MAC header */
+ if (len_org)
+ tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
+
/* Physical address of this Tx command's header (not MAC header!),
* within command buffer array. */
txcmd_phys = pci_map_single(priv->pci_dev,
- out_cmd, sizeof(struct iwl_cmd),
+ &out_cmd->hdr, len,
PCI_DMA_BIDIRECTIONAL);
pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
- pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd));
+ pci_unmap_len_set(&out_cmd->meta, len, len);
/* Add buffer containing Tx command and MAC(!) header to TFD's
* first entry */
- txcmd_phys += offsetof(struct iwl_cmd, hdr);
priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
txcmd_phys, len, 1, 0);
- if (info->control.hw_key)
- iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
+ if (!ieee80211_has_morefrags(hdr->frame_control)) {
+ txq->need_update = 1;
+ if (qc)
+ priv->stations[sta_id].tid[tid].seq_number = seq_number;
+ } else {
+ wait_write_ptr = 1;
+ txq->need_update = 0;
+ }
/* Set up TFD's 2nd entry to point directly to remainder of skb,
* if any (802.11 null frames have no payload). */
@@ -846,41 +871,29 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
0, 0);
}
- /* Tell NIC about any 2-byte padding after MAC header */
- if (len_org)
- tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
-
- /* Total # bytes to be transmitted */
- len = (u16)skb->len;
- tx_cmd->len = cpu_to_le16(len);
- /* TODO need this for burst mode later on */
- iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
-
- /* set is_hcca to 0; it probably will never be implemented */
- iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);
-
- iwl_update_tx_stats(priv, le16_to_cpu(fc), len);
-
scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
- offsetof(struct iwl_tx_cmd, scratch);
+ offsetof(struct iwl_tx_cmd, scratch);
+
+ len = sizeof(struct iwl_tx_cmd) +
+ sizeof(struct iwl_cmd_header) + hdr_len;
+ /* take back ownership of DMA buffer to enable update */
+ pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys,
+ len, PCI_DMA_BIDIRECTIONAL);
tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
- if (!ieee80211_has_morefrags(hdr->frame_control)) {
- txq->need_update = 1;
- if (qc)
- priv->stations[sta_id].tid[tid].seq_number = seq_number;
- } else {
- wait_write_ptr = 1;
- txq->need_update = 0;
- }
-
+ IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n",
+ le16_to_cpu(out_cmd->hdr.sequence));
+ IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx_cmd->tx_flags));
iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
-
iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
/* Set up entry for this TFD in Tx byte-count array */
- priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, len);
+ priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq,
+ le16_to_cpu(tx_cmd->len));
+
+ pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
+ len, PCI_DMA_BIDIRECTIONAL);
/* Tell device the write index *just past* this latest filled TFD */
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -968,18 +981,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
INDEX_TO_SEQ(q->write_ptr));
if (out_cmd->meta.flags & CMD_SIZE_HUGE)
out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
- len = (idx == TFD_CMD_SLOTS) ?
- IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
-
- phys_addr = pci_map_single(priv->pci_dev, out_cmd,
- len, PCI_DMA_BIDIRECTIONAL);
- pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr);
- pci_unmap_len_set(&out_cmd->meta, len, len);
- phys_addr += offsetof(struct iwl_cmd, hdr);
+ len = sizeof(struct iwl_cmd) - sizeof(struct iwl_cmd_meta);
+ len += (idx == TFD_CMD_SLOTS) ? IWL_MAX_SCAN_SIZE : 0;
- priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
- phys_addr, fix_size, 1,
- U32_PAD(cmd->len));
#ifdef CONFIG_IWLWIFI_DEBUG
switch (out_cmd->hdr.cmd) {
@@ -1007,6 +1011,15 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
/* Set up entry in queue's byte count circular buffer */
priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
+ phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr,
+ fix_size, PCI_DMA_BIDIRECTIONAL);
+ pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr);
+ pci_unmap_len_set(&out_cmd->meta, len, fix_size);
+
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ phys_addr, fix_size, 1,
+ U32_PAD(cmd->len));
+
/* Increment and update queue's write index */
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
ret = iwl_txq_update_write_ptr(priv, txq);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index ce729281ff6..617c4235d97 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -972,7 +972,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
dma_addr_t phys_addr;
dma_addr_t txcmd_phys;
int txq_id = skb_get_queue_mapping(skb);
- u16 len, idx, len_org, hdr_len;
+ u16 len, idx, len_org, hdr_len; /* TODO: len_org is not used */
u8 id;
u8 unicast;
u8 sta_id;
@@ -1074,6 +1074,40 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Copy MAC header from skb into command buffer */
memcpy(tx->hdr, hdr, hdr_len);
+
+ if (info->control.hw_key)
+ iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id);
+
+ /* TODO need this for burst mode later on */
+ iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id);
+
+ /* set is_hcca to 0; it probably will never be implemented */
+ iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0);
+
+ /* Total # bytes to be transmitted */
+ len = (u16)skb->len;
+ tx->len = cpu_to_le16(len);
+
+
+ tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
+ tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
+
+ if (!ieee80211_has_morefrags(hdr->frame_control)) {
+ txq->need_update = 1;
+ if (qc)
+ priv->stations_39[sta_id].tid[tid].seq_number = seq_number;
+ } else {
+ wait_write_ptr = 1;
+ txq->need_update = 0;
+ }
+
+ IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n",
+ le16_to_cpu(out_cmd->hdr.sequence));
+ IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx->tx_flags));
+ iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx));
+ iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr,
+ ieee80211_hdrlen(fc));
+
/*
* Use the first empty entry in this queue's command buffer array
* to contain the Tx command and MAC header concatenated together
@@ -1096,22 +1130,18 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Physical address of this Tx command's header (not MAC header!),
* within command buffer array. */
- txcmd_phys = pci_map_single(priv->pci_dev,
- out_cmd, sizeof(struct iwl_cmd),
- PCI_DMA_TODEVICE);
+ txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr,
+ len, PCI_DMA_TODEVICE);
+ /* we do not map meta data ... so we can safely access address to
+ * provide to unmap command*/
pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
- pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd));
- /* Add buffer containing Tx command and MAC(!) header to TFD's
- * first entry */
- txcmd_phys += offsetof(struct iwl_cmd, hdr);
+ pci_unmap_len_set(&out_cmd->meta, len, len);
/* Add buffer containing Tx command and MAC(!) header to TFD's
* first entry */
priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
txcmd_phys, len, 1, 0);
- if (info->control.hw_key)
- iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id);
/* Set up TFD's 2nd entry to point directly to remainder of skb,
* if any (802.11 null frames have no payload). */
@@ -1124,32 +1154,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
0, U32_PAD(len));
}
- /* Total # bytes to be transmitted */
- len = (u16)skb->len;
- tx->len = cpu_to_le16(len);
-
- /* TODO need this for burst mode later on */
- iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id);
-
- /* set is_hcca to 0; it probably will never be implemented */
- iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0);
-
- tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
- tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
-
- if (!ieee80211_has_morefrags(hdr->frame_control)) {
- txq->need_update = 1;
- if (qc)
- priv->stations_39[sta_id].tid[tid].seq_number = seq_number;
- } else {
- wait_write_ptr = 1;
- txq->need_update = 0;
- }
-
- iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx));
-
- iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr,
- ieee80211_hdrlen(fc));
/* Tell device the write index *just past* this latest filled TFD */
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -1661,6 +1665,37 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv)
spin_unlock_irqrestore(&rxq->lock, flags);
}
+void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
+{
+ unsigned long flags;
+ int i;
+ spin_lock_irqsave(&rxq->lock, flags);
+ INIT_LIST_HEAD(&rxq->rx_free);
+ INIT_LIST_HEAD(&rxq->rx_used);
+ /* Fill the rx_used queue with _all_ of the Rx buffers */
+ for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
+ /* In the reset function, these buffers may have been allocated
+ * to an SKB, so we need to unmap and free potential storage */
+ if (rxq->pool[i].skb != NULL) {
+ pci_unmap_single(priv->pci_dev,
+ rxq->pool[i].real_dma_addr,
+ priv->hw_params.rx_buf_size,
+ PCI_DMA_FROMDEVICE);
+ priv->alloc_rxb_skb--;
+ dev_kfree_skb(rxq->pool[i].skb);
+ rxq->pool[i].skb = NULL;
+ }
+ list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
+ }
+
+ /* Set us so that we have processed and used all buffers, but have
+ * not restocked the Rx queue with fresh buffers */
+ rxq->read = rxq->write = 0;
+ rxq->free_count = 0;
+ spin_unlock_irqrestore(&rxq->lock, flags);
+}
+EXPORT_SYMBOL(iwl3945_rx_queue_reset);
+
/*
* this should be called while priv->lock is locked
*/
@@ -1685,6 +1720,34 @@ void iwl3945_rx_replenish(void *data)
spin_unlock_irqrestore(&priv->lock, flags);
}
+/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
+ * If an SKB has been detached, the POOL needs to have its SKB set to NULL
+ * This free routine walks the list of POOL entries and if SKB is set to
+ * non NULL it is unmapped and freed
+ */
+static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
+{
+ int i;
+ for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
+ if (rxq->pool[i].skb != NULL) {
+ pci_unmap_single(priv->pci_dev,
+ rxq->pool[i].real_dma_addr,
+ priv->hw_params.rx_buf_size,
+ PCI_DMA_FROMDEVICE);
+ dev_kfree_skb(rxq->pool[i].skb);
+ }
+ }
+
+ pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
+ rxq->dma_addr);
+ pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status),
+ rxq->rb_stts, rxq->rb_stts_dma);
+ rxq->bd = NULL;
+ rxq->rb_stts = NULL;
+}
+EXPORT_SYMBOL(iwl3945_rx_queue_free);
+
+
/* Convert linear signal-to-noise ratio into dB */
static u8 ratio2dB[100] = {
/* 0 1 2 3 4 5 6 7 8 9 */
@@ -1802,9 +1865,9 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
rxq->queue[i] = NULL;
- pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->real_dma_addr,
- priv->hw_params.rx_buf_size,
- PCI_DMA_FROMDEVICE);
+ pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
+ priv->hw_params.rx_buf_size,
+ PCI_DMA_FROMDEVICE);
pkt = (struct iwl_rx_packet *)rxb->skb->data;
/* Reclaim a command buffer only if this packet is a response
@@ -1852,9 +1915,6 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
rxb->skb = NULL;
}
- pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
- priv->hw_params.rx_buf_size,
- PCI_DMA_FROMDEVICE);
spin_lock_irqsave(&rxq->lock, flags);
list_add_tail(&rxb->list, &priv->rxq.rx_used);
spin_unlock_irqrestore(&rxq->lock, flags);
@@ -4075,7 +4135,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (!static_key) {
sta_id = iwl3945_hw_find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211(priv, "leave - %pMnot in station map.\n",
+ IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
addr);
return -EINVAL;
}
@@ -4913,6 +4973,8 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
hw->wiphy->custom_regulatory = true;
+ hw->wiphy->max_scan_ssids = 1; /* WILL FIX */
+
/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
@@ -5194,12 +5256,12 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
iwl_rfkill_unregister(priv);
- cancel_delayed_work(&priv->rfkill_poll);
+ cancel_delayed_work_sync(&priv->rfkill_poll);
iwl3945_dealloc_ucode_pci(priv);
if (priv->rxq.bd)
- iwl_rx_queue_free(priv, &priv->rxq);
+ iwl3945_rx_queue_free(priv, &priv->rxq);
iwl3945_hw_txq_ctx_free(priv);
iwl3945_unset_hw_params(priv);
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 63d7e19ce9b..8e669775cb5 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -170,6 +170,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
lbs_deb_rx("rx err: frame received with bad length\n");
dev->stats.rx_length_errors++;
ret = 0;
+ dev_kfree_skb(skb);
goto done;
}
@@ -181,6 +182,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
lbs_pr_alert("rxpd not ok\n");
dev->stats.rx_errors++;
ret = 0;
+ dev_kfree_skb(skb);
goto done;
}
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 57a0268d1ba..a9a970469c2 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -893,8 +893,7 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
rx_desc->next_rx_desc_phys_addr =
cpu_to_le32(rxq->rx_desc_dma
+ nexti * sizeof(*rx_desc));
- rx_desc->rx_ctrl =
- cpu_to_le32(MWL8K_RX_CTRL_OWNED_BY_HOST);
+ rx_desc->rx_ctrl = MWL8K_RX_CTRL_OWNED_BY_HOST;
}
return 0;
@@ -3720,12 +3719,12 @@ err_free_reg:
return rc;
}
-static void __devexit mwl8k_remove(struct pci_dev *pdev)
+static void __devexit mwl8k_shutdown(struct pci_dev *pdev)
{
printk(KERN_ERR "===>%s(%u)\n", __func__, __LINE__);
}
-static void __devexit mwl8k_shutdown(struct pci_dev *pdev)
+static void __devexit mwl8k_remove(struct pci_dev *pdev)
{
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct mwl8k_priv *priv;
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 081428d9409..632fac86a30 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -372,15 +372,13 @@ int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
}
/* Wait upto 100ms for tx queue to empty */
- k = 100;
- do {
- k--;
+ for (k = 100; k > 0; k--) {
udelay(1000);
ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
&xmitting);
- if (ret)
+ if (ret || !xmitting)
break;
- } while ((k > 0) && xmitting);
+ }
if (k == 0)
ret = -ETIMEDOUT;
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 2dda5fe418b..ecf8b6ed5a4 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -14,9 +14,9 @@
* published by the Free Software Foundation.
*/
-#ifdef CONFIG_MAC80211_LEDS
+#ifdef CONFIG_P54_LEDS
#include <linux/leds.h>
-#endif /* CONFIG_MAC80211_LEDS */
+#endif /* CONFIG_P54_LEDS */
enum p54_control_frame_types {
P54_CONTROL_TYPE_SETUP = 0,
@@ -116,7 +116,7 @@ enum fw_state {
FW_STATE_RESETTING,
};
-#ifdef CONFIG_MAC80211_LEDS
+#ifdef CONFIG_P54_LEDS
#define P54_LED_MAX_NAME_LEN 31
@@ -129,7 +129,7 @@ struct p54_led_dev {
unsigned int registered;
};
-#endif /* CONFIG_MAC80211_LEDS */
+#endif /* CONFIG_P54_LEDS */
struct p54_common {
struct ieee80211_hw *hw;
@@ -177,10 +177,10 @@ struct p54_common {
u8 privacy_caps;
u8 rx_keycache_size;
/* LED management */
- #ifdef CONFIG_MAC80211_LEDS
+#ifdef CONFIG_P54_LEDS
struct p54_led_dev assoc_led;
struct p54_led_dev tx_led;
- #endif /* CONFIG_MAC80211_LEDS */
+#endif /* CONFIG_P54_LEDS */
u16 softled_state; /* bit field of glowing LEDs */
};
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 0c1b0577d4e..c8f0232ee5e 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -2543,8 +2543,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
priv->basic_rate_mask = 0x15f;
skb_queue_head_init(&priv->tx_queue);
dev->flags = IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_SUPPORTS_PS |
- IEEE80211_HW_PS_NULLFUNC_STACK |
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM;
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index 2b222aaa6f0..d1fe577de3d 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -457,9 +457,10 @@ static int p54spi_wq_tx(struct p54s_priv *priv)
struct ieee80211_tx_info *info;
struct p54_tx_info *minfo;
struct p54s_tx_info *dinfo;
+ unsigned long flags;
int ret = 0;
- spin_lock_bh(&priv->tx_lock);
+ spin_lock_irqsave(&priv->tx_lock, flags);
while (!list_empty(&priv->tx_pending)) {
entry = list_entry(priv->tx_pending.next,
@@ -467,7 +468,7 @@ static int p54spi_wq_tx(struct p54s_priv *priv)
list_del_init(&entry->tx_list);
- spin_unlock_bh(&priv->tx_lock);
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
dinfo = container_of((void *) entry, struct p54s_tx_info,
tx_list);
@@ -479,16 +480,14 @@ static int p54spi_wq_tx(struct p54s_priv *priv)
ret = p54spi_tx_frame(priv, skb);
- spin_lock_bh(&priv->tx_lock);
-
if (ret < 0) {
p54_free_skb(priv->hw, skb);
- goto out;
+ return ret;
}
- }
-out:
- spin_unlock_bh(&priv->tx_lock);
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ }
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
return ret;
}
@@ -498,12 +497,13 @@ static void p54spi_op_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct p54_tx_info *mi = (struct p54_tx_info *) info->rate_driver_data;
struct p54s_tx_info *di = (struct p54s_tx_info *) mi->data;
+ unsigned long flags;
BUILD_BUG_ON(sizeof(*di) > sizeof((mi->data)));
- spin_lock_bh(&priv->tx_lock);
+ spin_lock_irqsave(&priv->tx_lock, flags);
list_add_tail(&di->tx_list, &priv->tx_pending);
- spin_unlock_bh(&priv->tx_lock);
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
queue_work(priv->hw->workqueue, &priv->work);
}
@@ -604,6 +604,7 @@ out:
static void p54spi_op_stop(struct ieee80211_hw *dev)
{
struct p54s_priv *priv = dev->priv;
+ unsigned long flags;
if (mutex_lock_interruptible(&priv->mutex)) {
/* FIXME: how to handle this error? */
@@ -615,9 +616,9 @@ static void p54spi_op_stop(struct ieee80211_hw *dev)
cancel_work_sync(&priv->work);
p54spi_power_off(priv);
- spin_lock_bh(&priv->tx_lock);
+ spin_lock_irqsave(&priv->tx_lock, flags);
INIT_LIST_HEAD(&priv->tx_pending);
- spin_unlock_bh(&priv->tx_lock);
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
priv->fw_state = FW_STATE_OFF;
mutex_unlock(&priv->mutex);
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index da6640afc83..6cc6cbc9234 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -71,6 +71,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
{USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */
{USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */
{USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
+ {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */
{USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
{USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
{USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 05f94e21b42..5752aaae906 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -646,10 +646,8 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
* Register HW.
*/
status = ieee80211_register_hw(rt2x00dev->hw);
- if (status) {
- rt2x00lib_remove_hw(rt2x00dev);
+ if (status)
return status;
- }
set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 43fa0f84900..9730b4f8fd2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -369,8 +369,6 @@ int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state)
if (retval)
return retval;
- rt2x00pci_free_reg(rt2x00dev);
-
pci_save_state(pci_dev);
pci_disable_device(pci_dev);
return pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
@@ -381,7 +379,6 @@ int rt2x00pci_resume(struct pci_dev *pci_dev)
{
struct ieee80211_hw *hw = pci_get_drvdata(pci_dev);
struct rt2x00_dev *rt2x00dev = hw->priv;
- int retval;
if (pci_set_power_state(pci_dev, PCI_D0) ||
pci_enable_device(pci_dev) ||
@@ -390,20 +387,7 @@ int rt2x00pci_resume(struct pci_dev *pci_dev)
return -EIO;
}
- retval = rt2x00pci_alloc_reg(rt2x00dev);
- if (retval)
- return retval;
-
- retval = rt2x00lib_resume(rt2x00dev);
- if (retval)
- goto exit_free_reg;
-
- return 0;
-
-exit_free_reg:
- rt2x00pci_free_reg(rt2x00dev);
-
- return retval;
+ return rt2x00lib_resume(rt2x00dev);
}
EXPORT_SYMBOL_GPL(rt2x00pci_resume);
#endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 7d50ca82375..501544882c2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -702,8 +702,6 @@ int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state)
if (retval)
return retval;
- rt2x00usb_free_reg(rt2x00dev);
-
/*
* Decrease usbdev refcount.
*/
@@ -717,24 +715,10 @@ int rt2x00usb_resume(struct usb_interface *usb_intf)
{
struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);
struct rt2x00_dev *rt2x00dev = hw->priv;
- int retval;
usb_get_dev(interface_to_usbdev(usb_intf));
- retval = rt2x00usb_alloc_reg(rt2x00dev);
- if (retval)
- return retval;
-
- retval = rt2x00lib_resume(rt2x00dev);
- if (retval)
- goto exit_free_reg;
-
- return 0;
-
-exit_free_reg:
- rt2x00usb_free_reg(rt2x00dev);
-
- return retval;
+ return rt2x00lib_resume(rt2x00dev);
}
EXPORT_SYMBOL_GPL(rt2x00usb_resume);
#endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 420fff42c0d..853b2b279b6 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2369,6 +2369,8 @@ static struct usb_device_id rt73usb_device_table[] = {
/* Buffalo */
{ USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) },
/* CNet */
{ USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) },
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index 1cd02f5a23a..bc43f78f6f0 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -255,6 +255,9 @@ static int __init sharpsl_pcmcia_init(void)
{
int ret;
+ if (!platform_scoop_config)
+ return -ENODEV;
+
sharpsl_pcmcia_ops.nr = platform_scoop_config->num_devs;
sharpsl_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index d3c92d777bd..552958545f9 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -317,7 +317,8 @@ static void sony_laptop_report_input_event(u8 event)
struct input_dev *key_dev = sony_laptop_input.key_dev;
struct sony_laptop_keypress kp = { NULL };
- if (event == SONYPI_EVENT_FNKEY_RELEASED) {
+ if (event == SONYPI_EVENT_FNKEY_RELEASED ||
+ event == SONYPI_EVENT_ANYBUTTON_RELEASED) {
/* Nothing, not all VAIOs generate this event */
return;
}
@@ -905,7 +906,6 @@ static struct sony_nc_event sony_127_events[] = {
{ 0x05, SONYPI_EVENT_ANYBUTTON_RELEASED },
{ 0x86, SONYPI_EVENT_PKEY_P5 },
{ 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
- { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
{ 0x87, SONYPI_EVENT_SETTINGKEY_PRESSED },
{ 0x07, SONYPI_EVENT_ANYBUTTON_RELEASED },
{ 0, 0 },
@@ -1004,6 +1004,7 @@ static int sony_nc_function_setup(struct acpi_device *device)
sony_call_snc_handle(0x0100, 0, &result);
sony_call_snc_handle(0x0101, 0, &result);
sony_call_snc_handle(0x0102, 0x100, &result);
+ sony_call_snc_handle(0x0127, 0, &result);
return 0;
}
@@ -1040,7 +1041,7 @@ static int sony_nc_resume(struct acpi_device *device)
/* set the last requested brightness level */
if (sony_backlight_device &&
- !sony_backlight_update_status(sony_backlight_device))
+ sony_backlight_update_status(sony_backlight_device) < 0)
printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
return 0;
@@ -1102,8 +1103,11 @@ static int sony_nc_setup_wifi_rfkill(struct acpi_device *device)
err = rfkill_register(sony_wifi_rfkill);
if (err)
rfkill_free(sony_wifi_rfkill);
- else
+ else {
sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill;
+ sony_nc_rfkill_set(sony_wifi_rfkill->data,
+ RFKILL_STATE_UNBLOCKED);
+ }
return err;
}
@@ -1124,8 +1128,11 @@ static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device)
err = rfkill_register(sony_bluetooth_rfkill);
if (err)
rfkill_free(sony_bluetooth_rfkill);
- else
+ else {
sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill;
+ sony_nc_rfkill_set(sony_bluetooth_rfkill->data,
+ RFKILL_STATE_UNBLOCKED);
+ }
return err;
}
@@ -1145,8 +1152,11 @@ static int sony_nc_setup_wwan_rfkill(struct acpi_device *device)
err = rfkill_register(sony_wwan_rfkill);
if (err)
rfkill_free(sony_wwan_rfkill);
- else
+ else {
sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill;
+ sony_nc_rfkill_set(sony_wwan_rfkill->data,
+ RFKILL_STATE_UNBLOCKED);
+ }
return err;
}
@@ -1166,8 +1176,11 @@ static int sony_nc_setup_wimax_rfkill(struct acpi_device *device)
err = rfkill_register(sony_wimax_rfkill);
if (err)
rfkill_free(sony_wimax_rfkill);
- else
+ else {
sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill;
+ sony_nc_rfkill_set(sony_wimax_rfkill->data,
+ RFKILL_STATE_UNBLOCKED);
+ }
return err;
}
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index a40b075743d..912be65b626 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -21,7 +21,7 @@
* 02110-1301, USA.
*/
-#define TPACPI_VERSION "0.22"
+#define TPACPI_VERSION "0.23"
#define TPACPI_SYSFS_VERSION 0x020300
/*
@@ -303,11 +303,17 @@ static u32 dbg_level;
static struct workqueue_struct *tpacpi_wq;
+enum led_status_t {
+ TPACPI_LED_OFF = 0,
+ TPACPI_LED_ON,
+ TPACPI_LED_BLINK,
+};
+
/* Special LED class that can defer work */
struct tpacpi_led_classdev {
struct led_classdev led_classdev;
struct work_struct work;
- enum led_brightness new_brightness;
+ enum led_status_t new_state;
unsigned int led;
};
@@ -2946,12 +2952,18 @@ static int hotkey_read(char *p)
return len;
}
-static void hotkey_enabledisable_warn(void)
+static void hotkey_enabledisable_warn(bool enable)
{
tpacpi_log_usertask("procfs hotkey enable/disable");
- WARN(1, TPACPI_WARN
- "hotkey enable/disable functionality has been "
- "removed from the driver. Hotkeys are always enabled.\n");
+ if (!WARN((tpacpi_lifecycle == TPACPI_LIFE_RUNNING || !enable),
+ TPACPI_WARN
+ "hotkey enable/disable functionality has been "
+ "removed from the driver. Hotkeys are always "
+ "enabled\n"))
+ printk(TPACPI_ERR
+ "Please remove the hotkey=enable module "
+ "parameter, it is deprecated. Hotkeys are always "
+ "enabled\n");
}
static int hotkey_write(char *buf)
@@ -2971,9 +2983,9 @@ static int hotkey_write(char *buf)
res = 0;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "enable") == 0) {
- hotkey_enabledisable_warn();
+ hotkey_enabledisable_warn(1);
} else if (strlencmp(cmd, "disable") == 0) {
- hotkey_enabledisable_warn();
+ hotkey_enabledisable_warn(0);
res = -EPERM;
} else if (strlencmp(cmd, "reset") == 0) {
mask = hotkey_orig_mask;
@@ -4207,7 +4219,7 @@ static void light_set_status_worker(struct work_struct *work)
container_of(work, struct tpacpi_led_classdev, work);
if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
- light_set_status((data->new_brightness != LED_OFF));
+ light_set_status((data->new_state != TPACPI_LED_OFF));
}
static void light_sysfs_set(struct led_classdev *led_cdev,
@@ -4217,7 +4229,8 @@ static void light_sysfs_set(struct led_classdev *led_cdev,
container_of(led_cdev,
struct tpacpi_led_classdev,
led_classdev);
- data->new_brightness = brightness;
+ data->new_state = (brightness != LED_OFF) ?
+ TPACPI_LED_ON : TPACPI_LED_OFF;
queue_work(tpacpi_wq, &data->work);
}
@@ -4724,12 +4737,6 @@ enum { /* For TPACPI_LED_OLD */
TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */
};
-enum led_status_t {
- TPACPI_LED_OFF = 0,
- TPACPI_LED_ON,
- TPACPI_LED_BLINK,
-};
-
static enum led_access_mode led_supported;
TPACPI_HANDLE(led, ec, "SLED", /* 570 */
@@ -4841,23 +4848,13 @@ static int led_set_status(const unsigned int led,
return rc;
}
-static void led_sysfs_set_status(unsigned int led,
- enum led_brightness brightness)
-{
- led_set_status(led,
- (brightness == LED_OFF) ?
- TPACPI_LED_OFF :
- (tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ?
- TPACPI_LED_BLINK : TPACPI_LED_ON);
-}
-
static void led_set_status_worker(struct work_struct *work)
{
struct tpacpi_led_classdev *data =
container_of(work, struct tpacpi_led_classdev, work);
if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
- led_sysfs_set_status(data->led, data->new_brightness);
+ led_set_status(data->led, data->new_state);
}
static void led_sysfs_set(struct led_classdev *led_cdev,
@@ -4866,7 +4863,13 @@ static void led_sysfs_set(struct led_classdev *led_cdev,
struct tpacpi_led_classdev *data = container_of(led_cdev,
struct tpacpi_led_classdev, led_classdev);
- data->new_brightness = brightness;
+ if (brightness == LED_OFF)
+ data->new_state = TPACPI_LED_OFF;
+ else if (tpacpi_led_state_cache[data->led] != TPACPI_LED_BLINK)
+ data->new_state = TPACPI_LED_ON;
+ else
+ data->new_state = TPACPI_LED_BLINK;
+
queue_work(tpacpi_wq, &data->work);
}
@@ -4884,7 +4887,7 @@ static int led_sysfs_blink_set(struct led_classdev *led_cdev,
} else if ((*delay_on != 500) || (*delay_off != 500))
return -EINVAL;
- data->new_brightness = TPACPI_LED_BLINK;
+ data->new_state = TPACPI_LED_BLINK;
queue_work(tpacpi_wq, &data->work);
return 0;
@@ -7858,6 +7861,15 @@ static int __init thinkpad_acpi_module_init(void)
MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
/*
+ * This will autoload the driver in almost every ThinkPad
+ * in widespread use.
+ *
+ * Only _VERY_ old models, like the 240, 240x and 570 lack
+ * the HKEY event interface.
+ */
+MODULE_DEVICE_TABLE(acpi, ibm_htk_device_ids);
+
+/*
* DMI matching for module autoloading
*
* See http://thinkwiki.org/wiki/List_of_DMI_IDs
@@ -7869,18 +7881,13 @@ MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
#define IBM_BIOS_MODULE_ALIAS(__type) \
MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW*")
-/* Non-ancient thinkpads */
-MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*");
-MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*");
-
/* Ancient thinkpad BIOSes have to be identified by
* BIOS type or model number, and there are far less
* BIOS types than model numbers... */
-IBM_BIOS_MODULE_ALIAS("I[BDHIMNOTWVYZ]");
-IBM_BIOS_MODULE_ALIAS("1[0368A-GIKM-PST]");
-IBM_BIOS_MODULE_ALIAS("K[UX-Z]");
+IBM_BIOS_MODULE_ALIAS("I[MU]"); /* 570, 570e */
-MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh");
+MODULE_AUTHOR("Borislav Deianov <borislav@users.sf.net>");
+MODULE_AUTHOR("Henrique de Moraes Holschuh <hmh@hmh.eng.br>");
MODULE_DESCRIPTION(TPACPI_DESC);
MODULE_VERSION(TPACPI_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
index c07809c8016..5469e099597 100644
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -285,7 +285,7 @@ extern int tape_mtop(struct tape_device *, int, int);
extern void tape_state_set(struct tape_device *, enum tape_state);
extern int tape_generic_online(struct tape_device *, struct tape_discipline *);
-extern int tape_generic_offline(struct tape_device *device);
+extern int tape_generic_offline(struct ccw_device *);
/* Externals from tape_devmap.c */
extern int tape_generic_probe(struct ccw_device *);
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 807ded5eb04..5f8e8ef43dd 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -1294,12 +1294,6 @@ tape_34xx_online(struct ccw_device *cdev)
);
}
-static int
-tape_34xx_offline(struct ccw_device *cdev)
-{
- return tape_generic_offline(cdev->dev.driver_data);
-}
-
static struct ccw_driver tape_34xx_driver = {
.name = "tape_34xx",
.owner = THIS_MODULE,
@@ -1307,7 +1301,7 @@ static struct ccw_driver tape_34xx_driver = {
.probe = tape_generic_probe,
.remove = tape_generic_remove,
.set_online = tape_34xx_online,
- .set_offline = tape_34xx_offline,
+ .set_offline = tape_generic_offline,
};
static int
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index fc1d9129414..823b05bd0dd 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -1707,19 +1707,13 @@ tape_3590_online(struct ccw_device *cdev)
&tape_discipline_3590);
}
-static int
-tape_3590_offline(struct ccw_device *cdev)
-{
- return tape_generic_offline(cdev->dev.driver_data);
-}
-
static struct ccw_driver tape_3590_driver = {
.name = "tape_3590",
.owner = THIS_MODULE,
.ids = tape_3590_ids,
.probe = tape_generic_probe,
.remove = tape_generic_remove,
- .set_offline = tape_3590_offline,
+ .set_offline = tape_generic_offline,
.set_online = tape_3590_online,
};
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 08c09d3503c..8a109f3b69c 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -387,8 +387,11 @@ tape_cleanup_device(struct tape_device *device)
* Manual offline is only allowed while the drive is not in use.
*/
int
-tape_generic_offline(struct tape_device *device)
+tape_generic_offline(struct ccw_device *cdev)
{
+ struct tape_device *device;
+
+ device = cdev->dev.driver_data;
if (!device) {
return -ENODEV;
}
diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c
index 61af3d91ac8..e3519fa5a3b 100644
--- a/drivers/scsi/a4000t.c
+++ b/drivers/scsi/a4000t.c
@@ -129,7 +129,7 @@ static int __init a4000t_scsi_init(void)
a4000t_scsi_device = platform_device_register_simple("a4000t-scsi",
-1, NULL, 0);
if (IS_ERR(a4000t_scsi_device)) {
- platform_driver_register(&a4000t_scsi_driver);
+ platform_driver_unregister(&a4000t_scsi_driver);
return PTR_ERR(a4000t_scsi_device);
}
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 7ddff3f5508..938bc1b6c3f 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -771,8 +771,6 @@ static int pci_netmos_init(struct pci_dev *dev)
}
/*
- * ITE support by Niels de Vos <niels.devos@wincor-nixdorf.com>
- *
* These chips are available with optionally one parallel port and up to
* two serial ports. Unfortunately they all have the same product id.
*
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 34e6108e1d4..0fe434505ac 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -3,7 +3,7 @@
*
* This driver supports USB CDC WCM Device Management.
*
- * Copyright (c) 2007-2008 Oliver Neukum
+ * Copyright (c) 2007-2009 Oliver Neukum
*
* Some code taken from cdc-acm.c
*
@@ -610,7 +610,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (!buffer)
goto out;
- while (buflen > 0) {
+ while (buflen > 2) {
if (buffer [1] != USB_DT_CS_INTERFACE) {
dev_err(&intf->dev, "skipping garbage\n");
goto next_desc;
@@ -646,16 +646,18 @@ next_desc:
spin_lock_init(&desc->iuspin);
init_waitqueue_head(&desc->wait);
desc->wMaxCommand = maxcom;
+ /* this will be expanded and needed in hardware endianness */
desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber);
desc->intf = intf;
INIT_WORK(&desc->rxwork, wdm_rxwork);
- iface = &intf->altsetting[0];
+ rv = -EINVAL;
+ iface = intf->cur_altsetting;
+ if (iface->desc.bNumEndpoints != 1)
+ goto err;
ep = &iface->endpoint[0].desc;
- if (!ep || !usb_endpoint_is_int_in(ep)) {
- rv = -EINVAL;
+ if (!ep || !usb_endpoint_is_int_in(ep))
goto err;
- }
desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize);
desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0;
@@ -711,12 +713,19 @@ next_desc:
usb_set_intfdata(intf, desc);
rv = usb_register_dev(intf, &wdm_class);
- dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n",
- intf->minor - WDM_MINOR_BASE);
if (rv < 0)
- goto err;
+ goto err3;
+ else
+ dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n",
+ intf->minor - WDM_MINOR_BASE);
out:
return rv;
+err3:
+ usb_set_intfdata(intf, NULL);
+ usb_buffer_free(interface_to_usbdev(desc->intf),
+ desc->bMaxPacketSize0,
+ desc->inbuf,
+ desc->response->transfer_dma);
err2:
usb_buffer_free(interface_to_usbdev(desc->intf),
desc->wMaxPacketSize,
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index cadb2dc1d28..3ba2fff7149 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -119,7 +119,7 @@ void *hcd_buffer_alloc(
if (size <= pool_max [i])
return dma_pool_alloc(hcd->pool [i], mem_flags, dma);
}
- return dma_alloc_coherent(hcd->self.controller, size, dma, 0);
+ return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);
}
void hcd_buffer_free(
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 22c65960c42..38e531ecae4 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -51,6 +51,7 @@
* - Gadget API (majority of optional features)
* - Suspend & Remote Wakeup
*/
+#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dmapool.h>
#include <linux/dma-mapping.h>
@@ -142,7 +143,7 @@ static struct {
#define CAP_DEVICEADDR (0x014UL)
#define CAP_ENDPTLISTADDR (0x018UL)
#define CAP_PORTSC (0x044UL)
-#define CAP_DEVLC (0x0B4UL)
+#define CAP_DEVLC (0x084UL)
#define CAP_USBMODE (hw_bank.lpm ? 0x0C8UL : 0x068UL)
#define CAP_ENDPTSETUPSTAT (hw_bank.lpm ? 0x0D8UL : 0x06CUL)
#define CAP_ENDPTPRIME (hw_bank.lpm ? 0x0DCUL : 0x070UL)
@@ -1986,6 +1987,8 @@ static int ep_enable(struct usb_ep *ep,
do {
dbg_event(_usb_addr(mEp), "ENABLE", 0);
+ mEp->qh[mEp->dir].ptr->cap = 0;
+
if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
mEp->qh[mEp->dir].ptr->cap |= QH_IOS;
else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 5c030b080d4..381a53b3e11 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -738,7 +738,6 @@ static struct fsg_dev *the_fsg;
static struct usb_gadget_driver fsg_driver;
static void close_backing_file(struct lun *curlun);
-static void close_all_backing_files(struct fsg_dev *fsg);
/*-------------------------------------------------------------------------*/
@@ -3593,12 +3592,10 @@ static int fsg_main_thread(void *fsg_)
fsg->thread_task = NULL;
spin_unlock_irq(&fsg->lock);
- /* In case we are exiting because of a signal, unregister the
- * gadget driver and close the backing file. */
- if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) {
+ /* If we are exiting because of a signal, unregister the
+ * gadget driver. */
+ if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags))
usb_gadget_unregister_driver(&fsg_driver);
- close_all_backing_files(fsg);
- }
/* Let the unbind and cleanup routines know the thread has exited */
complete_and_exit(&fsg->thread_notifier, 0);
@@ -3703,14 +3700,6 @@ static void close_backing_file(struct lun *curlun)
}
}
-static void close_all_backing_files(struct fsg_dev *fsg)
-{
- int i;
-
- for (i = 0; i < fsg->nluns; ++i)
- close_backing_file(&fsg->luns[i]);
-}
-
static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf)
{
@@ -3845,6 +3834,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
if (curlun->registered) {
device_remove_file(&curlun->dev, &dev_attr_ro);
device_remove_file(&curlun->dev, &dev_attr_file);
+ close_backing_file(curlun);
device_unregister(&curlun->dev);
curlun->registered = 0;
}
@@ -4190,7 +4180,6 @@ autoconf_fail:
out:
fsg->state = FSG_STATE_TERMINATED; // The thread is dead
fsg_unbind(gadget);
- close_all_backing_files(fsg);
complete(&fsg->thread_notifier);
return rc;
}
@@ -4284,7 +4273,6 @@ static void __exit fsg_cleanup(void)
/* Wait for the thread to finish up */
wait_for_completion(&fsg->thread_notifier);
- close_all_backing_files(fsg);
kref_put(&fsg->ref, fsg_release);
}
module_exit(fsg_cleanup);
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 57d9641c6bf..a2db0e174f2 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -3104,7 +3104,6 @@ static int omap_udc_resume(struct platform_device *dev)
/*-------------------------------------------------------------------------*/
static struct platform_driver udc_driver = {
- .probe = omap_udc_probe,
.remove = __exit_p(omap_udc_remove),
.suspend = omap_udc_suspend,
.resume = omap_udc_resume,
@@ -3122,7 +3121,7 @@ static int __init udc_init(void)
#endif
"%s\n", driver_desc,
use_dma ? " (dma)" : "");
- return platform_driver_register(&udc_driver);
+ return platform_driver_probe(&udc_driver, omap_udc_probe);
}
module_init(udc_init);
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index ada5d2ba297..556d0ec0c1f 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -323,7 +323,7 @@ static int tt_available (
* already scheduled transactions
*/
if (125 < usecs) {
- int ufs = (usecs / 125) - 1;
+ int ufs = (usecs / 125);
int i;
for (i = uframe; i < (uframe + ufs) && i < 8; i++)
if (0 < tt_usecs[i]) {
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 0112353ec97..4000cf6d1e8 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -2191,7 +2191,7 @@ static int musb_resume_early(struct platform_device *pdev)
#else
#define musb_suspend NULL
-#define musb_resume NULL
+#define musb_resume_early NULL
#endif
static struct platform_driver musb_driver = {
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 901dffdf23b..60924ce0849 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -3,7 +3,6 @@
* Some code has been taken from tusb6010.c
* Copyrights for that are attributable to:
* Copyright (C) 2006 Nokia Corporation
- * Jarkko Nikula <jarkko.nikula@nokia.com>
* Tony Lindgren <tony@atomide.com>
*
* This file is part of the Inventra Controller Driver for Linux.
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
index 9e20fd070d7..4ac1477d356 100644
--- a/drivers/usb/musb/tusb6010.c
+++ b/drivers/usb/musb/tusb6010.c
@@ -2,7 +2,6 @@
* TUSB6010 USB 2.0 OTG Dual Role controller
*
* Copyright (C) 2006 Nokia Corporation
- * Jarkko Nikula <jarkko.nikula@nokia.com>
* Tony Lindgren <tony@atomide.com>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/drivers/usb/musb/tusb6010.h b/drivers/usb/musb/tusb6010.h
index ab8c96286ce..35c933a5d99 100644
--- a/drivers/usb/musb/tusb6010.h
+++ b/drivers/usb/musb/tusb6010.h
@@ -2,7 +2,6 @@
* Definitions for TUSB6010 USB 2.0 OTG Dual Role controller
*
* Copyright (C) 2006 Nokia Corporation
- * Jarkko Nikula <jarkko.nikula@nokia.com>
* Tony Lindgren <tony@atomide.com>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c
index ff318fae7d4..0a43a7db750 100644
--- a/drivers/usb/otg/otg.c
+++ b/drivers/usb/otg/otg.c
@@ -43,7 +43,8 @@ EXPORT_SYMBOL(otg_get_transceiver);
*/
void otg_put_transceiver(struct otg_transceiver *x)
{
- put_device(x->dev);
+ if (x)
+ put_device(x->dev);
}
EXPORT_SYMBOL(otg_put_transceiver);
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 858bdd038fb..dd501bb63ed 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -175,13 +175,6 @@ static int cyberjack_open(struct tty_struct *tty,
dbg("%s - usb_clear_halt", __func__);
usb_clear_halt(port->serial->dev, port->write_urb->pipe);
- /* force low_latency on so that our tty_push actually forces
- * the data through, otherwise it is scheduled, and with high
- * data rates (like with OHCI) data can get lost.
- */
- if (tty)
- tty->low_latency = 1;
-
priv = usb_get_serial_port_data(port);
spin_lock_irqsave(&priv->lock, flags);
priv->rdtodo = 0;
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index eae4740d448..e568710b263 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -656,10 +656,6 @@ static int cypress_open(struct tty_struct *tty,
priv->rx_flags = 0;
spin_unlock_irqrestore(&priv->lock, flags);
- /* setting to zero could cause data loss */
- if (tty)
- tty->low_latency = 1;
-
/* raise both lines and set termios */
spin_lock_irqsave(&priv->lock, flags);
priv->line_control = CONTROL_DTR | CONTROL_RTS;
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 8a69cce40b6..c709ec474a8 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -478,12 +478,6 @@ static void empeg_set_termios(struct tty_struct *tty,
termios->c_cflag
|= CS8; /* character size 8 bits */
- /*
- * Force low_latency on; otherwise the pushes are scheduled;
- * this is bad as it opens up the possibility of dropping bytes
- * on the floor. We don't want to drop bytes on the floor. :)
- */
- tty->low_latency = 1;
tty_encode_baud_rate(tty, 115200, 115200);
}
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index a26a0e2cdb4..586d30ff450 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -973,14 +973,6 @@ static int garmin_open(struct tty_struct *tty,
dbg("%s - port %d", __func__, port->number);
- /*
- * Force low_latency on so that our tty_push actually forces the data
- * through, otherwise it is scheduled, and with high data rates (like
- * with OHCI) data can get lost.
- */
- if (tty)
- tty->low_latency = 1;
-
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->mode = initial_mode;
garmin_data_p->count = 0;
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 9d57cace373..4cec9906ccf 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -122,12 +122,6 @@ int usb_serial_generic_open(struct tty_struct *tty,
dbg("%s - port %d", __func__, port->number);
- /* force low_latency on so that our tty_push actually forces the data
- through, otherwise it is scheduled, and with high data rates (like
- with OHCI) data can get lost. */
- if (tty)
- tty->low_latency = 1;
-
/* clear the throttle flags */
spin_lock_irqsave(&port->lock, flags);
port->throttled = 0;
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index e85c8c0d1ad..fb4a73d090f 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -193,8 +193,6 @@ static const struct divisor_table_entry divisor_table[] = {
/* local variables */
static int debug;
-static int low_latency = 1; /* tty low latency flag, on by default */
-
static atomic_t CmdUrbs; /* Number of outstanding Command Write Urbs */
@@ -867,9 +865,6 @@ static int edge_open(struct tty_struct *tty,
if (edge_port == NULL)
return -ENODEV;
- if (tty)
- tty->low_latency = low_latency;
-
/* see if we've set up our endpoint info yet (can't set it up
in edge_startup as the structures were not set up at that time.) */
serial = port->serial;
@@ -3299,6 +3294,3 @@ MODULE_FIRMWARE("edgeport/down2.fw");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
-
-module_param(low_latency, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(low_latency, "Low latency enabled or not");
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index c3cdd00ddc4..513b25e044c 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -76,7 +76,6 @@ struct edgeport_uart_buf_desc {
#define EDGE_READ_URB_STOPPING 1
#define EDGE_READ_URB_STOPPED 2
-#define EDGE_LOW_LATENCY 1
#define EDGE_CLOSING_WAIT 4000 /* in .01 sec */
#define EDGE_OUT_BUF_SIZE 1024
@@ -232,7 +231,6 @@ static unsigned short OperationalBuildNumber;
static int debug;
-static int low_latency = EDGE_LOW_LATENCY;
static int closing_wait = EDGE_CLOSING_WAIT;
static int ignore_cpu_rev;
static int default_uart_mode; /* RS232 */
@@ -1850,9 +1848,6 @@ static int edge_open(struct tty_struct *tty,
if (edge_port == NULL)
return -ENODEV;
- if (tty)
- tty->low_latency = low_latency;
-
port_number = port->number - port->serial->minor;
switch (port_number) {
case 0:
@@ -3008,9 +3003,6 @@ MODULE_FIRMWARE("edgeport/down3.bin");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
-module_param(low_latency, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(low_latency, "Low latency enabled or not");
-
module_param(closing_wait, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(closing_wait, "Maximum wait for data to drain, in .01 secs");
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index ef92095b073..cd62825a9ac 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -631,13 +631,7 @@ static int ipaq_open(struct tty_struct *tty,
priv->free_len += PACKET_SIZE;
}
- /*
- * Force low latency on. This will immediately push data to the line
- * discipline instead of queueing.
- */
-
if (tty) {
- tty->low_latency = 1;
/* FIXME: These two are bogus */
tty->raw = 1;
tty->real_raw = 1;
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index f530032ed93..da2a2b46644 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -207,9 +207,6 @@ static int ipw_open(struct tty_struct *tty,
if (!buf_flow_init)
return -ENOMEM;
- if (tty)
- tty->low_latency = 1;
-
/* --1: Tell the modem to initialize (we think) From sniffs this is
* always the first thing that gets sent to the modem during
* opening of the device */
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index 2314c6ae4fc..4473d442b2a 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -1051,7 +1051,6 @@ static int iuu_open(struct tty_struct *tty,
tty->termios->c_oflag = 0;
tty->termios->c_iflag = 0;
priv->termios_initialized = 1;
- tty->low_latency = 1;
priv->poll = 0;
}
spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 6286baad939..c148544953b 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -231,13 +231,7 @@ static int kobil_open(struct tty_struct *tty,
/* someone sets the dev to 0 if the close method has been called */
port->interrupt_in_urb->dev = port->serial->dev;
-
- /* force low_latency on so that our tty_push actually forces
- * the data through, otherwise it is scheduled, and with high
- * data rates (like with OHCI) data can get lost.
- */
if (tty) {
- tty->low_latency = 1;
/* Default to echo off and other sane device settings */
tty->termios->c_lflag = 0;
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index e772cc0a97f..24e3b5d4b4d 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -446,13 +446,6 @@ static int mos7720_open(struct tty_struct *tty,
data = 0x0c;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
- /* force low_latency on so that our tty_push actually forces *
- * the data through,otherwise it is scheduled, and with *
- * high data rates (like with OHCI) data can get lost. */
-
- if (tty)
- tty->low_latency = 1;
-
/* see if we've set up our endpoint info yet *
* (can't set it up in mos7720_startup as the *
* structures were not set up at that time.) */
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 2c20e88a91b..84fb1dcd30d 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -38,7 +38,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "1.3.1"
+#define DRIVER_VERSION "1.3.2"
#define DRIVER_DESC "Moschip 7840/7820 USB Serial Driver"
/*
@@ -123,6 +123,11 @@
#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44
#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42
+/* This driver also supports the ATEN UC2324 device since it is mos7840 based
+ * - if I knew the device id it would also support the ATEN UC2322 */
+#define USB_VENDOR_ID_ATENINTL 0x0557
+#define ATENINTL_DEVICE_ID_UC2324 0x2011
+
/* Interrupt Routine Defines */
#define SERIAL_IIR_RLS 0x06
@@ -170,6 +175,7 @@ static struct usb_device_id moschip_port_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
+ {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
{} /* terminating entry */
};
@@ -178,6 +184,7 @@ static __devinitdata struct usb_device_id moschip_id_table_combined[] = {
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
+ {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
{} /* terminating entry */
};
@@ -1000,12 +1007,6 @@ static int mos7840_open(struct tty_struct *tty,
status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset,
Data);
- /* force low_latency on so that our tty_push actually forces *
- * the data through,otherwise it is scheduled, and with *
- * high data rates (like with OHCI) data can get lost. */
- if (tty)
- tty->low_latency = 1;
-
/* Check to see if we've set up our endpoint info yet *
* (can't set it up in mos7840_startup as the structures *
* were not set up at that time.) */
@@ -2477,9 +2478,14 @@ static int mos7840_startup(struct usb_serial *serial)
mos7840_set_port_private(serial->port[i], mos7840_port);
spin_lock_init(&mos7840_port->pool_lock);
- mos7840_port->port_num = ((serial->port[i]->number -
- (serial->port[i]->serial->minor)) +
- 1);
+ /* minor is not initialised until later by
+ * usb-serial.c:get_free_serial() and cannot therefore be used
+ * to index device instances */
+ mos7840_port->port_num = i + 1;
+ dbg ("serial->port[i]->number = %d", serial->port[i]->number);
+ dbg ("serial->port[i]->serial->minor = %d", serial->port[i]->serial->minor);
+ dbg ("mos7840_port->port_num = %d", mos7840_port->port_num);
+ dbg ("serial->minor = %d", serial->minor);
if (mos7840_port->port_num == 1) {
mos7840_port->SpRegOffset = 0x0;
@@ -2690,13 +2696,16 @@ static void mos7840_shutdown(struct usb_serial *serial)
for (i = 0; i < serial->num_ports; ++i) {
mos7840_port = mos7840_get_port_private(serial->port[i]);
- spin_lock_irqsave(&mos7840_port->pool_lock, flags);
- mos7840_port->zombie = 1;
- spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
- usb_kill_urb(mos7840_port->control_urb);
- kfree(mos7840_port->ctrl_buf);
- kfree(mos7840_port->dr);
- kfree(mos7840_port);
+ dbg ("mos7840_port %d = %p", i, mos7840_port);
+ if (mos7840_port) {
+ spin_lock_irqsave(&mos7840_port->pool_lock, flags);
+ mos7840_port->zombie = 1;
+ spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
+ usb_kill_urb(mos7840_port->control_urb);
+ kfree(mos7840_port->ctrl_buf);
+ kfree(mos7840_port->dr);
+ kfree(mos7840_port);
+ }
mos7840_set_port_private(serial->port[i], NULL);
}
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 839583dc8b6..b500ad10b75 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -159,14 +159,6 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port,
priv->port = port;
spin_unlock_irqrestore(&priv->lock, flags);
- /*
- * Force low_latency on so that our tty_push actually forces the data
- * through, otherwise it is scheduled, and with high data rates (like
- * with OHCI) data can get lost.
- */
- if (tty)
- tty->low_latency = 1;
-
/* Start reading from the device */
usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev,
usb_rcvbulkpipe(priv->udev,
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 47bd070f24b..7817b82889c 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -936,9 +936,6 @@ static int option_open(struct tty_struct *tty,
usb_pipeout(urb->pipe), 0); */
}
- if (tty)
- tty->low_latency = 1;
-
option_send_setup(tty, port);
return 0;
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index d9bf9a5c20e..913225c6161 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -14,7 +14,7 @@
Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
*/
-#define DRIVER_VERSION "v.1.3.2"
+#define DRIVER_VERSION "v.1.3.3"
#define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>"
#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
@@ -259,9 +259,21 @@ static int sierra_send_setup(struct tty_struct *tty,
val |= 0x02;
/* If composite device then properly report interface */
- if (serial->num_ports == 1)
+ if (serial->num_ports == 1) {
interface = sierra_calc_interface(serial);
+ /* Control message is sent only to interfaces with
+ * interrupt_in endpoints
+ */
+ if (port->interrupt_in_urb) {
+ /* send control message */
+ return usb_control_msg(serial->dev,
+ usb_rcvctrlpipe(serial->dev, 0),
+ 0x22, 0x21, val, interface,
+ NULL, 0, USB_CTRL_SET_TIMEOUT);
+ }
+ }
+
/* Otherwise the need to do non-composite mapping */
else {
if (port->bulk_out_endpointAddress == 2)
@@ -270,12 +282,13 @@ static int sierra_send_setup(struct tty_struct *tty,
interface = 1;
else if (port->bulk_out_endpointAddress == 5)
interface = 2;
- }
- return usb_control_msg(serial->dev,
+ return usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
0x22, 0x21, val, interface,
NULL, 0, USB_CTRL_SET_TIMEOUT);
+
+ }
}
return 0;
@@ -585,9 +598,6 @@ static int sierra_open(struct tty_struct *tty,
}
}
- if (tty)
- tty->low_latency = 1;
-
sierra_send_setup(tty, port);
/* start up the interrupt endpoint if we have one */
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 9c4c700c7cc..0a64bac306e 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -50,11 +50,10 @@
#define TI_TRANSFER_TIMEOUT 2
-#define TI_DEFAULT_LOW_LATENCY 0
#define TI_DEFAULT_CLOSING_WAIT 4000 /* in .01 secs */
/* supported setserial flags */
-#define TI_SET_SERIAL_FLAGS (ASYNC_LOW_LATENCY)
+#define TI_SET_SERIAL_FLAGS 0
/* read urb states */
#define TI_READ_URB_RUNNING 0
@@ -161,7 +160,6 @@ static int ti_buf_get(struct circ_buf *cb, char *buf, int count);
/* module parameters */
static int debug;
-static int low_latency = TI_DEFAULT_LOW_LATENCY;
static int closing_wait = TI_DEFAULT_CLOSING_WAIT;
static ushort vendor_3410[TI_EXTRA_VID_PID_COUNT];
static unsigned int vendor_3410_count;
@@ -296,10 +294,6 @@ MODULE_FIRMWARE("mts_edge.fw");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes");
-module_param(low_latency, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(low_latency,
- "TTY low_latency flag, 0=off, 1=on, default is off");
-
module_param(closing_wait, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(closing_wait,
"Maximum wait for data to drain in close, in .01 secs, default is 4000");
@@ -448,7 +442,6 @@ static int ti_startup(struct usb_serial *serial)
spin_lock_init(&tport->tp_lock);
tport->tp_uart_base_addr = (i == 0 ?
TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
- tport->tp_flags = low_latency ? ASYNC_LOW_LATENCY : 0;
tport->tp_closing_wait = closing_wait;
init_waitqueue_head(&tport->tp_msr_wait);
init_waitqueue_head(&tport->tp_write_wait);
@@ -528,10 +521,6 @@ static int ti_open(struct tty_struct *tty,
if (mutex_lock_interruptible(&tdev->td_open_close_lock))
return -ERESTARTSYS;
- if (tty)
- tty->low_latency =
- (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
-
port_number = port->number - port->serial->minor;
memset(&(tport->tp_icount), 0x00, sizeof(tport->tp_icount));
@@ -1454,7 +1443,6 @@ static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport,
return -EFAULT;
tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS;
- tty->low_latency = (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
tport->tp_closing_wait = new_serial.closing_wait;
return 0;
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 2a70563bbee..0a566eea49c 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -137,22 +137,10 @@ static void destroy_serial(struct kref *kref)
dbg("%s - %s", __func__, serial->type->description);
- serial->type->shutdown(serial);
-
/* return the minor range that this device had */
if (serial->minor != SERIAL_TTY_NO_MINOR)
return_serial(serial);
- for (i = 0; i < serial->num_ports; ++i)
- serial->port[i]->port.count = 0;
-
- /* the ports are cleaned up and released in port_release() */
- for (i = 0; i < serial->num_ports; ++i)
- if (serial->port[i]->dev.parent != NULL) {
- device_unregister(&serial->port[i]->dev);
- serial->port[i] = NULL;
- }
-
/* If this is a "fake" port, we have to clean it up here, as it will
* not get cleaned up in port_release() as it was never registered with
* the driver core */
@@ -187,7 +175,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
struct usb_serial *serial;
struct usb_serial_port *port;
unsigned int portNumber;
- int retval;
+ int retval = 0;
dbg("%s", __func__);
@@ -198,21 +186,24 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
return -ENODEV;
}
+ mutex_lock(&serial->disc_mutex);
portNumber = tty->index - serial->minor;
port = serial->port[portNumber];
- if (!port) {
- retval = -ENODEV;
- goto bailout_kref_put;
- }
-
- if (port->serial->disconnected) {
+ if (!port || serial->disconnected)
retval = -ENODEV;
- goto bailout_kref_put;
- }
+ else
+ get_device(&port->dev);
+ /*
+ * Note: Our locking order requirement does not allow port->mutex
+ * to be acquired while serial->disc_mutex is held.
+ */
+ mutex_unlock(&serial->disc_mutex);
+ if (retval)
+ goto bailout_serial_put;
if (mutex_lock_interruptible(&port->mutex)) {
retval = -ERESTARTSYS;
- goto bailout_kref_put;
+ goto bailout_port_put;
}
++port->port.count;
@@ -232,14 +223,20 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
goto bailout_mutex_unlock;
}
- retval = usb_autopm_get_interface(serial->interface);
+ mutex_lock(&serial->disc_mutex);
+ if (serial->disconnected)
+ retval = -ENODEV;
+ else
+ retval = usb_autopm_get_interface(serial->interface);
if (retval)
goto bailout_module_put;
+
/* only call the device specific open if this
* is the first time the port is opened */
retval = serial->type->open(tty, port, filp);
if (retval)
goto bailout_interface_put;
+ mutex_unlock(&serial->disc_mutex);
}
mutex_unlock(&port->mutex);
@@ -248,13 +245,16 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
bailout_interface_put:
usb_autopm_put_interface(serial->interface);
bailout_module_put:
+ mutex_unlock(&serial->disc_mutex);
module_put(serial->type->driver.owner);
bailout_mutex_unlock:
port->port.count = 0;
tty->driver_data = NULL;
tty_port_tty_set(&port->port, NULL);
mutex_unlock(&port->mutex);
-bailout_kref_put:
+bailout_port_put:
+ put_device(&port->dev);
+bailout_serial_put:
usb_serial_put(serial);
return retval;
}
@@ -262,6 +262,9 @@ bailout_kref_put:
static void serial_close(struct tty_struct *tty, struct file *filp)
{
struct usb_serial_port *port = tty->driver_data;
+ struct usb_serial *serial;
+ struct module *owner;
+ int count;
if (!port)
return;
@@ -269,6 +272,8 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
dbg("%s - port %d", __func__, port->number);
mutex_lock(&port->mutex);
+ serial = port->serial;
+ owner = serial->type->driver.owner;
if (port->port.count == 0) {
mutex_unlock(&port->mutex);
@@ -281,7 +286,7 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
* this before we drop the port count. The call is protected
* by the port mutex
*/
- port->serial->type->close(tty, port, filp);
+ serial->type->close(tty, port, filp);
if (port->port.count == (port->console ? 2 : 1)) {
struct tty_struct *tty = tty_port_tty_get(&port->port);
@@ -295,17 +300,23 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
}
}
- if (port->port.count == 1) {
- mutex_lock(&port->serial->disc_mutex);
- if (!port->serial->disconnected)
- usb_autopm_put_interface(port->serial->interface);
- mutex_unlock(&port->serial->disc_mutex);
- module_put(port->serial->type->driver.owner);
- }
--port->port.count;
-
+ count = port->port.count;
mutex_unlock(&port->mutex);
- usb_serial_put(port->serial);
+ put_device(&port->dev);
+
+ /* Mustn't dereference port any more */
+ if (count == 0) {
+ mutex_lock(&serial->disc_mutex);
+ if (!serial->disconnected)
+ usb_autopm_put_interface(serial->interface);
+ mutex_unlock(&serial->disc_mutex);
+ }
+ usb_serial_put(serial);
+
+ /* Mustn't dereference serial any more */
+ if (count == 0)
+ module_put(owner);
}
static int serial_write(struct tty_struct *tty, const unsigned char *buf,
@@ -549,7 +560,13 @@ static void kill_traffic(struct usb_serial_port *port)
static void port_free(struct usb_serial_port *port)
{
+ /*
+ * Stop all the traffic before cancelling the work, so that
+ * nobody will restart it by calling usb_serial_port_softint.
+ */
kill_traffic(port);
+ cancel_work_sync(&port->work);
+
usb_free_urb(port->read_urb);
usb_free_urb(port->write_urb);
usb_free_urb(port->interrupt_in_urb);
@@ -558,7 +575,6 @@ static void port_free(struct usb_serial_port *port)
kfree(port->bulk_out_buffer);
kfree(port->interrupt_in_buffer);
kfree(port->interrupt_out_buffer);
- flush_scheduled_work(); /* port->work */
kfree(port);
}
@@ -1043,6 +1059,12 @@ void usb_serial_disconnect(struct usb_interface *interface)
usb_set_intfdata(interface, NULL);
/* must set a flag, to signal subdrivers */
serial->disconnected = 1;
+ mutex_unlock(&serial->disc_mutex);
+
+ /* Unfortunately, many of the sub-drivers expect the port structures
+ * to exist when their shutdown method is called, so we have to go
+ * through this awkward two-step unregistration procedure.
+ */
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
if (port) {
@@ -1052,11 +1074,21 @@ void usb_serial_disconnect(struct usb_interface *interface)
tty_kref_put(tty);
}
kill_traffic(port);
+ cancel_work_sync(&port->work);
+ device_del(&port->dev);
+ }
+ }
+ serial->type->shutdown(serial);
+ for (i = 0; i < serial->num_ports; ++i) {
+ port = serial->port[i];
+ if (port) {
+ put_device(&port->dev);
+ serial->port[i] = NULL;
}
}
+
/* let the last holder of this object
* cause it to be cleaned up */
- mutex_unlock(&serial->disc_mutex);
usb_serial_put(serial);
dev_info(dev, "device disconnected\n");
}
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 4facce3d936..5ac414bda71 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -296,14 +296,6 @@ static int visor_open(struct tty_struct *tty, struct usb_serial_port *port,
priv->throttled = 0;
spin_unlock_irqrestore(&priv->lock, flags);
- /*
- * Force low_latency on so that our tty_push actually forces the data
- * through, otherwise it is scheduled, and with high data rates (like
- * with OHCI) data can get lost.
- */
- if (tty)
- tty->low_latency = 1;
-
/* Start reading from the device */
usb_fill_bulk_urb(port->read_urb, serial->dev,
usb_rcvbulkpipe(serial->dev,
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 96db479d116..fa65a3b0860 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1851,6 +1851,12 @@ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_CAPACITY_HEURISTICS),
+/* Reported by Alessio Treglia <quadrispro@ubuntu.com> */
+UNUSUAL_DEV( 0xed10, 0x7636, 0x0001, 0x0001,
+ "TGE",
+ "Digital MP3 Audio Player",
+ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ),
+
/* Control/Bulk transport for all SubClass values */
USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR),
diff --git a/drivers/watchdog/orion5x_wdt.c b/drivers/watchdog/orion5x_wdt.c
index 7529616739d..2cde568e4fb 100644
--- a/drivers/watchdog/orion5x_wdt.c
+++ b/drivers/watchdog/orion5x_wdt.c
@@ -22,6 +22,7 @@
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/spinlock.h>
+#include <mach/bridge-regs.h>
#include <plat/orion5x_wdt.h>
/*