aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig26
-rw-r--r--drivers/acpi/asus_acpi.c2
-rw-r--r--drivers/acpi/battery.c11
-rw-r--r--drivers/acpi/bus.c2
-rw-r--r--drivers/acpi/button.c1
-rw-r--r--drivers/acpi/dock.c1
-rw-r--r--drivers/acpi/ec.c6
-rw-r--r--drivers/acpi/osl.c86
-rw-r--r--drivers/acpi/pci_irq.c98
-rw-r--r--drivers/acpi/pci_root.c2
-rw-r--r--drivers/acpi/processor_core.c25
-rw-r--r--drivers/acpi/processor_idle.c12
-rw-r--r--drivers/acpi/scan.c5
-rw-r--r--drivers/acpi/sleep/main.c2
-rw-r--r--drivers/acpi/system.c2
-rw-r--r--drivers/acpi/thermal.c12
-rw-r--r--drivers/acpi/toshiba_acpi.c7
-rw-r--r--drivers/acpi/utilities/utdebug.c2
-rw-r--r--drivers/acpi/utilities/utobject.c2
-rw-r--r--drivers/acpi/utils.c6
-rw-r--r--drivers/acpi/video.c64
-rw-r--r--drivers/acpi/wmi.c10
-rw-r--r--drivers/ata/Kconfig1
-rw-r--r--drivers/ata/ahci.c72
-rw-r--r--drivers/ata/libata-acpi.c96
-rw-r--r--drivers/ata/pata_ali.c2
-rw-r--r--drivers/atm/firestream.c4
-rw-r--r--drivers/atm/fore200e.c4
-rw-r--r--drivers/atm/idt77252.c12
-rw-r--r--drivers/block/Kconfig10
-rw-r--r--drivers/block/Makefile1
-rw-r--r--drivers/block/floppy.c5
-rw-r--r--drivers/block/ps2esdi.c1079
-rw-r--r--drivers/block/viodasd.c3
-rw-r--r--drivers/block/virtio_blk.c1
-rw-r--r--drivers/bluetooth/hci_usb.c3
-rw-r--r--drivers/char/drm/ati_pcigart.c91
-rw-r--r--drivers/char/drm/drmP.h3
-rw-r--r--drivers/char/drm/drm_fops.c7
-rw-r--r--drivers/char/drm/drm_lock.c35
-rw-r--r--drivers/char/drm/drm_pciids.h7
-rw-r--r--drivers/char/drm/r128_cce.c1
-rw-r--r--drivers/char/drm/radeon_cp.c1
-rw-r--r--drivers/char/drm/via_dma.c59
-rw-r--r--drivers/char/drm/via_dmablit.c2
-rw-r--r--drivers/char/riscom8.c2
-rw-r--r--drivers/char/rocket.c37
-rw-r--r--drivers/char/rocket_int.h83
-rw-r--r--drivers/dma/dmaengine.c2
-rw-r--r--drivers/dma/fsldma.c88
-rw-r--r--drivers/dma/fsldma.h1
-rw-r--r--drivers/dma/iop-adma.c32
-rw-r--r--drivers/firewire/Kconfig50
-rw-r--r--drivers/firewire/fw-ohci.c108
-rw-r--r--drivers/firewire/fw-sbp2.c36
-rw-r--r--drivers/firewire/fw-topology.c3
-rw-r--r--drivers/firewire/fw-transaction.c8
-rw-r--r--drivers/firewire/fw-transaction.h6
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-input.c22
-rw-r--r--drivers/hid/usbhid/hid-core.c2
-rw-r--r--drivers/hid/usbhid/hid-quirks.c6
-rw-r--r--drivers/hwmon/Kconfig5
-rw-r--r--drivers/hwmon/ibmpex.c13
-rw-r--r--drivers/i2c/busses/i2c-amd756.c2
-rw-r--r--drivers/i2c/chips/Makefile7
-rw-r--r--drivers/i2c/i2c-core.c6
-rw-r--r--drivers/ide/ide-taskfile.c36
-rw-r--r--drivers/ieee1394/sbp2.c5
-rw-r--r--drivers/infiniband/core/cm.c3
-rw-r--r--drivers/infiniband/core/fmr_pool.c38
-rw-r--r--drivers/infiniband/core/iwcm.c5
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.c5
-rw-r--r--drivers/infiniband/hw/ipath/ipath_common.h2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c28
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mad.c7
-rw-r--r--drivers/infiniband/hw/ipath/ipath_qp.c13
-rw-r--r--drivers/infiniband/hw/ipath/ipath_rc.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_registers.h2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c9
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c9
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c2
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c47
-rw-r--r--drivers/input/misc/cobalt_btns.c16
-rw-r--r--drivers/input/mouse/alps.c5
-rw-r--r--drivers/input/serio/i8042-snirm.h75
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h7
-rw-r--r--drivers/input/serio/i8042.c3
-rw-r--r--drivers/input/serio/i8042.h2
-rw-r--r--drivers/input/tablet/wacom.h6
-rw-r--r--drivers/input/tablet/wacom_sys.c6
-rw-r--r--drivers/input/tablet/wacom_wac.c31
-rw-r--r--drivers/input/tablet/wacom_wac.h1
-rw-r--r--drivers/input/touchscreen/ads7846.c2
-rw-r--r--drivers/isdn/i4l/isdn_common.c4
-rw-r--r--drivers/isdn/i4l/isdn_v110.c2
-rw-r--r--drivers/macintosh/via-pmu-backlight.c5
-rw-r--r--drivers/macintosh/via-pmu.c2
-rw-r--r--drivers/md/md.c12
-rw-r--r--drivers/md/raid5.c6
-rw-r--r--drivers/media/dvb/dvb-usb/opera1.c2
-rw-r--r--drivers/media/video/Kconfig4
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c1
-rw-r--r--drivers/media/video/cx88/cx88-cards.c5
-rw-r--r--drivers/media/video/cx88/cx88-video.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c7
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.c8
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c41
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c5
-rw-r--r--drivers/media/video/tvp5150.c4
-rw-r--r--drivers/media/video/usbvideo/usbvideo.c9
-rw-r--r--drivers/media/video/v4l1-compat.c50
-rw-r--r--drivers/memstick/core/memstick.c9
-rw-r--r--drivers/memstick/core/mspro_block.c94
-rw-r--r--drivers/memstick/host/jmb38x_ms.c113
-rw-r--r--drivers/memstick/host/tifm_ms.c17
-rw-r--r--drivers/message/fusion/mptbase.c276
-rw-r--r--drivers/message/fusion/mptscsih.c11
-rw-r--r--drivers/misc/Kconfig1
-rw-r--r--drivers/misc/acer-wmi.c44
-rw-r--r--drivers/misc/sony-laptop.c2
-rw-r--r--drivers/mmc/host/tifm_sd.c2
-rw-r--r--drivers/net/Kconfig20
-rw-r--r--drivers/net/ac3200.c7
-rw-r--r--drivers/net/apne.c7
-rw-r--r--drivers/net/appletalk/ltpc.c3
-rw-r--r--drivers/net/arcnet/capmode.c6
-rw-r--r--drivers/net/atarilance.c5
-rw-r--r--drivers/net/e100.c29
-rw-r--r--drivers/net/enc28j60.c3
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c2
-rw-r--r--drivers/net/mv643xx_eth.c1
-rw-r--r--drivers/net/pcmcia/axnet_cs.c2
-rw-r--r--drivers/net/phy/Kconfig1
-rw-r--r--drivers/net/phy/davicom.c17
-rw-r--r--drivers/net/pppol2tp.c69
-rw-r--r--drivers/net/s2io.c2
-rw-r--r--drivers/net/tulip/de2104x.c3
-rw-r--r--drivers/net/virtio_net.c22
-rw-r--r--drivers/net/wan/sbni.c2
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c5
-rw-r--r--drivers/parisc/pdc_stable.c6
-rw-r--r--drivers/parisc/sba_iommu.c4
-rw-r--r--drivers/pci/bus.c6
-rw-r--r--drivers/pci/hotplug/pciehp_core.c2
-rw-r--r--drivers/pci/pci-acpi.c24
-rw-r--r--drivers/pnp/quirks.c100
-rw-r--r--drivers/rtc/Kconfig2
-rw-r--r--drivers/rtc/rtc-at91sam9.c6
-rw-r--r--drivers/scsi/Kconfig2
-rw-r--r--drivers/scsi/a100u2w.c9
-rw-r--r--drivers/scsi/advansys.c2
-rw-r--r--drivers/scsi/arcmsr/arcmsr.h14
-rw-r--r--drivers/scsi/gdth.c7
-rw-r--r--drivers/scsi/scsi_lib.c5
-rw-r--r--drivers/scsi/scsi_sysfs.c2
-rw-r--r--drivers/scsi/sd.c1
-rw-r--r--drivers/scsi/sr.c1
-rw-r--r--drivers/spi/au1550_spi.c4
-rw-r--r--drivers/spi/spi_bitbang.c8
-rw-r--r--drivers/thermal/Kconfig1
-rw-r--r--drivers/usb/storage/isd200.c5
-rw-r--r--drivers/video/Kconfig14
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/fb_defio.c22
-rw-r--r--drivers/video/i810/i810_main.c2
-rw-r--r--drivers/video/metronomefb.c999
-rw-r--r--drivers/virtio/virtio_balloon.c4
-rw-r--r--drivers/virtio/virtio_pci.c15
-rw-r--r--drivers/virtio/virtio_ring.c1
174 files changed, 2748 insertions, 2247 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index f688c214be0..b4f5e854282 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -283,34 +283,22 @@ config ACPI_TOSHIBA
If you have a legacy free Toshiba laptop (such as the Libretto L1
series), say Y.
-config ACPI_CUSTOM_DSDT
- bool "Include Custom DSDT"
+config ACPI_CUSTOM_DSDT_FILE
+ string "Custom DSDT Table file to include"
+ default ""
depends on !STANDALONE
- default n
help
This option supports a custom DSDT by linking it into the kernel.
See Documentation/acpi/dsdt-override.txt
- If unsure, say N.
-
-config ACPI_CUSTOM_DSDT_FILE
- string "Custom DSDT Table file to include"
- depends on ACPI_CUSTOM_DSDT
- default ""
- help
Enter the full path name to the file which includes the AmlCode
declaration.
-config ACPI_CUSTOM_DSDT_INITRD
- bool "Read Custom DSDT from initramfs"
- depends on BLK_DEV_INITRD
- default n
- help
- This option supports a custom DSDT by optionally loading it from initrd.
- See Documentation/acpi/dsdt-override.txt
+ If unsure, don't enter a file name.
- If you are not using this feature now, but may use it later,
- it is safe to say Y here.
+config ACPI_CUSTOM_DSDT
+ bool
+ default ACPI_CUSTOM_DSDT_FILE != ""
config ACPI_BLACKLIST_YEAR
int "Disable ACPI for systems before Jan 1st this year" if X86_32
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index d25ef961415..44ad90c03c2 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -610,7 +610,7 @@ write_led(const char __user * buffer, unsigned long count,
(led_out) ? (hotk->status | ledmask) : (hotk->status & ~ledmask);
if (invert) /* invert target value */
- led_out = !led_out & 0x1;
+ led_out = !led_out;
if (!write_acpi_int(hotk->handle, ledname, led_out, NULL))
printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n",
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index f6215e80980..d5729d5dc19 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -293,13 +293,12 @@ static int extract_package(struct acpi_battery *battery,
strncpy(ptr, (u8 *)&element->integer.value,
sizeof(acpi_integer));
ptr[sizeof(acpi_integer)] = 0;
- } else return -EFAULT;
+ } else
+ *ptr = 0; /* don't have value */
} else {
- if (element->type == ACPI_TYPE_INTEGER) {
- int *x = (int *)((u8 *)battery +
- offsets[i].offset);
- *x = element->integer.value;
- } else return -EFAULT;
+ int *x = (int *)((u8 *)battery + offsets[i].offset);
+ *x = (element->type == ACPI_TYPE_INTEGER) ?
+ element->integer.value : -1;
}
}
return 0;
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index ce3c0a2cbac..5b6760e0f95 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -776,7 +776,7 @@ static int __init acpi_init(void)
acpi_kobj = kobject_create_and_add("acpi", firmware_kobj);
if (!acpi_kobj) {
- printk(KERN_WARNING "%s: kset create error\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: kset create error\n", __func__);
acpi_kobj = NULL;
}
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 24a7865a57c..6c5da83cdb6 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -449,6 +449,7 @@ static int acpi_button_add(struct acpi_device *device)
input->phys = button->phys;
input->id.bustype = BUS_HOST;
input->id.product = button->type;
+ input->dev.parent = &device->dev;
switch (button->type) {
case ACPI_BUTTON_TYPE_POWER:
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 307cef65c24..fa44fb96fc3 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -710,6 +710,7 @@ static ssize_t write_undock(struct device *dev, struct device_attribute *attr,
if (!count)
return -EINVAL;
+ begin_undock(dock_station);
ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST);
return ret ? ret: count;
}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index caf873c14bf..7222a18a031 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -943,11 +943,7 @@ int __init acpi_ec_ecdt_probe(void)
boot_ec->command_addr = ecdt_ptr->control.address;
boot_ec->data_addr = ecdt_ptr->data.address;
boot_ec->gpe = ecdt_ptr->gpe;
- if (ACPI_FAILURE(acpi_get_handle(NULL, ecdt_ptr->id,
- &boot_ec->handle))) {
- pr_info("Failed to locate handle for boot EC\n");
- boot_ec->handle = ACPI_ROOT_OBJECT;
- }
+ boot_ec->handle = ACPI_ROOT_OBJECT;
} else {
/* This workaround is needed only on some broken machines,
* which require early EC, but fail to provide ECDT */
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 8edba7b678e..a697fb6cf05 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -91,10 +91,6 @@ static DEFINE_SPINLOCK(acpi_res_lock);
#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
static char osi_additional_string[OSI_STRING_LENGTH_MAX];
-#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
-static int acpi_no_initrd_override;
-#endif
-
/*
* "Ode to _OSI(Linux)"
*
@@ -324,67 +320,6 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
return AE_OK;
}
-#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
-static struct acpi_table_header *acpi_find_dsdt_initrd(void)
-{
- struct file *firmware_file;
- mm_segment_t oldfs;
- unsigned long len, len2;
- struct acpi_table_header *dsdt_buffer, *ret = NULL;
- struct kstat stat;
- char *ramfs_dsdt_name = "/DSDT.aml";
-
- printk(KERN_INFO PREFIX "Checking initramfs for custom DSDT\n");
-
- /*
- * Never do this at home, only the user-space is allowed to open a file.
- * The clean way would be to use the firmware loader.
- * But this code must be run before there is any userspace available.
- * A static/init firmware infrastructure doesn't exist yet...
- */
- if (vfs_stat(ramfs_dsdt_name, &stat) < 0)
- return ret;
-
- len = stat.size;
- /* check especially against empty files */
- if (len <= 4) {
- printk(KERN_ERR PREFIX "Failed: DSDT only %lu bytes.\n", len);
- return ret;
- }
-
- firmware_file = filp_open(ramfs_dsdt_name, O_RDONLY, 0);
- if (IS_ERR(firmware_file)) {
- printk(KERN_ERR PREFIX "Failed to open %s.\n", ramfs_dsdt_name);
- return ret;
- }
-
- dsdt_buffer = kmalloc(len, GFP_ATOMIC);
- if (!dsdt_buffer) {
- printk(KERN_ERR PREFIX "Failed to allocate %lu bytes.\n", len);
- goto err;
- }
-
- oldfs = get_fs();
- set_fs(KERNEL_DS);
- len2 = vfs_read(firmware_file, (char __user *)dsdt_buffer, len,
- &firmware_file->f_pos);
- set_fs(oldfs);
- if (len2 < len) {
- printk(KERN_ERR PREFIX "Failed to read %lu bytes from %s.\n",
- len, ramfs_dsdt_name);
- ACPI_FREE(dsdt_buffer);
- goto err;
- }
-
- printk(KERN_INFO PREFIX "Found %lu byte DSDT in %s.\n",
- len, ramfs_dsdt_name);
- ret = dsdt_buffer;
-err:
- filp_close(firmware_file, NULL);
- return ret;
-}
-#endif
-
acpi_status
acpi_os_table_override(struct acpi_table_header * existing_table,
struct acpi_table_header ** new_table)
@@ -398,16 +333,6 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
if (strncmp(existing_table->signature, "DSDT", 4) == 0)
*new_table = (struct acpi_table_header *)AmlCode;
#endif
-#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
- if ((strncmp(existing_table->signature, "DSDT", 4) == 0) &&
- !acpi_no_initrd_override) {
- struct acpi_table_header *initrd_table;
-
- initrd_table = acpi_find_dsdt_initrd();
- if (initrd_table)
- *new_table = initrd_table;
- }
-#endif
if (*new_table != NULL) {
printk(KERN_WARNING PREFIX "Override [%4.4s-%8.8s], "
"this is unsafe: tainting kernel\n",
@@ -418,15 +343,6 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
return AE_OK;
}
-#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
-static int __init acpi_no_initrd_override_setup(char *s)
-{
- acpi_no_initrd_override = 1;
- return 1;
-}
-__setup("acpi_no_initrd_override", acpi_no_initrd_override_setup);
-#endif
-
static irqreturn_t acpi_irq(int irq, void *dev_id)
{
u32 handled;
@@ -1237,7 +1153,7 @@ int acpi_check_resource_conflict(struct resource *res)
if (clash) {
if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
- printk(KERN_INFO "%sACPI: %s resource %s [0x%llx-0x%llx]"
+ printk("%sACPI: %s resource %s [0x%llx-0x%llx]"
" conflicts with ACPI region %s"
" [0x%llx-0x%llx]\n",
acpi_enforce_resources == ENFORCE_RESOURCES_LAX
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 7f19859580c..7af414a3c63 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -25,6 +25,7 @@
*/
+#include <linux/dmi.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -76,6 +77,101 @@ static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(int segment,
return NULL;
}
+/* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */
+static struct dmi_system_id medion_md9580[] = {
+ {
+ .ident = "Medion MD9580-F laptop",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "A555"),
+ },
+ },
+ { }
+};
+
+/* http://bugzilla.kernel.org/show_bug.cgi?id=5044 */
+static struct dmi_system_id dell_optiplex[] = {
+ {
+ .ident = "Dell Optiplex GX1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX1 600S+"),
+ },
+ },
+ { }
+};
+
+/* http://bugzilla.kernel.org/show_bug.cgi?id=10138 */
+static struct dmi_system_id hp_t5710[] = {
+ {
+ .ident = "HP t5710",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "hp t5000 series"),
+ DMI_MATCH(DMI_BOARD_NAME, "098Ch"),
+ },
+ },
+ { }
+};
+
+struct prt_quirk {
+ struct dmi_system_id *system;
+ unsigned int segment;
+ unsigned int bus;
+ unsigned int device;
+ unsigned char pin;
+ char *source; /* according to BIOS */
+ char *actual_source;
+};
+
+/*
+ * These systems have incorrect _PRT entries. The BIOS claims the PCI
+ * interrupt at the listed segment/bus/device/pin is connected to the first
+ * link device, but it is actually connected to the second.
+ */
+static struct prt_quirk prt_quirks[] = {
+ { medion_md9580, 0, 0, 9, 'A',
+ "\\_SB_.PCI0.ISA.LNKA",
+ "\\_SB_.PCI0.ISA.LNKB"},
+ { dell_optiplex, 0, 0, 0xd, 'A',
+ "\\_SB_.LNKB",
+ "\\_SB_.LNKA"},
+ { hp_t5710, 0, 0, 1, 'A',
+ "\\_SB_.PCI0.LNK1",
+ "\\_SB_.PCI0.LNK3"},
+};
+
+static void
+do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt)
+{
+ int i;
+ struct prt_quirk *quirk;
+
+ for (i = 0; i < ARRAY_SIZE(prt_quirks); i++) {
+ quirk = &prt_quirks[i];
+
+ /* All current quirks involve link devices, not GSIs */
+ if (!prt->source)
+ continue;
+
+ if (dmi_check_system(quirk->system) &&
+ entry->id.segment == quirk->segment &&
+ entry->id.bus == quirk->bus &&
+ entry->id.device == quirk->device &&
+ entry->pin + 'A' == quirk->pin &&
+ !strcmp(prt->source, quirk->source) &&
+ strlen(prt->source) >= strlen(quirk->actual_source)) {
+ printk(KERN_WARNING PREFIX "firmware reports "
+ "%04x:%02x:%02x[%c] connected to %s; "
+ "changing to %s\n",
+ entry->id.segment, entry->id.bus,
+ entry->id.device, 'A' + entry->pin,
+ prt->source, quirk->actual_source);
+ strcpy(prt->source, quirk->actual_source);
+ }
+ }
+}
+
static int
acpi_pci_irq_add_entry(acpi_handle handle,
int segment, int bus, struct acpi_pci_routing_table *prt)
@@ -96,6 +192,8 @@ acpi_pci_irq_add_entry(acpi_handle handle,
entry->id.function = prt->address & 0xFFFF;
entry->pin = prt->pin;
+ do_prt_fixups(entry, prt);
+
/*
* Type 1: Dynamic
* ---------------
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index f14ff1ffab2..c3fed31166b 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -184,7 +184,7 @@ static void acpi_pci_bridge_scan(struct acpi_device *device)
}
}
-static int acpi_pci_root_add(struct acpi_device *device)
+static int __devinit acpi_pci_root_add(struct acpi_device *device)
{
int result = 0;
struct acpi_pci_root *root = NULL;
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index a3cc8a98255..36a68fa114e 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -840,17 +840,19 @@ static int is_processor_present(acpi_handle handle)
status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
- /*
- * if a processor object does not have an _STA object,
- * OSPM assumes that the processor is present.
- */
- if (status == AE_NOT_FOUND)
- return 1;
if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
return 1;
- ACPI_EXCEPTION((AE_INFO, status, "Processor Device is not present"));
+ /*
+ * _STA is mandatory for a processor that supports hot plug
+ */
+ if (status == AE_NOT_FOUND)
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Processor does not support hot plug\n"));
+ else
+ ACPI_EXCEPTION((AE_INFO, status,
+ "Processor Device is not present"));
return 0;
}
@@ -886,8 +888,8 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
return 0;
}
-static void
-acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
+static void __ref acpi_processor_hotplug_notify(acpi_handle handle,
+ u32 event, void *data)
{
struct acpi_processor *pr;
struct acpi_device *device = NULL;
@@ -897,9 +899,10 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
switch (event) {
case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK:
- printk("Processor driver received %s event\n",
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Processor driver received %s event\n",
(event == ACPI_NOTIFY_BUS_CHECK) ?
- "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK");
+ "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"));
if (!is_processor_present(handle))
break;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 6f3b217699e..e8e2d886923 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -216,8 +216,10 @@ static void acpi_safe_halt(void)
* test NEED_RESCHED:
*/
smp_mb();
- if (!need_resched())
+ if (!need_resched()) {
safe_halt();
+ local_irq_disable();
+ }
current_thread_info()->status |= TS_POLLING;
}
@@ -421,7 +423,9 @@ static void acpi_processor_idle(void)
else
acpi_safe_halt();
- local_irq_enable();
+ if (irqs_disabled())
+ local_irq_enable();
+
return;
}
@@ -530,7 +534,9 @@ static void acpi_processor_idle(void)
* skew otherwise.
*/
sleep_ticks = 0xFFFFFFFF;
- local_irq_enable();
+ if (irqs_disabled())
+ local_irq_enable();
+
break;
case ACPI_STATE_C2:
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 3fac011f9cf..57570ac4780 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -609,7 +609,8 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer);
if (ACPI_SUCCESS(status)) {
obj = buffer.pointer;
- status = acpi_get_handle(NULL, obj->string.pointer, ejd);
+ status = acpi_get_handle(ACPI_ROOT_OBJECT, obj->string.pointer,
+ ejd);
kfree(buffer.pointer);
}
return status;
@@ -966,7 +967,7 @@ static void acpi_device_set_id(struct acpi_device *device,
case ACPI_BUS_TYPE_DEVICE:
status = acpi_get_object_info(handle, &buffer);
if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX "%s: Error reading device info\n", __FUNCTION__);
+ printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
return;
}
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 293a1cbb47c..d2f71a54726 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -504,7 +504,7 @@ static void acpi_power_off_prepare(void)
static void acpi_power_off(void)
{
/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
- printk("%s called\n", __FUNCTION__);
+ printk("%s called\n", __func__);
local_irq_disable();
acpi_enable_wakeup_device(ACPI_STATE_S5);
acpi_enter_sleep_state(ACPI_STATE_S5);
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 55cf4c05bb7..4749f379a91 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -319,7 +319,7 @@ void acpi_irq_stats_init(void)
goto fail;
for (i = 0; i < num_counters; ++i) {
- char buffer[10];
+ char buffer[12];
char *name;
if (i < num_gpes)
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 8d4b79b4f93..c4e00ac8ea8 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -879,6 +879,8 @@ static void acpi_thermal_check(void *data)
}
/* sys I/F for generic thermal sysfs support */
+#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)
+
static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
{
struct acpi_thermal *tz = thermal->devdata;
@@ -886,7 +888,7 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
if (!tz)
return -EINVAL;
- return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(tz->temperature));
+ return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
}
static const char enabled[] = "kernel";
@@ -980,21 +982,21 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
if (tz->trips.critical.flags.valid) {
if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(
+ return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
tz->trips.critical.temperature));
trip--;
}
if (tz->trips.hot.flags.valid) {
if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(
+ return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
tz->trips.hot.temperature));
trip--;
}
if (tz->trips.passive.flags.valid) {
if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(
+ return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
tz->trips.passive.temperature));
trip--;
}
@@ -1002,7 +1004,7 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
tz->trips.active[i].flags.valid; i++) {
if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(
+ return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
tz->trips.active[i].temperature));
trip--;
}
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index 9e8c20c6a0b..0a43c8e0eff 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -99,6 +99,13 @@ MODULE_LICENSE("GPL");
#define HCI_VIDEO_OUT_CRT 0x2
#define HCI_VIDEO_OUT_TV 0x4
+static const struct acpi_device_id toshiba_device_ids[] = {
+ {"TOS6200", 0},
+ {"TOS1900", 0},
+ {"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, toshiba_device_ids);
+
/* utility
*/
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index c7e128e5369..7361204b1ee 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -109,7 +109,7 @@ void acpi_ut_track_stack_ptr(void)
* RETURN: Updated pointer to the function name
*
* DESCRIPTION: Remove the "Acpi" prefix from the function name, if present.
- * This allows compiler macros such as __FUNCTION__ to be used
+ * This allows compiler macros such as __func__ to be used
* with no change to the debug output.
*
******************************************************************************/
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index 76ee766c84f..e08b3fa6639 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -432,7 +432,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
* element -- which is legal)
*/
if (!internal_object) {
- *obj_length = 0;
+ *obj_length = sizeof(union acpi_object);
return_ACPI_STATUS(AE_OK);
}
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index eba55b7d6c9..44ea60cf21c 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -407,6 +407,12 @@ acpi_evaluate_reference(acpi_handle handle,
break;
}
+ if (!element->reference.handle) {
+ printk(KERN_WARNING PREFIX "Invalid reference in"
+ " package %s\n", pathname);
+ status = AE_NULL_ENTRY;
+ break;
+ }
/* Get the acpi_handle. */
list->handles[i] = element->reference.handle;
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 12cce69b544..12fb44f1676 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -713,7 +713,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
kfree(obj);
- if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
+ if (device->cap._BCL && device->cap._BCM && max_level > 0) {
int result;
static int count = 0;
char *name;
@@ -807,40 +807,11 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
static int acpi_video_bus_check(struct acpi_video_bus *video)
{
acpi_status status = -ENOENT;
- long device_id;
- struct device *dev;
- struct acpi_device *device;
+
if (!video)
return -EINVAL;
- device = video->device;
-
- status =
- acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
-
- if (!ACPI_SUCCESS(status))
- return -ENODEV;
-
- /* We need to attempt to determine whether the _ADR refers to a
- PCI device or not. There's no terribly good way to do this,
- so the best we can hope for is to assume that there'll never
- be a video device in the host bridge */
- if (device_id >= 0x10000) {
- /* It looks like a PCI device. Does it exist? */
- dev = acpi_get_physical_device(device->handle);
- } else {
- /* It doesn't look like a PCI device. Does its parent
- exist? */
- acpi_handle phandle;
- if (acpi_get_parent(device->handle, &phandle))
- return -ENODEV;
- dev = acpi_get_physical_device(phandle);
- }
- if (!dev)
- return -ENODEV;
- put_device(dev);
-
/* Since there is no HID, CID and so on for VGA driver, we have
* to check well known required nodes.
*/
@@ -1201,7 +1172,7 @@ static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset)
if (!video)
goto end;
- printk(KERN_INFO PREFIX "Please implement %s\n", __FUNCTION__);
+ printk(KERN_INFO PREFIX "Please implement %s\n", __func__);
seq_printf(seq, "<TODO>\n");
end:
@@ -1366,37 +1337,8 @@ acpi_video_bus_write_DOS(struct file *file,
static int acpi_video_bus_add_fs(struct acpi_device *device)
{
- long device_id;
- int status;
struct proc_dir_entry *entry = NULL;
struct acpi_video_bus *video;
- struct device *dev;
-
- status =
- acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
-
- if (!ACPI_SUCCESS(status))
- return -ENODEV;
-
- /* We need to attempt to determine whether the _ADR refers to a
- PCI device or not. There's no terribly good way to do this,
- so the best we can hope for is to assume that there'll never
- be a video device in the host bridge */
- if (device_id >= 0x10000) {
- /* It looks like a PCI device. Does it exist? */
- dev = acpi_get_physical_device(device->handle);
- } else {
- /* It doesn't look like a PCI device. Does its parent
- exist? */
- acpi_handle phandle;
- if (acpi_get_parent(device->handle, &phandle))
- return -ENODEV;
- dev = acpi_get_physical_device(phandle);
- }
- if (!dev)
- return -ENODEV;
- put_device(dev);
-
video = acpi_driver_data(device);
diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c
index efacc9f8bfe..c33b1c6e93b 100644
--- a/drivers/acpi/wmi.c
+++ b/drivers/acpi/wmi.c
@@ -293,7 +293,7 @@ struct acpi_buffer *out)
{
struct guid_block *block = NULL;
struct wmi_block *wblock = NULL;
- acpi_handle handle;
+ acpi_handle handle, wc_handle;
acpi_status status, wc_status = AE_ERROR;
struct acpi_object_list input, wc_input;
union acpi_object wc_params[1], wq_params[1];
@@ -338,8 +338,10 @@ struct acpi_buffer *out)
* expensive, but have no corresponding WCxx method. So we
* should not fail if this happens.
*/
- wc_status = acpi_evaluate_object(handle, wc_method,
- &wc_input, NULL);
+ wc_status = acpi_get_handle(handle, wc_method, &wc_handle);
+ if (ACPI_SUCCESS(wc_status))
+ wc_status = acpi_evaluate_object(handle, wc_method,
+ &wc_input, NULL);
}
strcpy(method, "WQ");
@@ -351,7 +353,7 @@ struct acpi_buffer *out)
* If ACPI_WMI_EXPENSIVE, call the relevant WCxx method, even if
* the WQxx method failed - we should disable collection anyway.
*/
- if ((block->flags & ACPI_WMI_EXPENSIVE) && wc_status) {
+ if ((block->flags & ACPI_WMI_EXPENSIVE) && ACPI_SUCCESS(wc_status)) {
wc_params[0].integer.value = 0;
status = acpi_evaluate_object(handle,
wc_method, &wc_input, NULL);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index e469647330d..25aba69b59b 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -30,6 +30,7 @@ config ATA_NONSTANDARD
config ATA_ACPI
bool
depends on ACPI && PCI
+ select ACPI_DOCK
default y
help
This option adds support for ATA-related ACPI objects.
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 6978469eb16..17ee6ed985d 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -49,6 +49,10 @@
#define DRV_NAME "ahci"
#define DRV_VERSION "3.0"
+static int ahci_skip_host_reset;
+module_param_named(skip_host_reset, ahci_skip_host_reset, int, 0444);
+MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)");
+
static int ahci_enable_alpm(struct ata_port *ap,
enum link_pm policy);
static void ahci_disable_alpm(struct ata_port *ap);
@@ -587,6 +591,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
/* Marvell */
{ PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */
+ { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */
/* Generic, PCI class code for AHCI */
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -661,6 +666,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR];
u32 cap, port_map;
int i;
+ int mv;
/* make sure AHCI mode is enabled before accessing CAP */
ahci_enable_ahci(mmio);
@@ -696,12 +702,16 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
* presence register, as bit 4 (counting from 0)
*/
if (hpriv->flags & AHCI_HFLAG_MV_PATA) {
+ if (pdev->device == 0x6121)
+ mv = 0x3;
+ else
+ mv = 0xf;
dev_printk(KERN_ERR, &pdev->dev,
"MV_AHCI HACK: port_map %x -> %x\n",
- hpriv->port_map,
- hpriv->port_map & 0xf);
+ port_map,
+ port_map & mv);
- port_map &= 0xf;
+ port_map &= mv;
}
/* cross check port_map and cap.n_ports */
@@ -1088,29 +1098,35 @@ static int ahci_reset_controller(struct ata_host *host)
ahci_enable_ahci(mmio);
/* global controller reset */
- tmp = readl(mmio + HOST_CTL);
- if ((tmp & HOST_RESET) == 0) {
- writel(tmp | HOST_RESET, mmio + HOST_CTL);
- readl(mmio + HOST_CTL); /* flush */
- }
+ if (!ahci_skip_host_reset) {
+ tmp = readl(mmio + HOST_CTL);
+ if ((tmp & HOST_RESET) == 0) {
+ writel(tmp | HOST_RESET, mmio + HOST_CTL);
+ readl(mmio + HOST_CTL); /* flush */
+ }
- /* reset must complete within 1 second, or
- * the hardware should be considered fried.
- */
- ssleep(1);
+ /* reset must complete within 1 second, or
+ * the hardware should be considered fried.
+ */
+ ssleep(1);
- tmp = readl(mmio + HOST_CTL);
- if (tmp & HOST_RESET) {
- dev_printk(KERN_ERR, host->dev,
- "controller reset failed (0x%x)\n", tmp);
- return -EIO;
- }
+ tmp = readl(mmio + HOST_CTL);
+ if (tmp & HOST_RESET) {
+ dev_printk(KERN_ERR, host->dev,
+ "controller reset failed (0x%x)\n", tmp);
+ return -EIO;
+ }
- /* turn on AHCI mode */
- ahci_enable_ahci(mmio);
+ /* turn on AHCI mode */
+ ahci_enable_ahci(mmio);
- /* some registers might be cleared on reset. restore initial values */
- ahci_restore_initial_config(host);
+ /* Some registers might be cleared on reset. Restore
+ * initial values.
+ */
+ ahci_restore_initial_config(host);
+ } else
+ dev_printk(KERN_INFO, host->dev,
+ "skipping global host reset\n");
if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
u16 tmp16;
@@ -1162,9 +1178,14 @@ static void ahci_init_controller(struct ata_host *host)
int i;
void __iomem *port_mmio;
u32 tmp;
+ int mv;
if (hpriv->flags & AHCI_HFLAG_MV_PATA) {
- port_mmio = __ahci_port_base(host, 4);
+ if (pdev->device == 0x6121)
+ mv = 2;
+ else
+ mv = 4;
+ port_mmio = __ahci_port_base(host, mv);
writel(0, port_mmio + PORT_IRQ_MASK);
@@ -2241,7 +2262,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
return rc;
- rc = pcim_iomap_regions(pdev, 1 << AHCI_PCI_BAR, DRV_NAME);
+ /* AHCI controllers often implement SFF compatible interface.
+ * Grab all PCI BARs just in case.
+ */
+ rc = pcim_iomap_regions_request_all(pdev, 1 << AHCI_PCI_BAR, DRV_NAME);
if (rc == -EBUSY)
pcim_pin_device(pdev);
if (rc)
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 0770cb7391a..bf98a566ada 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -118,45 +118,77 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
}
-static void ata_acpi_handle_hotplug(struct ata_port *ap, struct kobject *kobj,
+static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
u32 event)
{
char event_string[12];
char *envp[] = { event_string, NULL };
- struct ata_eh_info *ehi = &ap->link.eh_info;
-
- if (event == 0 || event == 1) {
- unsigned long flags;
- spin_lock_irqsave(ap->lock, flags);
- ata_ehi_clear_desc(ehi);
- ata_ehi_push_desc(ehi, "ACPI event");
- ata_ehi_hotplugged(ehi);
- ata_port_freeze(ap);
- spin_unlock_irqrestore(ap->lock, flags);
+ struct ata_eh_info *ehi;
+ struct kobject *kobj = NULL;
+ int wait = 0;
+ unsigned long flags;
+
+ if (!ap)
+ ap = dev->link->ap;
+ ehi = &ap->link.eh_info;
+
+ spin_lock_irqsave(ap->lock, flags);
+
+ switch (event) {
+ case ACPI_NOTIFY_BUS_CHECK:
+ case ACPI_NOTIFY_DEVICE_CHECK:
+ ata_ehi_push_desc(ehi, "ACPI event");
+ ata_ehi_hotplugged(ehi);
+ ata_port_freeze(ap);
+ break;
+
+ case ACPI_NOTIFY_EJECT_REQUEST:
+ ata_ehi_push_desc(ehi, "ACPI event");
+ if (dev)
+ dev->flags |= ATA_DFLAG_DETACH;
+ else {
+ struct ata_link *tlink;
+ struct ata_device *tdev;
+
+ ata_port_for_each_link(tlink, ap)
+ ata_link_for_each_dev(tdev, tlink)
+ tdev->flags |= ATA_DFLAG_DETACH;
+ }
+
+ ata_port_schedule_eh(ap);
+ wait = 1;
+ break;
}
+ if (dev) {
+ if (dev->sdev)
+ kobj = &dev->sdev->sdev_gendev.kobj;
+ } else
+ kobj = &ap->dev->kobj;
+
if (kobj) {
sprintf(event_string, "BAY_EVENT=%d", event);
kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
}
+
+ spin_unlock_irqrestore(ap->lock, flags);
+
+ if (wait)
+ ata_port_wait_eh(ap);
}
static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
{
struct ata_device *dev = data;
- struct kobject *kobj = NULL;
- if (dev->sdev)
- kobj = &dev->sdev->sdev_gendev.kobj;
-
- ata_acpi_handle_hotplug(dev->link->ap, kobj, event);
+ ata_acpi_handle_hotplug(NULL, dev, event);
}
static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data)
{
struct ata_port *ap = data;
- ata_acpi_handle_hotplug(ap, &ap->dev->kobj, event);
+ ata_acpi_handle_hotplug(ap, NULL, event);
}
/**
@@ -191,20 +223,30 @@ void ata_acpi_associate(struct ata_host *host)
else
ata_acpi_associate_ide_port(ap);
- if (ap->acpi_handle)
- acpi_install_notify_handler (ap->acpi_handle,
- ACPI_SYSTEM_NOTIFY,
- ata_acpi_ap_notify,
- ap);
+ if (ap->acpi_handle) {
+ acpi_install_notify_handler(ap->acpi_handle,
+ ACPI_SYSTEM_NOTIFY,
+ ata_acpi_ap_notify, ap);
+#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
+ /* we might be on a docking station */
+ register_hotplug_dock_device(ap->acpi_handle,
+ ata_acpi_ap_notify, ap);
+#endif
+ }
for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
struct ata_device *dev = &ap->link.device[j];
- if (dev->acpi_handle)
- acpi_install_notify_handler (dev->acpi_handle,
- ACPI_SYSTEM_NOTIFY,
- ata_acpi_dev_notify,
- dev);
+ if (dev->acpi_handle) {
+ acpi_install_notify_handler(dev->acpi_handle,
+ ACPI_SYSTEM_NOTIFY,
+ ata_acpi_dev_notify, dev);
+#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
+ /* we might be on a docking station */
+ register_hotplug_dock_device(dev->acpi_handle,
+ ata_acpi_dev_notify, dev);
+#endif
+ }
}
}
}
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 7e68edf3c0f..8786455c901 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -295,7 +295,7 @@ static void ali_lock_sectors(struct ata_device *adev)
static int ali_check_atapi_dma(struct ata_queued_cmd *qc)
{
/* If its not a media command, its not worth it */
- if (qc->nbytes < 2048)
+ if (atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC)
return -EOPNOTSUPP;
return 0;
}
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index c662d686154..47c57a4294b 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -331,8 +331,8 @@ module_param(fs_keystream, int, 0);
#define FS_DEBUG_QSIZE 0x00001000
-#define func_enter() fs_dprintk (FS_DEBUG_FLOW, "fs: enter %s\n", __FUNCTION__)
-#define func_exit() fs_dprintk (FS_DEBUG_FLOW, "fs: exit %s\n", __FUNCTION__)
+#define func_enter() fs_dprintk(FS_DEBUG_FLOW, "fs: enter %s\n", __func__)
+#define func_exit() fs_dprintk(FS_DEBUG_FLOW, "fs: exit %s\n", __func__)
static struct fs_dev *fs_boards = NULL;
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index f97e050338f..9427a61f62b 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -95,8 +95,8 @@
#if 1
#define ASSERT(expr) if (!(expr)) { \
printk(FORE200E "assertion failed! %s[%d]: %s\n", \
- __FUNCTION__, __LINE__, #expr); \
- panic(FORE200E "%s", __FUNCTION__); \
+ __func__, __LINE__, #expr); \
+ panic(FORE200E "%s", __func__); \
}
#else
#define ASSERT(expr) do {} while (0)
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index eee54c0cde6..b967919fb7e 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -555,7 +555,7 @@ idt77252_tx_dump(struct idt77252_dev *card)
struct vc_map *vc;
int i;
- printk("%s\n", __FUNCTION__);
+ printk("%s\n", __func__);
for (i = 0; i < card->tct_size; i++) {
vc = card->vcs[i];
if (!vc)
@@ -1035,7 +1035,7 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
skb = sb_pool_skb(card, le32_to_cpu(rsqe->word_2));
if (skb == NULL) {
printk("%s: NULL skb in %s, rsqe: %08x %08x %08x %08x\n",
- card->name, __FUNCTION__,
+ card->name, __func__,
le32_to_cpu(rsqe->word_1), le32_to_cpu(rsqe->word_2),
le32_to_cpu(rsqe->word_3), le32_to_cpu(rsqe->word_4));
return;
@@ -1873,7 +1873,7 @@ add_rx_skb(struct idt77252_dev *card, int queue,
return;
if (sb_pool_add(card, skb, queue)) {
- printk("%s: SB POOL full\n", __FUNCTION__);
+ printk("%s: SB POOL full\n", __func__);
goto outfree;
}
@@ -1883,7 +1883,7 @@ add_rx_skb(struct idt77252_dev *card, int queue,
IDT77252_PRV_PADDR(skb) = paddr;
if (push_rx_skb(card, skb, queue)) {
- printk("%s: FB QUEUE full\n", __FUNCTION__);
+ printk("%s: FB QUEUE full\n", __func__);
goto outunmap;
}
}
@@ -3821,12 +3821,12 @@ static int __init idt77252_init(void)
{
struct sk_buff *skb;
- printk("%s: at %p\n", __FUNCTION__, idt77252_init);
+ printk("%s: at %p\n", __func__, idt77252_init);
if (sizeof(skb->cb) < sizeof(struct atm_skb_data) +
sizeof(struct idt77252_skb_prv)) {
printk(KERN_ERR "%s: skb->cb is too small (%lu < %lu)\n",
- __FUNCTION__, (unsigned long) sizeof(skb->cb),
+ __func__, (unsigned long) sizeof(skb->cb),
(unsigned long) sizeof(struct atm_skb_data) +
sizeof(struct idt77252_skb_prv));
return -EIO;
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index b6d230b3209..0d1d2133d9b 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -44,16 +44,6 @@ config MAC_FLOPPY
If you have a SWIM-3 (Super Woz Integrated Machine 3; from Apple)
floppy controller, say Y here. Most commonly found in PowerMacs.
-config BLK_DEV_PS2
- tristate "PS/2 ESDI hard disk support"
- depends on MCA && MCA_LEGACY && BROKEN
- help
- Say Y here if you have a PS/2 machine with a MCA bus and an ESDI
- hard disk.
-
- To compile this driver as a module, choose M here: the
- module will be called ps2esdi.
-
config AMIGA_Z2RAM
tristate "Amiga Zorro II ramdisk support"
depends on ZORRO
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 01c972415cb..5e584306be9 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -13,7 +13,6 @@ obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o
obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o
obj-$(CONFIG_BLK_DEV_RAM) += brd.o
obj-$(CONFIG_BLK_DEV_LOOP) += loop.o
-obj-$(CONFIG_BLK_DEV_PS2) += ps2esdi.o
obj-$(CONFIG_BLK_DEV_XD) += xd.o
obj-$(CONFIG_BLK_CPQ_DA) += cpqarray.o
obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 32c79a55511..7652e87d60c 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -217,7 +217,6 @@ static int use_virtual_dma;
*/
static DEFINE_SPINLOCK(floppy_lock);
-static struct completion device_release;
static unsigned short virtual_dma_port = 0x3f0;
irqreturn_t floppy_interrupt(int irq, void *dev_id);
@@ -4144,7 +4143,6 @@ DEVICE_ATTR(cmos,S_IRUGO,floppy_cmos_show,NULL);
static void floppy_device_release(struct device *dev)
{
- complete(&device_release);
}
static struct platform_device floppy_device[N_DRIVE];
@@ -4539,7 +4537,6 @@ void cleanup_module(void)
{
int drive;
- init_completion(&device_release);
blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
unregister_blkdev(FLOPPY_MAJOR, "fd");
@@ -4564,8 +4561,6 @@ void cleanup_module(void)
/* eject disk, if any */
fd_eject(0);
-
- wait_for_completion(&device_release);
}
module_param(floppy, charp, 0);
diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
deleted file mode 100644
index 3c796e23625..00000000000
--- a/drivers/block/ps2esdi.c
+++ /dev/null
@@ -1,1079 +0,0 @@
-/* ps2esdi driver based on assembler code by Arindam Banerji,
- written by Peter De Schrijver */
-/* Reassuring note to IBM : This driver was NOT developed by vice-versa
- engineering the PS/2's BIOS */
-/* Dedicated to Wannes, Tofke, Ykke, Godot, Killroy and all those
- other lovely fish out there... */
-/* This code was written during the long and boring WINA
- elections 1994 */
-/* Thanks to Arindam Banerij for giving me the source of his driver */
-/* This code may be freely distributed and modified in any way,
- as long as these notes remain intact */
-
-/* Revised: 05/07/94 by Arindam Banerji (axb@cse.nd.edu) */
-/* Revised: 09/08/94 by Peter De Schrijver (stud11@cc4.kuleuven.ac.be)
- Thanks to Arindam Banerij for sending me the docs of the adapter */
-
-/* BA Modified for ThinkPad 720 by Boris Ashkinazi */
-/* (bash@vnet.ibm.com) 08/08/95 */
-
-/* Modified further for ThinkPad-720C by Uri Blumenthal */
-/* (uri@watson.ibm.com) Sep 11, 1995 */
-
-/* TODO :
- + Timeouts
- + Get disk parameters
- + DMA above 16MB
- + reset after read/write error
- */
-
-#define DEVICE_NAME "PS/2 ESDI"
-
-#include <linux/major.h>
-#include <linux/errno.h>
-#include <linux/wait.h>
-#include <linux/interrupt.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/genhd.h>
-#include <linux/ps2esdi.h>
-#include <linux/blkdev.h>
-#include <linux/mca-legacy.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/hdreg.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/mca_dma.h>
-#include <asm/uaccess.h>
-
-#define PS2ESDI_IRQ 14
-#define MAX_HD 2
-#define MAX_RETRIES 5
-#define MAX_16BIT 65536
-#define ESDI_TIMEOUT 0xf000
-#define ESDI_STAT_TIMEOUT 4
-
-#define TYPE_0_CMD_BLK_LENGTH 2
-#define TYPE_1_CMD_BLK_LENGTH 4
-
-static void reset_ctrl(void);
-
-static int ps2esdi_geninit(void);
-
-static void do_ps2esdi_request(struct request_queue * q);
-
-static void ps2esdi_readwrite(int cmd, struct request *req);
-
-static void ps2esdi_fill_cmd_block(u_short * cmd_blk, u_short cmd,
-u_short cyl, u_short head, u_short sector, u_short length, u_char drive);
-
-static int ps2esdi_out_cmd_blk(u_short * cmd_blk);
-
-static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode);
-
-static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id);
-static void (*current_int_handler) (u_int) = NULL;
-static void ps2esdi_normal_interrupt_handler(u_int);
-static void ps2esdi_initial_reset_int_handler(u_int);
-static void ps2esdi_geometry_int_handler(u_int);
-static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo);
-
-static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer);
-
-static void dump_cmd_complete_status(u_int int_ret_code);
-
-static void ps2esdi_get_device_cfg(void);
-
-static void ps2esdi_reset_timer(unsigned long unused);
-
-static u_int dma_arb_level; /* DMA arbitration level */
-
-static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int);
-
-static int no_int_yet;
-static int ps2esdi_drives;
-static u_short io_base;
-static DEFINE_TIMER(esdi_timer, ps2esdi_reset_timer, 0, 0);
-static int reset_status;
-static int ps2esdi_slot = -1;
-static int tp720esdi = 0; /* Is it Integrated ESDI of ThinkPad-720? */
-static int intg_esdi = 0; /* If integrated adapter */
-struct ps2esdi_i_struct {
- unsigned int head, sect, cyl, wpcom, lzone, ctl;
-};
-static DEFINE_SPINLOCK(ps2esdi_lock);
-static struct request_queue *ps2esdi_queue;
-static struct request *current_req;
-
-#if 0
-#if 0 /* try both - I don't know which one is better... UB */
-static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
-{
- {4, 48, 1553, 0, 0, 0},
- {0, 0, 0, 0, 0, 0}};
-#else
-static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
-{
- {64, 32, 161, 0, 0, 0},
- {0, 0, 0, 0, 0, 0}};
-#endif
-#endif
-static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
-{
- {0, 0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0, 0}};
-
-static struct block_device_operations ps2esdi_fops =
-{
- .owner = THIS_MODULE,
- .getgeo = ps2esdi_getgeo,
-};
-
-static struct gendisk *ps2esdi_gendisk[2];
-
-/* initialization routine called by ll_rw_blk.c */
-static int __init ps2esdi_init(void)
-{
-
- int error = 0;
-
- /* register the device - pass the name and major number */
- if (register_blkdev(PS2ESDI_MAJOR, "ed"))
- return -EBUSY;
-
- /* set up some global information - indicating device specific info */
- ps2esdi_queue = blk_init_queue(do_ps2esdi_request, &ps2esdi_lock);
- if (!ps2esdi_queue) {
- unregister_blkdev(PS2ESDI_MAJOR, "ed");
- return -ENOMEM;
- }
-
- /* some minor housekeeping - setup the global gendisk structure */
- error = ps2esdi_geninit();
- if (error) {
- printk(KERN_WARNING "PS2ESDI: error initialising"
- " device, releasing resources\n");
- unregister_blkdev(PS2ESDI_MAJOR, "ed");
- blk_cleanup_queue(ps2esdi_queue);
- return error;
- }
- return 0;
-} /* ps2esdi_init */
-
-#ifndef MODULE
-
-module_init(ps2esdi_init);
-
-#else
-
-static int cyl[MAX_HD] = {-1,-1};
-static int head[MAX_HD] = {-1, -1};
-static int sect[MAX_HD] = {-1, -1};
-
-module_param(tp720esdi, bool, 0);
-module_param_array(cyl, int, NULL, 0);
-module_param_array(head, int, NULL, 0);
-module_param_array(sect, int, NULL, 0);
-MODULE_LICENSE("GPL");
-
-int init_module(void) {
- int drive;
-
- for(drive = 0; drive < MAX_HD; drive++) {
- struct ps2esdi_i_struct *info = &ps2esdi_info[drive];
-
- if (cyl[drive] != -1) {
- info->cyl = info->lzone = cyl[drive];
- info->wpcom = 0;
- }
- if (head[drive] != -1) {
- info->head = head[drive];
- info->ctl = (head[drive] > 8 ? 8 : 0);
- }
- if (sect[drive] != -1) info->sect = sect[drive];
- }
- return ps2esdi_init();
-}
-
-void
-cleanup_module(void) {
- int i;
- if(ps2esdi_slot) {
- mca_mark_as_unused(ps2esdi_slot);
- mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
- }
- release_region(io_base, 4);
- free_dma(dma_arb_level);
- free_irq(PS2ESDI_IRQ, &ps2esdi_gendisk);
- unregister_blkdev(PS2ESDI_MAJOR, "ed");
- blk_cleanup_queue(ps2esdi_queue);
- for (i = 0; i < ps2esdi_drives; i++) {
- del_gendisk(ps2esdi_gendisk[i]);
- put_disk(ps2esdi_gendisk[i]);
- }
-}
-#endif /* MODULE */
-
-/* handles boot time command line parameters */
-void __init tp720_setup(char *str, int *ints)
-{
- /* no params, just sets the tp720esdi flag if it exists */
-
- printk("%s: TP 720 ESDI flag set\n", DEVICE_NAME);
- tp720esdi = 1;
-}
-
-void __init ed_setup(char *str, int *ints)
-{
- int hdind = 0;
-
- /* handles 3 parameters only - corresponding to
- 1. Number of cylinders
- 2. Number of heads
- 3. Sectors/track
- */
-
- if (ints[0] != 3)
- return;
-
- /* print out the information - seen at boot time */
- printk("%s: ints[0]=%d ints[1]=%d ints[2]=%d ints[3]=%d\n",
- DEVICE_NAME, ints[0], ints[1], ints[2], ints[3]);
-
- /* set the index into device specific information table */
- if (ps2esdi_info[0].head != 0)
- hdind = 1;
-
- /* set up all the device information */
- ps2esdi_info[hdind].head = ints[2];
- ps2esdi_info[hdind].sect = ints[3];
- ps2esdi_info[hdind].cyl = ints[1];
- ps2esdi_info[hdind].wpcom = 0;
- ps2esdi_info[hdind].lzone = ints[1];
- ps2esdi_info[hdind].ctl = (ints[2] > 8 ? 8 : 0);
-#if 0 /* this may be needed for PS2/Mod.80, but it hurts ThinkPad! */
- ps2esdi_drives = hdind + 1; /* increment index for the next time */
-#endif
-} /* ed_setup */
-
-static int ps2esdi_getinfo(char *buf, int slot, void *d)
-{
- int len = 0;
-
- len += sprintf(buf + len, "DMA Arbitration Level: %d\n",
- dma_arb_level);
- len += sprintf(buf + len, "IO Port: %x\n", io_base);
- len += sprintf(buf + len, "IRQ: 14\n");
- len += sprintf(buf + len, "Drives: %d\n", ps2esdi_drives);
-
- return len;
-}
-
-/* ps2 esdi specific initialization - called thru the gendisk chain */
-static int __init ps2esdi_geninit(void)
-{
- /*
- The first part contains the initialization code
- for the ESDI disk subsystem. All we really do
- is search for the POS registers of the controller
- to do some simple setup operations. First, we
- must ensure that the controller is installed,
- enabled, and configured as PRIMARY. Then we must
- determine the DMA arbitration level being used by
- the controller so we can handle data transfer
- operations properly. If all of this works, then
- we will set the INIT_FLAG to a non-zero value.
- */
-
- int slot = 0, i, reset_start, reset_end;
- u_char status;
- unsigned short adapterID;
- int error = 0;
-
- if ((slot = mca_find_adapter(INTG_ESDI_ID, 0)) != MCA_NOTFOUND) {
- adapterID = INTG_ESDI_ID;
- printk("%s: integrated ESDI adapter found in slot %d\n",
- DEVICE_NAME, slot+1);
-#ifndef MODULE
- mca_set_adapter_name(slot, "PS/2 Integrated ESDI");
-#endif
- } else if ((slot = mca_find_adapter(NRML_ESDI_ID, 0)) != -1) {
- adapterID = NRML_ESDI_ID;
- printk("%s: normal ESDI adapter found in slot %d\n",
- DEVICE_NAME, slot+1);
- mca_set_adapter_name(slot, "PS/2 ESDI");
- } else {
- return -ENODEV;
- }
-
- ps2esdi_slot = slot;
- mca_mark_as_used(slot);
- mca_set_adapter_procfn(slot, (MCA_ProcFn) ps2esdi_getinfo, NULL);
-
- /* Found the slot - read the POS register 2 to get the necessary
- configuration and status information. POS register 2 has the
- following information :
- Bit Function
- 7 reserved = 0
- 6 arbitration method
- 0 - fairness enabled
- 1 - fairness disabled, linear priority assignment
- 5-2 arbitration level
- 1 alternate address
- 1 alternate address
- 0 - use addresses 0x3510 - 0x3517
- 0 adapter enable
- */
-
- status = mca_read_stored_pos(slot, 2);
- /* is it enabled ? */
- if (!(status & STATUS_ENABLED)) {
- printk("%s: ESDI adapter disabled\n", DEVICE_NAME);
- error = -ENODEV;
- goto err_out1;
- }
- /* try to grab IRQ, and try to grab a slow IRQ if it fails, so we can
- share with the SCSI driver */
- if (request_irq(PS2ESDI_IRQ, ps2esdi_interrupt_handler,
- IRQF_DISABLED | IRQF_SHARED, "PS/2 ESDI", &ps2esdi_gendisk)
- && request_irq(PS2ESDI_IRQ, ps2esdi_interrupt_handler,
- IRQF_SHARED, "PS/2 ESDI", &ps2esdi_gendisk)
- ) {
- printk("%s: Unable to get IRQ %d\n", DEVICE_NAME, PS2ESDI_IRQ);
- error = -EBUSY;
- goto err_out1;
- }
- if (status & STATUS_ALTERNATE)
- io_base = ALT_IO_BASE;
- else
- io_base = PRIMARY_IO_BASE;
-
- if (!request_region(io_base, 4, "ed")) {
- printk(KERN_WARNING"Unable to request region 0x%x\n", io_base);
- error = -EBUSY;
- goto err_out2;
- }
- /* get the dma arbitration level */
- dma_arb_level = (status >> 2) & 0xf;
-
- /* BA */
- printk("%s: DMA arbitration level : %d\n",
- DEVICE_NAME, dma_arb_level);
-
- LITE_ON;
- current_int_handler = ps2esdi_initial_reset_int_handler;
- reset_ctrl();
- reset_status = 0;
- reset_start = jiffies;
- while (!reset_status) {
- init_timer(&esdi_timer);
- esdi_timer.expires = jiffies + HZ;
- esdi_timer.data = 0;
- add_timer(&esdi_timer);
- sleep_on(&ps2esdi_int);
- }
- reset_end = jiffies;
- LITE_OFF;
- printk("%s: reset interrupt after %d jiffies, %u.%02u secs\n",
- DEVICE_NAME, reset_end - reset_start, (reset_end - reset_start) / HZ,
- (reset_end - reset_start) % HZ);
-
-
- /* Integrated ESDI Disk and Controller has only one drive! */
- if (adapterID == INTG_ESDI_ID) {/* if not "normal" PS2 ESDI adapter */
- ps2esdi_drives = 1; /* then we have only one physical disk! */ intg_esdi = 1;
- }
-
-
-
- /* finally this part sets up some global data structures etc. */
-
- ps2esdi_get_device_cfg();
-
- /* some annoyance in the above routine returns TWO drives?
- Is something else happining in the background?
- Regaurdless we fix the # of drives again. AJK */
- /* Integrated ESDI Disk and Controller has only one drive! */
- if (adapterID == INTG_ESDI_ID) /* if not "normal" PS2 ESDI adapter */
- ps2esdi_drives = 1; /* Not three or two, ONE DAMNIT! */
-
- current_int_handler = ps2esdi_normal_interrupt_handler;
-
- if (request_dma(dma_arb_level, "ed") !=0) {
- printk(KERN_WARNING "PS2ESDI: Can't request dma-channel %d\n"
- ,(int) dma_arb_level);
- error = -EBUSY;
- goto err_out3;
- }
- blk_queue_max_sectors(ps2esdi_queue, 128);
-
- error = -ENOMEM;
- for (i = 0; i < ps2esdi_drives; i++) {
- struct gendisk *disk = alloc_disk(64);
- if (!disk)
- goto err_out4;
- disk->major = PS2ESDI_MAJOR;
- disk->first_minor = i<<6;
- sprintf(disk->disk_name, "ed%c", 'a'+i);
- disk->fops = &ps2esdi_fops;
- ps2esdi_gendisk[i] = disk;
- }
-
- for (i = 0; i < ps2esdi_drives; i++) {
- struct gendisk *disk = ps2esdi_gendisk[i];
- set_capacity(disk, ps2esdi_info[i].head * ps2esdi_info[i].sect *
- ps2esdi_info[i].cyl);
- disk->queue = ps2esdi_queue;
- disk->private_data = &ps2esdi_info[i];
- add_disk(disk);
- }
- return 0;
-err_out4:
- while (i--)
- put_disk(ps2esdi_gendisk[i]);
-err_out3:
- release_region(io_base, 4);
-err_out2:
- free_irq(PS2ESDI_IRQ, &ps2esdi_gendisk);
-err_out1:
- if(ps2esdi_slot) {
- mca_mark_as_unused(ps2esdi_slot);
- mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
- }
- return error;
-}
-
-static void __init ps2esdi_get_device_cfg(void)
-{
- u_short cmd_blk[TYPE_0_CMD_BLK_LENGTH];
-
- /*BA */ printk("%s: Drive 0\n", DEVICE_NAME);
- current_int_handler = ps2esdi_geometry_int_handler;
- cmd_blk[0] = CMD_GET_DEV_CONFIG | 0x600;
- cmd_blk[1] = 0;
- no_int_yet = TRUE;
- ps2esdi_out_cmd_blk(cmd_blk);
- if (no_int_yet)
- sleep_on(&ps2esdi_int);
-
- if (ps2esdi_drives > 1) {
- printk("%s: Drive 1\n", DEVICE_NAME); /*BA */
- cmd_blk[0] = CMD_GET_DEV_CONFIG | (1 << 5) | 0x600;
- cmd_blk[1] = 0;
- no_int_yet = TRUE;
- ps2esdi_out_cmd_blk(cmd_blk);
- if (no_int_yet)
- sleep_on(&ps2esdi_int);
- } /* if second physical drive is present */
- return;
-}
-
-/* strategy routine that handles most of the IO requests */
-static void do_ps2esdi_request(struct request_queue * q)
-{
- struct request *req;
- /* since, this routine is called with interrupts cleared - they
- must be before it finishes */
-
- req = elv_next_request(q);
- if (!req)
- return;
-
-#if 0
- printk("%s:got request. device : %s command : %d sector : %ld count : %ld, buffer: %p\n",
- DEVICE_NAME,
- req->rq_disk->disk_name,
- req->cmd, req->sector,
- req->current_nr_sectors, req->buffer);
-#endif
-
- /* check for above 16Mb dmas */
- if (isa_virt_to_bus(req->buffer + req->current_nr_sectors * 512) > 16 * MB) {
- printk("%s: DMA above 16MB not supported\n", DEVICE_NAME);
- end_request(req, FAIL);
- return;
- }
-
- if (req->sector+req->current_nr_sectors > get_capacity(req->rq_disk)) {
- printk("Grrr. error. ps2esdi_drives: %d, %llu %llu\n",
- ps2esdi_drives, req->sector,
- (unsigned long long)get_capacity(req->rq_disk));
- end_request(req, FAIL);
- return;
- }
-
- switch (rq_data_dir(req)) {
- case READ:
- ps2esdi_readwrite(READ, req);
- break;
- case WRITE:
- ps2esdi_readwrite(WRITE, req);
- break;
- default:
- printk("%s: Unknown command\n", req->rq_disk->disk_name);
- end_request(req, FAIL);
- break;
- } /* handle different commands */
-} /* main strategy routine */
-
-/* resets the ESDI adapter */
-static void reset_ctrl(void)
-{
-
- u_long expire;
- u_short status;
-
- /* enable interrupts on the controller */
- status = inb(ESDI_INTRPT);
- outb((status & 0xe0) | ATT_EOI, ESDI_ATTN); /* to be sure we don't have
- any interrupt pending... */
- outb_p(CTRL_ENABLE_INTR, ESDI_CONTROL);
-
- /* read the ESDI status port - if the controller is not busy,
- simply do a soft reset (fast) - otherwise we'll have to do a
- hard (slow) reset. */
- if (!(inb_p(ESDI_STATUS) & STATUS_BUSY)) {
- /*BA */ printk("%s: soft reset...\n", DEVICE_NAME);
- outb_p(CTRL_SOFT_RESET, ESDI_ATTN);
- }
- /* soft reset */
- else {
- /*BA */
- printk("%s: hard reset...\n", DEVICE_NAME);
- outb_p(CTRL_HARD_RESET, ESDI_CONTROL);
- expire = jiffies + 2*HZ;
- while (time_before(jiffies, expire));
- outb_p(1, ESDI_CONTROL);
- } /* hard reset */
-
-
-} /* reset the controller */
-
-/* called by the strategy routine to handle read and write requests */
-static void ps2esdi_readwrite(int cmd, struct request *req)
-{
- struct ps2esdi_i_struct *p = req->rq_disk->private_data;
- unsigned block = req->sector;
- unsigned count = req->current_nr_sectors;
- int drive = p - ps2esdi_info;
- u_short track, head, cylinder, sector;
- u_short cmd_blk[TYPE_1_CMD_BLK_LENGTH];
-
- /* do some relevant arithmatic */
- track = block / p->sect;
- head = track % p->head;
- cylinder = track / p->head;
- sector = block % p->sect;
-
-#if 0
- printk("%s: cyl=%d head=%d sect=%d\n", DEVICE_NAME, cylinder, head, sector);
-#endif
- /* call the routine that actually fills out a command block */
- ps2esdi_fill_cmd_block
- (cmd_blk,
- (cmd == READ) ? CMD_READ : CMD_WRITE,
- cylinder, head, sector, count, drive);
-
- /* send the command block to the controller */
- current_req = req;
- spin_unlock_irq(&ps2esdi_lock);
- if (ps2esdi_out_cmd_blk(cmd_blk)) {
- spin_lock_irq(&ps2esdi_lock);
- printk("%s: Controller failed\n", DEVICE_NAME);
- if ((++req->errors) >= MAX_RETRIES)
- end_request(req, FAIL);
- }
- /* check for failure to put out the command block */
- else {
- spin_lock_irq(&ps2esdi_lock);
-#if 0
- printk("%s: waiting for xfer\n", DEVICE_NAME);
-#endif
- /* turn disk lights on */
- LITE_ON;
- }
-
-} /* ps2esdi_readwrite */
-
-/* fill out the command block */
-static void ps2esdi_fill_cmd_block(u_short * cmd_blk, u_short cmd,
- u_short cyl, u_short head, u_short sector, u_short length, u_char drive)
-{
-
- cmd_blk[0] = (drive << 5) | cmd;
- cmd_blk[1] = length;
- cmd_blk[2] = ((cyl & 0x1f) << 11) | (head << 5) | sector;
- cmd_blk[3] = (cyl & 0x3E0) >> 5;
-
-} /* fill out the command block */
-
-/* write a command block to the controller */
-static int ps2esdi_out_cmd_blk(u_short * cmd_blk)
-{
-
- int i;
- unsigned long jif;
- u_char status;
-
- /* enable interrupts */
- outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
-
- /* do not write to the controller, if it is busy */
- for (jif = jiffies + ESDI_STAT_TIMEOUT;
- time_after(jif, jiffies) &&
- (inb(ESDI_STATUS) & STATUS_BUSY); )
- ;
-
-#if 0
- printk("%s: i(1)=%ld\n", DEVICE_NAME, jif);
-#endif
-
- /* if device is still busy - then just time out */
- if (inb(ESDI_STATUS) & STATUS_BUSY) {
- printk("%s: ps2esdi_out_cmd timed out (1)\n", DEVICE_NAME);
- return ERROR;
- } /* timeout ??? */
- /* Set up the attention register in the controller */
- outb(((*cmd_blk) & 0xE0) | 1, ESDI_ATTN);
-
-#if 0
- printk("%s: sending %d words to controller\n", DEVICE_NAME, (((*cmd_blk) >> 14) + 1) << 1);
-#endif
-
- /* one by one send each word out */
- for (i = (((*cmd_blk) >> 14) + 1) << 1; i; i--) {
- status = inb(ESDI_STATUS);
- for (jif = jiffies + ESDI_STAT_TIMEOUT;
- time_after(jif, jiffies) && (status & STATUS_BUSY) &&
- (status & STATUS_CMD_INF); status = inb(ESDI_STATUS));
- if ((status & (STATUS_BUSY | STATUS_CMD_INF)) == STATUS_BUSY) {
-#if 0
- printk("%s: sending %04X\n", DEVICE_NAME, *cmd_blk);
-#endif
- outw(*cmd_blk++, ESDI_CMD_INT);
- } else {
- printk("%s: ps2esdi_out_cmd timed out while sending command (status=%02X)\n",
- DEVICE_NAME, status);
- return ERROR;
- }
- } /* send all words out */
- return OK;
-} /* send out the commands */
-
-
-/* prepare for dma - do all the necessary setup */
-static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode)
-{
- unsigned long flags = claim_dma_lock();
-
- mca_disable_dma(dma_arb_level);
-
- mca_set_dma_addr(dma_arb_level, isa_virt_to_bus(buffer));
-
- mca_set_dma_count(dma_arb_level, length * 512 / 2);
-
- mca_set_dma_mode(dma_arb_level, dma_xmode);
-
- mca_enable_dma(dma_arb_level);
-
- release_dma_lock(flags);
-
-} /* prepare for dma */
-
-
-
-static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id)
-{
- u_int int_ret_code;
-
- if (inb(ESDI_STATUS) & STATUS_INTR) {
- int_ret_code = inb(ESDI_INTRPT);
- if (current_int_handler) {
- /* Disable adapter interrupts till processing is finished */
- outb(CTRL_DISABLE_INTR, ESDI_CONTROL);
- current_int_handler(int_ret_code);
- } else
- printk("%s: help ! No interrupt handler.\n", DEVICE_NAME);
- } else {
- return IRQ_NONE;
- }
- return IRQ_HANDLED;
-}
-
-static void ps2esdi_initial_reset_int_handler(u_int int_ret_code)
-{
-
- switch (int_ret_code & 0xf) {
- case INT_RESET:
- /*BA */
- printk("%s: initial reset completed.\n", DEVICE_NAME);
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- wake_up(&ps2esdi_int);
- break;
- case INT_ATTN_ERROR:
- printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
- int_ret_code);
- printk("%s: status: %02x\n", DEVICE_NAME, inb(ESDI_STATUS));
- break;
- default:
- printk("%s: initial reset handler received interrupt: %02X\n",
- DEVICE_NAME, int_ret_code);
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- break;
- }
- outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
-}
-
-
-static void ps2esdi_geometry_int_handler(u_int int_ret_code)
-{
- u_int status, drive_num;
- unsigned long rba;
- int i;
-
- drive_num = int_ret_code >> 5;
- switch (int_ret_code & 0xf) {
- case INT_CMD_COMPLETE:
- for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
- if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
- printk("%s: timeout reading status word\n", DEVICE_NAME);
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- break;
- }
- status = inw(ESDI_STT_INT);
- if ((status & 0x1F) == CMD_GET_DEV_CONFIG) {
-#define REPLY_WORDS 5 /* we already read word 0 */
- u_short reply[REPLY_WORDS];
-
- if (ps2esdi_read_status_words((status >> 8) - 1, REPLY_WORDS, reply)) {
- /*BA */
- printk("%s: Device Configuration Status for drive %u\n",
- DEVICE_NAME, drive_num);
-
- printk("%s: Spares/cyls: %u", DEVICE_NAME, reply[0] >> 8);
-
- printk
- ("Config bits: %s%s%s%s%s\n",
- (reply[0] & CONFIG_IS) ? "Invalid Secondary, " : "",
- ((reply[0] & CONFIG_ZD) && !(reply[0] & CONFIG_IS))
- ? "Zero Defect, " : "Defects Present, ",
- (reply[0] & CONFIG_SF) ? "Skewed Format, " : "",
- (reply[0] & CONFIG_FR) ? "Removable, " : "Non-Removable, ",
- (reply[0] & CONFIG_RT) ? "No Retries" : "Retries");
-
- rba = reply[1] | ((unsigned long) reply[2] << 16);
- printk("%s: Number of RBA's: %lu\n", DEVICE_NAME, rba);
-
- printk("%s: Physical number of cylinders: %u, Sectors/Track: %u, Heads: %u\n",
- DEVICE_NAME, reply[3], reply[4] >> 8, reply[4] & 0xff);
-
- if (!ps2esdi_info[drive_num].head) {
- ps2esdi_info[drive_num].head = 64;
- ps2esdi_info[drive_num].sect = 32;
- ps2esdi_info[drive_num].cyl = rba / (64 * 32);
- ps2esdi_info[drive_num].wpcom = 0;
- ps2esdi_info[drive_num].lzone = ps2esdi_info[drive_num].cyl;
- ps2esdi_info[drive_num].ctl = 8;
- if (tp720esdi) { /* store the retrieved parameters */
- ps2esdi_info[0].head = reply[4] & 0Xff;
- ps2esdi_info[0].sect = reply[4] >> 8;
- ps2esdi_info[0].cyl = reply[3];
- ps2esdi_info[0].wpcom = 0;
- ps2esdi_info[0].lzone = reply[3];
- } else {
- if (!intg_esdi)
- ps2esdi_drives++;
- }
- }
-#ifdef OBSOLETE
- if (!ps2esdi_info[drive_num].head) {
- ps2esdi_info[drive_num].head = reply[4] & 0Xff;
- ps2esdi_info[drive_num].sect = reply[4] >> 8;
- ps2esdi_info[drive_num].cyl = reply[3];
- ps2esdi_info[drive_num].wpcom = 0;
- ps2esdi_info[drive_num].lzone = reply[3];
- if (tp720esdi) { /* store the retrieved parameters */
- ps2esdi_info[0].head = reply[4] & 0Xff;
- ps2esdi_info[0].sect = reply[4] >> 8;
- ps2esdi_info[0].cyl = reply[3];
- ps2esdi_info[0].wpcom = 0;
- ps2esdi_info[0].lzone = reply[3];
- } else {
- ps2esdi_drives++;
- }
- }
-#endif
-
- } else
- printk("%s: failed while getting device config\n", DEVICE_NAME);
-#undef REPLY_WORDS
- } else
- printk("%s: command %02X unknown by geometry handler\n",
- DEVICE_NAME, status & 0x1f);
-
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- break;
-
- case INT_ATTN_ERROR:
- printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
- int_ret_code);
- printk("%s: Device not available\n", DEVICE_NAME);
- break;
- case INT_CMD_ECC:
- case INT_CMD_RETRY:
- case INT_CMD_ECC_RETRY:
- case INT_CMD_WARNING:
- case INT_CMD_ABORT:
- case INT_CMD_FAILED:
- case INT_DMA_ERR:
- case INT_CMD_BLK_ERR:
- /*BA */ printk("%s: Whaa. Error occurred...\n", DEVICE_NAME);
- dump_cmd_complete_status(int_ret_code);
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- break;
- default:
- printk("%s: Unknown interrupt reason: %02X\n",
- DEVICE_NAME, int_ret_code & 0xf);
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- break;
- }
-
- wake_up(&ps2esdi_int);
- no_int_yet = FALSE;
- outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
-
-}
-
-static void ps2esdi_normal_interrupt_handler(u_int int_ret_code)
-{
- unsigned long flags;
- u_int status;
- u_int ending;
- int i;
-
- switch (int_ret_code & 0x0f) {
- case INT_TRANSFER_REQ:
- ps2esdi_prep_dma(current_req->buffer,
- current_req->current_nr_sectors,
- (rq_data_dir(current_req) == READ)
- ? MCA_DMA_MODE_16 | MCA_DMA_MODE_WRITE | MCA_DMA_MODE_XFER
- : MCA_DMA_MODE_16 | MCA_DMA_MODE_READ);
- outb(CTRL_ENABLE_DMA | CTRL_ENABLE_INTR, ESDI_CONTROL);
- ending = -1;
- break;
-
- case INT_ATTN_ERROR:
- printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
- int_ret_code);
- outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
- ending = FAIL;
- break;
-
- case INT_CMD_COMPLETE:
- for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
- if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
- printk("%s: timeout reading status word\n", DEVICE_NAME);
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
- if ((++current_req->errors) >= MAX_RETRIES)
- ending = FAIL;
- else
- ending = -1;
- break;
- }
- status = inw(ESDI_STT_INT);
- switch (status & 0x1F) {
- case (CMD_READ & 0xff):
- case (CMD_WRITE & 0xff):
- LITE_OFF;
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
- ending = SUCCES;
- break;
- default:
- printk("%s: interrupt for unknown command %02X\n",
- DEVICE_NAME, status & 0x1f);
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
- ending = -1;
- break;
- }
- break;
- case INT_CMD_ECC:
- case INT_CMD_RETRY:
- case INT_CMD_ECC_RETRY:
- LITE_OFF;
- dump_cmd_complete_status(int_ret_code);
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
- ending = SUCCES;
- break;
- case INT_CMD_WARNING:
- case INT_CMD_ABORT:
- case INT_CMD_FAILED:
- case INT_DMA_ERR:
- LITE_OFF;
- dump_cmd_complete_status(int_ret_code);
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
- if ((++current_req->errors) >= MAX_RETRIES)
- ending = FAIL;
- else
- ending = -1;
- break;
-
- case INT_CMD_BLK_ERR:
- dump_cmd_complete_status(int_ret_code);
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
- ending = FAIL;
- break;
-
- case INT_CMD_FORMAT:
- printk("%s: huh ? Who issued this format command ?\n"
- ,DEVICE_NAME);
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
- ending = -1;
- break;
-
- case INT_RESET:
- /* BA printk("%s: reset completed.\n", DEVICE_NAME) */ ;
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
- ending = -1;
- break;
-
- default:
- printk("%s: Unknown interrupt reason: %02X\n",
- DEVICE_NAME, int_ret_code & 0xf);
- outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
- outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
- ending = -1;
- break;
- }
- if(ending != -1) {
- spin_lock_irqsave(&ps2esdi_lock, flags);
- end_request(current_req, ending);
- current_req = NULL;
- do_ps2esdi_request(ps2esdi_queue);
- spin_unlock_irqrestore(&ps2esdi_lock, flags);
- }
-} /* handle interrupts */
-
-
-
-static int ps2esdi_read_status_words(int num_words,
- int max_words,
- u_short * buffer)
-{
- int i;
-
- for (; max_words && num_words; max_words--, num_words--, buffer++) {
- for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
- if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
- printk("%s: timeout reading status word\n", DEVICE_NAME);
- return FAIL;
- }
- *buffer = inw(ESDI_STT_INT);
- }
- return SUCCES;
-}
-
-
-
-
-static void dump_cmd_complete_status(u_int int_ret_code)
-{
-#define WAIT_FOR_STATUS \
- for(i=ESDI_TIMEOUT;i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL);i--); \
- if(!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) { \
- printk("%s: timeout reading status word\n",DEVICE_NAME); \
- return; \
- }
-
- int i, word_count;
- u_short stat_word;
- u_long rba;
-
- printk("%s: Device: %u, interrupt ID: %02X\n",
- DEVICE_NAME, int_ret_code >> 5,
- int_ret_code & 0xf);
-
- WAIT_FOR_STATUS;
- stat_word = inw(ESDI_STT_INT);
- word_count = (stat_word >> 8) - 1;
- printk("%s: %u status words, command: %02X\n", DEVICE_NAME, word_count,
- stat_word & 0xff);
-
- if (word_count--) {
- WAIT_FOR_STATUS;
- stat_word = inw(ESDI_STT_INT);
- printk("%s: command status code: %02X, command error code: %02X\n",
- DEVICE_NAME, stat_word >> 8, stat_word & 0xff);
- }
- if (word_count--) {
- WAIT_FOR_STATUS;
- stat_word = inw(ESDI_STT_INT);
- printk("%s: device error code: %s%s%s%s%s,%02X\n", DEVICE_NAME,
- (stat_word & 0x1000) ? "Ready, " : "Not Ready, ",
- (stat_word & 0x0800) ? "Selected, " : "Not Selected, ",
- (stat_word & 0x0400) ? "Write Fault, " : "",
- (stat_word & 0x0200) ? "Track 0, " : "",
- (stat_word & 0x0100) ? "Seek or command complete, " : "",
- stat_word >> 8);
- }
- if (word_count--) {
- WAIT_FOR_STATUS;
- stat_word = inw(ESDI_STT_INT);
- printk("%s: Blocks to do: %u", DEVICE_NAME, stat_word);
- }
- if (word_count -= 2) {
- WAIT_FOR_STATUS;
- rba = inw(ESDI_STT_INT);
- WAIT_FOR_STATUS;
- rba |= inw(ESDI_STT_INT) << 16;
- printk(", Last Cyl: %u Head: %u Sector: %u\n",
- (u_short) ((rba & 0x1ff80000) >> 11),
- (u_short) ((rba & 0x7E0) >> 5), (u_short) (rba & 0x1f));
- } else
- printk("\n");
-
- if (word_count--) {
- WAIT_FOR_STATUS;
- stat_word = inw(ESDI_STT_INT);
- printk("%s: Blocks required ECC: %u", DEVICE_NAME, stat_word);
- }
- printk("\n");
-
-#undef WAIT_FOR_STATUS
-
-}
-
-static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo)
-{
- struct ps2esdi_i_struct *p = bdev->bd_disk->private_data;
-
- geo->heads = p->head;
- geo->sectors = p->sect;
- geo->cylinders = p->cyl;
- return 0;
-}
-
-static void ps2esdi_reset_timer(unsigned long unused)
-{
-
- int status;
-
- status = inb(ESDI_INTRPT);
- if ((status & 0xf) == INT_RESET) {
- outb((status & 0xe0) | ATT_EOI, ESDI_ATTN);
- outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
- reset_status = 1;
- }
- wake_up(&ps2esdi_int);
-}
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index 9e61fca4611..41ca721d252 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -528,8 +528,7 @@ static int block_event_to_scatterlist(const struct vioblocklpevent *bevent,
numsg = VIOMAXBLOCKDMA;
*total_len = 0;
- memset(sg, 0, sizeof(sg[0]) * VIOMAXBLOCKDMA);
-
+ sg_init_table(sg, VIOMAXBLOCKDMA);
for (i = 0; (i < numsg) && (rw_data->dma_info[i].len > 0); ++i) {
sg_dma_address(&sg[i]) = rw_data->dma_info[i].token;
sg_dma_len(&sg[i]) = rw_data->dma_info[i].len;
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 3b1a68d6edd..0cfbe8c594a 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -238,6 +238,7 @@ static int virtblk_probe(struct virtio_device *vdev)
vblk->disk->first_minor = index_to_minor(index);
vblk->disk->private_data = vblk;
vblk->disk->fops = &virtblk_fops;
+ vblk->disk->driverfs_dev = &vdev->dev;
index++;
/* If barriers are supported, tell block layer that queue is ordered */
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index f16c94cbf48..8b884f87d8b 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -149,6 +149,9 @@ static struct usb_device_id blacklist_ids[] = {
{ USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
{ USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC },
+ /* CONWISE Technology based adapters with buggy SCO support */
+ { USB_DEVICE(0x0e5e, 0x6622), .driver_info = HCI_BROKEN_ISOC },
+
/* Belkin F8T012 and F8T013 devices */
{ USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
{ USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index d352dbb4ccf..e5a0e97cfdd 100644
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -35,42 +35,23 @@
# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
-static void *drm_ati_alloc_pcigart_table(int order)
+static int drm_ati_alloc_pcigart_table(struct drm_device *dev,
+ struct drm_ati_pcigart_info *gart_info)
{
- unsigned long address;
- struct page *page;
- int i;
-
- DRM_DEBUG("%d order\n", order);
-
- address = __get_free_pages(GFP_KERNEL | __GFP_COMP,
- order);
- if (address == 0UL) {
- return NULL;
- }
-
- page = virt_to_page(address);
+ gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size,
+ PAGE_SIZE,
+ gart_info->table_mask);
+ if (gart_info->table_handle == NULL)
+ return -ENOMEM;
- for (i = 0; i < order; i++, page++)
- SetPageReserved(page);
-
- DRM_DEBUG("returning 0x%08lx\n", address);
- return (void *)address;
+ return 0;
}
-static void drm_ati_free_pcigart_table(void *address, int order)
+static void drm_ati_free_pcigart_table(struct drm_device *dev,
+ struct drm_ati_pcigart_info *gart_info)
{
- struct page *page;
- int i;
- int num_pages = 1 << order;
- DRM_DEBUG("\n");
-
- page = virt_to_page((unsigned long)address);
-
- for (i = 0; i < num_pages; i++, page++)
- ClearPageReserved(page);
-
- free_pages((unsigned long)address, order);
+ drm_pci_free(dev, gart_info->table_handle);
+ gart_info->table_handle = NULL;
}
int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info)
@@ -78,8 +59,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info
struct drm_sg_mem *entry = dev->sg;
unsigned long pages;
int i;
- int order;
- int num_pages, max_pages;
+ int max_pages;
/* we need to support large memory configurations */
if (!entry) {
@@ -87,15 +67,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info
return 0;
}
- order = drm_order((gart_info->table_size + (PAGE_SIZE-1)) / PAGE_SIZE);
- num_pages = 1 << order;
-
if (gart_info->bus_addr) {
- if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
- pci_unmap_single(dev->pdev, gart_info->bus_addr,
- num_pages * PAGE_SIZE,
- PCI_DMA_TODEVICE);
- }
max_pages = (gart_info->table_size / sizeof(u32));
pages = (entry->pages <= max_pages)
@@ -112,10 +84,9 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info
gart_info->bus_addr = 0;
}
- if (gart_info->gart_table_location == DRM_ATI_GART_MAIN
- && gart_info->addr) {
- drm_ati_free_pcigart_table(gart_info->addr, order);
- gart_info->addr = NULL;
+ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN &&
+ gart_info->table_handle) {
+ drm_ati_free_pcigart_table(dev, gart_info);
}
return 1;
@@ -127,11 +98,10 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
struct drm_sg_mem *entry = dev->sg;
void *address = NULL;
unsigned long pages;
- u32 *pci_gart, page_base, bus_address = 0;
+ u32 *pci_gart, page_base;
+ dma_addr_t bus_address = 0;
int i, j, ret = 0;
- int order;
int max_pages;
- int num_pages;
if (!entry) {
DRM_ERROR("no scatter/gather memory!\n");
@@ -141,31 +111,14 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");
- order = drm_order((gart_info->table_size +
- (PAGE_SIZE-1)) / PAGE_SIZE);
- num_pages = 1 << order;
- address = drm_ati_alloc_pcigart_table(order);
- if (!address) {
+ ret = drm_ati_alloc_pcigart_table(dev, gart_info);
+ if (ret) {
DRM_ERROR("cannot allocate PCI GART page!\n");
goto done;
}
- if (!dev->pdev) {
- DRM_ERROR("PCI device unknown!\n");
- goto done;
- }
-
- bus_address = pci_map_single(dev->pdev, address,
- num_pages * PAGE_SIZE,
- PCI_DMA_TODEVICE);
- if (bus_address == 0) {
- DRM_ERROR("unable to map PCIGART pages!\n");
- order = drm_order((gart_info->table_size +
- (PAGE_SIZE-1)) / PAGE_SIZE);
- drm_ati_free_pcigart_table(address, order);
- address = NULL;
- goto done;
- }
+ address = gart_info->table_handle->vaddr;
+ bus_address = gart_info->table_handle->busaddr;
} else {
address = gart_info->addr;
bus_address = gart_info->bus_addr;
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index a6789f25009..8ea9dd1717a 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -54,6 +54,7 @@
#include <linux/pci.h>
#include <linux/jiffies.h>
#include <linux/smp_lock.h> /* For (un)lock_kernel */
+#include <linux/dma-mapping.h>
#include <linux/mm.h>
#include <linux/cdev.h>
#include <linux/mutex.h>
@@ -551,6 +552,8 @@ struct drm_ati_pcigart_info {
int gart_reg_if;
void *addr;
dma_addr_t bus_addr;
+ dma_addr_t table_mask;
+ struct drm_dma_handle *table_handle;
drm_local_map_t mapping;
int table_size;
};
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index 3992f73299c..f09d4b5002b 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -326,6 +326,7 @@ int drm_release(struct inode *inode, struct file *filp)
struct drm_file *file_priv = filp->private_data;
struct drm_device *dev = file_priv->head->dev;
int retcode = 0;
+ unsigned long irqflags;
lock_kernel();
@@ -357,9 +358,11 @@ int drm_release(struct inode *inode, struct file *filp)
*/
do{
- spin_lock(&dev->lock.spinlock);
+ spin_lock_irqsave(&dev->lock.spinlock,
+ irqflags);
locked = dev->lock.idle_has_lock;
- spin_unlock(&dev->lock.spinlock);
+ spin_unlock_irqrestore(&dev->lock.spinlock,
+ irqflags);
if (locked)
break;
schedule();
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
index bea2a7d5b2b..12dcdd1832f 100644
--- a/drivers/char/drm/drm_lock.c
+++ b/drivers/char/drm/drm_lock.c
@@ -53,6 +53,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
DECLARE_WAITQUEUE(entry, current);
struct drm_lock *lock = data;
int ret = 0;
+ unsigned long irqflags;
++file_priv->lock_count;
@@ -71,9 +72,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
return -EINVAL;
add_wait_queue(&dev->lock.lock_queue, &entry);
- spin_lock(&dev->lock.spinlock);
+ spin_lock_irqsave(&dev->lock.spinlock, irqflags);
dev->lock.user_waiters++;
- spin_unlock(&dev->lock.spinlock);
+ spin_unlock_irqrestore(&dev->lock.spinlock, irqflags);
for (;;) {
__set_current_state(TASK_INTERRUPTIBLE);
if (!dev->lock.hw_lock) {
@@ -95,9 +96,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
break;
}
}
- spin_lock(&dev->lock.spinlock);
+ spin_lock_irqsave(&dev->lock.spinlock, irqflags);
dev->lock.user_waiters--;
- spin_unlock(&dev->lock.spinlock);
+ spin_unlock_irqrestore(&dev->lock.spinlock, irqflags);
__set_current_state(TASK_RUNNING);
remove_wait_queue(&dev->lock.lock_queue, &entry);
@@ -198,8 +199,9 @@ int drm_lock_take(struct drm_lock_data *lock_data,
{
unsigned int old, new, prev;
volatile unsigned int *lock = &lock_data->hw_lock->lock;
+ unsigned long irqflags;
- spin_lock(&lock_data->spinlock);
+ spin_lock_irqsave(&lock_data->spinlock, irqflags);
do {
old = *lock;
if (old & _DRM_LOCK_HELD)
@@ -211,7 +213,7 @@ int drm_lock_take(struct drm_lock_data *lock_data,
}
prev = cmpxchg(lock, old, new);
} while (prev != old);
- spin_unlock(&lock_data->spinlock);
+ spin_unlock_irqrestore(&lock_data->spinlock, irqflags);
if (_DRM_LOCKING_CONTEXT(old) == context) {
if (old & _DRM_LOCK_HELD) {
@@ -272,15 +274,16 @@ int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context)
{
unsigned int old, new, prev;
volatile unsigned int *lock = &lock_data->hw_lock->lock;
+ unsigned long irqflags;
- spin_lock(&lock_data->spinlock);
+ spin_lock_irqsave(&lock_data->spinlock, irqflags);
if (lock_data->kernel_waiters != 0) {
drm_lock_transfer(lock_data, 0);
lock_data->idle_has_lock = 1;
- spin_unlock(&lock_data->spinlock);
+ spin_unlock_irqrestore(&lock_data->spinlock, irqflags);
return 1;
}
- spin_unlock(&lock_data->spinlock);
+ spin_unlock_irqrestore(&lock_data->spinlock, irqflags);
do {
old = *lock;
@@ -344,19 +347,20 @@ static int drm_notifier(void *priv)
void drm_idlelock_take(struct drm_lock_data *lock_data)
{
int ret = 0;
+ unsigned long irqflags;
- spin_lock(&lock_data->spinlock);
+ spin_lock_irqsave(&lock_data->spinlock, irqflags);
lock_data->kernel_waiters++;
if (!lock_data->idle_has_lock) {
- spin_unlock(&lock_data->spinlock);
+ spin_unlock_irqrestore(&lock_data->spinlock, irqflags);
ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT);
- spin_lock(&lock_data->spinlock);
+ spin_lock_irqsave(&lock_data->spinlock, irqflags);
if (ret == 1)
lock_data->idle_has_lock = 1;
}
- spin_unlock(&lock_data->spinlock);
+ spin_unlock_irqrestore(&lock_data->spinlock, irqflags);
}
EXPORT_SYMBOL(drm_idlelock_take);
@@ -364,8 +368,9 @@ void drm_idlelock_release(struct drm_lock_data *lock_data)
{
unsigned int old, prev;
volatile unsigned int *lock = &lock_data->hw_lock->lock;
+ unsigned long irqflags;
- spin_lock(&lock_data->spinlock);
+ spin_lock_irqsave(&lock_data->spinlock, irqflags);
if (--lock_data->kernel_waiters == 0) {
if (lock_data->idle_has_lock) {
do {
@@ -376,7 +381,7 @@ void drm_idlelock_release(struct drm_lock_data *lock_data)
lock_data->idle_has_lock = 0;
}
}
- spin_unlock(&lock_data->spinlock);
+ spin_unlock_irqrestore(&lock_data->spinlock, irqflags);
}
EXPORT_SYMBOL(drm_idlelock_release);
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index 715b361f0c2..a6a499f97e2 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -205,9 +205,9 @@
{0x1002, 0x71D6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x71DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \
{0x1002, 0x71DE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x7200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x7210, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x7211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x7200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x7210, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x7211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x7240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
{0x1002, 0x7243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
{0x1002, 0x7244, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
@@ -238,6 +238,7 @@
{0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \
{0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
+ {0x1002, 0x791f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
{0, 0, 0}
#define r128_PCI_IDS \
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c
index 892e0a58984..f36adbd3aaf 100644
--- a/drivers/char/drm/r128_cce.c
+++ b/drivers/char/drm/r128_cce.c
@@ -558,6 +558,7 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
#if __OS_HAS_AGP
if (dev_priv->is_pci) {
#endif
+ dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN;
dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE;
dev_priv->gart_info.addr = NULL;
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 833abc7e55f..9072e4a1894 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -1807,6 +1807,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
} else
#endif
{
+ dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
/* if we have an offset set from userspace */
if (dev_priv->pcigart_offset_set) {
dev_priv->gart_info.bus_addr =
diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c
index 94baec692b5..7a339dba6a6 100644
--- a/drivers/char/drm/via_dma.c
+++ b/drivers/char/drm/via_dma.c
@@ -126,6 +126,8 @@ via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size)
hw_addr, cur_addr, next_addr);
return -1;
}
+ if ((cur_addr < hw_addr) && (next_addr >= hw_addr))
+ msleep(1);
} while ((cur_addr < hw_addr) && (next_addr >= hw_addr));
return 0;
}
@@ -416,27 +418,50 @@ static int via_hook_segment(drm_via_private_t * dev_priv,
int paused, count;
volatile uint32_t *paused_at = dev_priv->last_pause_ptr;
uint32_t reader,ptr;
+ uint32_t diff;
paused = 0;
via_flush_write_combine();
(void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1);
+
*paused_at = pause_addr_lo;
via_flush_write_combine();
(void) *paused_at;
+
reader = *(dev_priv->hw_addr_ptr);
ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) +
dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
+
dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1;
- if ((ptr - reader) <= dev_priv->dma_diff ) {
- count = 10000000;
- while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--);
+ /*
+ * If there is a possibility that the command reader will
+ * miss the new pause address and pause on the old one,
+ * In that case we need to program the new start address
+ * using PCI.
+ */
+
+ diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
+ count = 10000000;
+ while(diff == 0 && count--) {
+ paused = (VIA_READ(0x41c) & 0x80000000);
+ if (paused)
+ break;
+ reader = *(dev_priv->hw_addr_ptr);
+ diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
}
+ paused = VIA_READ(0x41c) & 0x80000000;
+
if (paused && !no_pci_fire) {
reader = *(dev_priv->hw_addr_ptr);
- if ((ptr - reader) == dev_priv->dma_diff) {
-
+ diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
+ diff &= (dev_priv->dma_high - 1);
+ if (diff != 0 && diff < (dev_priv->dma_high >> 1)) {
+ DRM_ERROR("Paused at incorrect address. "
+ "0x%08x, 0x%08x 0x%08x\n",
+ ptr, reader, dev_priv->dma_diff);
+ } else if (diff == 0) {
/*
* There is a concern that these writes may stall the PCI bus
* if the GPU is not idle. However, idling the GPU first
@@ -577,6 +602,7 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
uint32_t pause_addr_lo, pause_addr_hi;
uint32_t jump_addr_lo, jump_addr_hi;
volatile uint32_t *last_pause_ptr;
+ uint32_t dma_low_save1, dma_low_save2;
agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi,
@@ -603,8 +629,29 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
&pause_addr_lo, 0);
*last_pause_ptr = pause_addr_lo;
+ dma_low_save1 = dev_priv->dma_low;
- via_hook_segment( dev_priv, jump_addr_hi, jump_addr_lo, 0);
+ /*
+ * Now, set a trap that will pause the regulator if it tries to rerun the old
+ * command buffer. (Which may happen if via_hook_segment detecs a command regulator pause
+ * and reissues the jump command over PCI, while the regulator has already taken the jump
+ * and actually paused at the current buffer end).
+ * There appears to be no other way to detect this condition, since the hw_addr_pointer
+ * does not seem to get updated immediately when a jump occurs.
+ */
+
+ last_pause_ptr =
+ via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ &pause_addr_lo, 0) - 1;
+ via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ &pause_addr_lo, 0);
+ *last_pause_ptr = pause_addr_lo;
+
+ dma_low_save2 = dev_priv->dma_low;
+ dev_priv->dma_low = dma_low_save1;
+ via_hook_segment(dev_priv, jump_addr_hi, jump_addr_lo, 0);
+ dev_priv->dma_low = dma_low_save2;
+ via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
}
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c
index 33c5197b73c..409e00afdd0 100644
--- a/drivers/char/drm/via_dmablit.c
+++ b/drivers/char/drm/via_dmablit.c
@@ -603,7 +603,7 @@ via_build_sg_info(struct drm_device *dev, drm_via_sg_info_t *vsg, drm_via_dmabli
* (Not a big limitation anyway.)
*/
- if ((xfer->mem_stride - xfer->line_length) >= PAGE_SIZE) {
+ if ((xfer->mem_stride - xfer->line_length) > 2*PAGE_SIZE) {
DRM_ERROR("Too large system memory stride. Stride: %d, "
"Length: %d\n", xfer->mem_stride, xfer->line_length);
return -EINVAL;
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 589ac6f65b9..3f9d0a9ac36 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -1709,7 +1709,7 @@ static int __init riscom8_init_module (void)
if (iobase || iobase1 || iobase2 || iobase3) {
for(i = 0; i < RC_NBOARD; i++)
- rc_board[0].base = 0;
+ rc_board[i].base = 0;
}
if (iobase)
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 72f289279d8..f585bc8579e 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -83,6 +83,7 @@
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
+#include <asm/unaligned.h>
#include <linux/bitops.h>
#include <linux/spinlock.h>
#include <linux/init.h>
@@ -1312,7 +1313,7 @@ static int rp_tiocmset(struct tty_struct *tty, struct file *file,
if (clear & TIOCM_DTR)
info->channel.TxControl[3] &= ~SET_DTR;
- sOutDW(info->channel.IndexAddr, *(DWord_t *) & (info->channel.TxControl[0]));
+ out32(info->channel.IndexAddr, info->channel.TxControl);
return 0;
}
@@ -1748,7 +1749,7 @@ static int rp_write(struct tty_struct *tty,
/* Write remaining data into the port's xmit_buf */
while (1) {
- if (info->tty == 0) /* Seemingly obligatory check... */
+ if (!info->tty) /* Seemingly obligatory check... */
goto end;
c = min(count, min(XMIT_BUF_SIZE - info->xmit_cnt - 1, XMIT_BUF_SIZE - info->xmit_head));
@@ -2798,7 +2799,7 @@ static int sReadAiopNumChan(WordIO_t io)
static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 };
/* write to chan 0 SRAM */
- sOutDW((DWordIO_t) io + _INDX_ADDR, *((DWord_t *) & R[0]));
+ out32((DWordIO_t) io + _INDX_ADDR, R);
sOutW(io + _INDX_ADDR, 0); /* read from SRAM, chan 0 */
x = sInW(io + _INDX_DATA);
sOutW(io + _INDX_ADDR, 0x4000); /* read from SRAM, chan 4 */
@@ -2864,7 +2865,7 @@ static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
R[1] = RData[i + 1] + 0x10 * ChanNum;
R[2] = RData[i + 2];
R[3] = RData[i + 3];
- sOutDW(ChP->IndexAddr, *((DWord_t *) & R[0]));
+ out32(ChP->IndexAddr, R);
}
ChR = ChP->R;
@@ -2887,43 +2888,43 @@ static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
ChP->BaudDiv[1] = (Byte_t) ((ChOff + _BAUD) >> 8);
ChP->BaudDiv[2] = (Byte_t) brd9600;
ChP->BaudDiv[3] = (Byte_t) (brd9600 >> 8);
- sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->BaudDiv[0]);
+ out32(ChP->IndexAddr, ChP->BaudDiv);
ChP->TxControl[0] = (Byte_t) (ChOff + _TX_CTRL);
ChP->TxControl[1] = (Byte_t) ((ChOff + _TX_CTRL) >> 8);
ChP->TxControl[2] = 0;
ChP->TxControl[3] = 0;
- sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxControl[0]);
+ out32(ChP->IndexAddr, ChP->TxControl);
ChP->RxControl[0] = (Byte_t) (ChOff + _RX_CTRL);
ChP->RxControl[1] = (Byte_t) ((ChOff + _RX_CTRL) >> 8);
ChP->RxControl[2] = 0;
ChP->RxControl[3] = 0;
- sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->RxControl[0]);
+ out32(ChP->IndexAddr, ChP->RxControl);
ChP->TxEnables[0] = (Byte_t) (ChOff + _TX_ENBLS);
ChP->TxEnables[1] = (Byte_t) ((ChOff + _TX_ENBLS) >> 8);
ChP->TxEnables[2] = 0;
ChP->TxEnables[3] = 0;
- sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxEnables[0]);
+ out32(ChP->IndexAddr, ChP->TxEnables);
ChP->TxCompare[0] = (Byte_t) (ChOff + _TXCMP1);
ChP->TxCompare[1] = (Byte_t) ((ChOff + _TXCMP1) >> 8);
ChP->TxCompare[2] = 0;
ChP->TxCompare[3] = 0;
- sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxCompare[0]);
+ out32(ChP->IndexAddr, ChP->TxCompare);
ChP->TxReplace1[0] = (Byte_t) (ChOff + _TXREP1B1);
ChP->TxReplace1[1] = (Byte_t) ((ChOff + _TXREP1B1) >> 8);
ChP->TxReplace1[2] = 0;
ChP->TxReplace1[3] = 0;
- sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxReplace1[0]);
+ out32(ChP->IndexAddr, ChP->TxReplace1);
ChP->TxReplace2[0] = (Byte_t) (ChOff + _TXREP2);
ChP->TxReplace2[1] = (Byte_t) ((ChOff + _TXREP2) >> 8);
ChP->TxReplace2[2] = 0;
ChP->TxReplace2[3] = 0;
- sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxReplace2[0]);
+ out32(ChP->IndexAddr, ChP->TxReplace2);
ChP->TxFIFOPtrs = ChOff + _TXF_OUTP;
ChP->TxFIFO = ChOff + _TX_FIFO;
@@ -2979,7 +2980,7 @@ static void sStopRxProcessor(CHANNEL_T * ChP)
R[1] = ChP->R[1];
R[2] = 0x0a;
R[3] = ChP->R[3];
- sOutDW(ChP->IndexAddr, *(DWord_t *) & R[0]);
+ out32(ChP->IndexAddr, R);
}
/***************************************************************************
@@ -3094,13 +3095,13 @@ static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
*WordPtr = ChP->TxPrioBuf; /* data byte address */
DWBuf[2] = Data; /* data byte value */
- sOutDW(IndexAddr, *((DWord_t *) (&DWBuf[0]))); /* write it out */
+ out32(IndexAddr, DWBuf); /* write it out */
*WordPtr = ChP->TxPrioCnt; /* Tx priority count address */
DWBuf[2] = PRI_PEND + 1; /* indicate 1 byte pending */
DWBuf[3] = 0; /* priority buffer pointer */
- sOutDW(IndexAddr, *((DWord_t *) (&DWBuf[0]))); /* write it out */
+ out32(IndexAddr, DWBuf); /* write it out */
} else { /* write it to Tx FIFO */
sWriteTxByte(sGetTxRxDataIO(ChP), Data);
@@ -3147,11 +3148,11 @@ static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
ChP->RxControl[2] |=
((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
- sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->RxControl[0]);
+ out32(ChP->IndexAddr, ChP->RxControl);
ChP->TxControl[2] |= ((Byte_t) Flags & TXINT_EN);
- sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxControl[0]);
+ out32(ChP->IndexAddr, ChP->TxControl);
if (Flags & CHANINT_EN) {
Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum];
@@ -3190,9 +3191,9 @@ static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
ChP->RxControl[2] &=
~((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
- sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->RxControl[0]);
+ out32(ChP->IndexAddr, ChP->RxControl);
ChP->TxControl[2] &= ~((Byte_t) Flags & TXINT_EN);
- sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxControl[0]);
+ out32(ChP->IndexAddr, ChP->TxControl);
if (Flags & CHANINT_EN) {
Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum];
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
index f3a75791b81..b01d38125a8 100644
--- a/drivers/char/rocket_int.h
+++ b/drivers/char/rocket_int.h
@@ -26,7 +26,6 @@ typedef unsigned int ByteIO_t;
typedef unsigned int Word_t;
typedef unsigned int WordIO_t;
-typedef unsigned long DWord_t;
typedef unsigned int DWordIO_t;
/*
@@ -38,7 +37,6 @@ typedef unsigned int DWordIO_t;
* instruction.
*/
-#ifdef ROCKET_DEBUG_IO
static inline void sOutB(unsigned short port, unsigned char value)
{
#ifdef ROCKET_DEBUG_IO
@@ -55,12 +53,13 @@ static inline void sOutW(unsigned short port, unsigned short value)
outw_p(value, port);
}
-static inline void sOutDW(unsigned short port, unsigned long value)
+static inline void out32(unsigned short port, Byte_t *p)
{
+ u32 value = le32_to_cpu(get_unaligned((__le32 *)p));
#ifdef ROCKET_DEBUG_IO
- printk(KERN_DEBUG "sOutDW(%x, %lx)...\n", port, value);
+ printk(KERN_DEBUG "out32(%x, %lx)...\n", port, value);
#endif
- outl_p(cpu_to_le32(value), port);
+ outl_p(value, port);
}
static inline unsigned char sInB(unsigned short port)
@@ -73,14 +72,6 @@ static inline unsigned short sInW(unsigned short port)
return inw_p(port);
}
-#else /* !ROCKET_DEBUG_IO */
-#define sOutB(a, b) outb_p(b, a)
-#define sOutW(a, b) outw_p(b, a)
-#define sOutDW(port, value) outl_p(cpu_to_le32(value), port)
-#define sInB(a) (inb_p(a))
-#define sInW(a) (inw_p(a))
-#endif /* ROCKET_DEBUG_IO */
-
/* This is used to move arrays of bytes so byte swapping isn't appropriate. */
#define sOutStrW(port, addr, count) if (count) outsw(port, addr, count)
#define sInStrW(port, addr, count) if (count) insw(port, addr, count)
@@ -390,7 +381,7 @@ Call: sClrBreak(ChP)
#define sClrBreak(ChP) \
do { \
(ChP)->TxControl[3] &= ~SETBREAK; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -402,7 +393,7 @@ Call: sClrDTR(ChP)
#define sClrDTR(ChP) \
do { \
(ChP)->TxControl[3] &= ~SET_DTR; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -415,7 +406,7 @@ Call: sClrRTS(ChP)
do { \
if ((ChP)->rtsToggle) break; \
(ChP)->TxControl[3] &= ~SET_RTS; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -489,7 +480,7 @@ Call: sDisCTSFlowCtl(ChP)
#define sDisCTSFlowCtl(ChP) \
do { \
(ChP)->TxControl[2] &= ~CTSFC_EN; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -501,7 +492,7 @@ Call: sDisIXANY(ChP)
#define sDisIXANY(ChP) \
do { \
(ChP)->R[0x0e] = 0x86; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x0c]); \
+ out32((ChP)->IndexAddr,&(ChP)->R[0x0c]); \
} while (0)
/***************************************************************************
@@ -515,7 +506,7 @@ Comments: Function sSetParity() can be used in place of functions sEnParity(),
#define sDisParity(ChP) \
do { \
(ChP)->TxControl[2] &= ~PARITY_EN; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -527,7 +518,7 @@ Call: sDisRTSToggle(ChP)
#define sDisRTSToggle(ChP) \
do { \
(ChP)->TxControl[2] &= ~RTSTOG_EN; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
(ChP)->rtsToggle = 0; \
} while (0)
@@ -540,7 +531,7 @@ Call: sDisRxFIFO(ChP)
#define sDisRxFIFO(ChP) \
do { \
(ChP)->R[0x32] = 0x0a; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x30]); \
+ out32((ChP)->IndexAddr,&(ChP)->R[0x30]); \
} while (0)
/***************************************************************************
@@ -567,7 +558,7 @@ Call: sDisTransmit(ChP)
#define sDisTransmit(ChP) \
do { \
(ChP)->TxControl[3] &= ~TX_ENABLE; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -579,7 +570,7 @@ Call: sDisTxSoftFlowCtl(ChP)
#define sDisTxSoftFlowCtl(ChP) \
do { \
(ChP)->R[0x06] = 0x8a; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x04]); \
+ out32((ChP)->IndexAddr,&(ChP)->R[0x04]); \
} while (0)
/***************************************************************************
@@ -604,7 +595,7 @@ Call: sEnCTSFlowCtl(ChP)
#define sEnCTSFlowCtl(ChP) \
do { \
(ChP)->TxControl[2] |= CTSFC_EN; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -616,7 +607,7 @@ Call: sEnIXANY(ChP)
#define sEnIXANY(ChP) \
do { \
(ChP)->R[0x0e] = 0x21; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x0c]); \
+ out32((ChP)->IndexAddr,&(ChP)->R[0x0c]); \
} while (0)
/***************************************************************************
@@ -633,7 +624,7 @@ Warnings: Before enabling parity odd or even parity should be chosen using
#define sEnParity(ChP) \
do { \
(ChP)->TxControl[2] |= PARITY_EN; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -647,10 +638,10 @@ Comments: This function will disable RTS flow control and clear the RTS
#define sEnRTSToggle(ChP) \
do { \
(ChP)->RxControl[2] &= ~RTSFC_EN; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->RxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->RxControl); \
(ChP)->TxControl[2] |= RTSTOG_EN; \
(ChP)->TxControl[3] &= ~SET_RTS; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
(ChP)->rtsToggle = 1; \
} while (0)
@@ -663,7 +654,7 @@ Call: sEnRxFIFO(ChP)
#define sEnRxFIFO(ChP) \
do { \
(ChP)->R[0x32] = 0x08; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x30]); \
+ out32((ChP)->IndexAddr,&(ChP)->R[0x30]); \
} while (0)
/***************************************************************************
@@ -684,7 +675,7 @@ Warnings: This function must be called after valid microcode has been
#define sEnRxProcessor(ChP) \
do { \
(ChP)->RxControl[2] |= RXPROC_EN; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->RxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->RxControl); \
} while (0)
/***************************************************************************
@@ -708,7 +699,7 @@ Call: sEnTransmit(ChP)
#define sEnTransmit(ChP) \
do { \
(ChP)->TxControl[3] |= TX_ENABLE; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -720,7 +711,7 @@ Call: sEnTxSoftFlowCtl(ChP)
#define sEnTxSoftFlowCtl(ChP) \
do { \
(ChP)->R[0x06] = 0xc5; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x04]); \
+ out32((ChP)->IndexAddr,&(ChP)->R[0x04]); \
} while (0)
/***************************************************************************
@@ -927,7 +918,7 @@ Call: sSendBreak(ChP)
#define sSendBreak(ChP) \
do { \
(ChP)->TxControl[3] |= SETBREAK; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -941,7 +932,7 @@ Call: sSetBaud(ChP,Divisor)
do { \
(ChP)->BaudDiv[2] = (Byte_t)(DIVISOR); \
(ChP)->BaudDiv[3] = (Byte_t)((DIVISOR) >> 8); \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->BaudDiv[0]); \
+ out32((ChP)->IndexAddr,(ChP)->BaudDiv); \
} while (0)
/***************************************************************************
@@ -953,7 +944,7 @@ Call: sSetData7(ChP)
#define sSetData7(ChP) \
do { \
(ChP)->TxControl[2] &= ~DATA8BIT; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -965,7 +956,7 @@ Call: sSetData8(ChP)
#define sSetData8(ChP) \
do { \
(ChP)->TxControl[2] |= DATA8BIT; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -977,7 +968,7 @@ Call: sSetDTR(ChP)
#define sSetDTR(ChP) \
do { \
(ChP)->TxControl[3] |= SET_DTR; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -994,7 +985,7 @@ Warnings: This function has no effect unless parity is enabled with function
#define sSetEvenParity(ChP) \
do { \
(ChP)->TxControl[2] |= EVEN_PAR; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -1011,7 +1002,7 @@ Warnings: This function has no effect unless parity is enabled with function
#define sSetOddParity(ChP) \
do { \
(ChP)->TxControl[2] &= ~EVEN_PAR; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -1024,7 +1015,7 @@ Call: sSetRTS(ChP)
do { \
if ((ChP)->rtsToggle) break; \
(ChP)->TxControl[3] |= SET_RTS; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -1050,7 +1041,7 @@ Comments: An interrupt will be generated when the trigger level is reached
do { \
(ChP)->RxControl[2] &= ~TRIG_MASK; \
(ChP)->RxControl[2] |= LEVEL; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->RxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->RxControl); \
} while (0)
/***************************************************************************
@@ -1062,7 +1053,7 @@ Call: sSetStop1(ChP)
#define sSetStop1(ChP) \
do { \
(ChP)->TxControl[2] &= ~STOP2; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -1074,7 +1065,7 @@ Call: sSetStop2(ChP)
#define sSetStop2(ChP) \
do { \
(ChP)->TxControl[2] |= STOP2; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ out32((ChP)->IndexAddr,(ChP)->TxControl); \
} while (0)
/***************************************************************************
@@ -1087,7 +1078,7 @@ Call: sSetTxXOFFChar(ChP,Ch)
#define sSetTxXOFFChar(ChP,CH) \
do { \
(ChP)->R[0x07] = (CH); \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x04]); \
+ out32((ChP)->IndexAddr,&(ChP)->R[0x04]); \
} while (0)
/***************************************************************************
@@ -1100,7 +1091,7 @@ Call: sSetTxXONChar(ChP,Ch)
#define sSetTxXONChar(ChP,CH) \
do { \
(ChP)->R[0x0b] = (CH); \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x08]); \
+ out32((ChP)->IndexAddr,&(ChP)->R[0x08]); \
} while (0)
/***************************************************************************
@@ -1113,7 +1104,7 @@ Comments: This function is used to start a Rx processor after it was
will restart both the Rx processor and software input flow control.
*/
-#define sStartRxProcessor(ChP) sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0])
+#define sStartRxProcessor(ChP) out32((ChP)->IndexAddr,&(ChP)->R[0])
/***************************************************************************
Function: sWriteTxByte
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 29965231b91..8db0e7f9d3f 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -357,7 +357,7 @@ int dma_async_device_register(struct dma_device *device)
!device->device_prep_dma_zero_sum);
BUG_ON(dma_has_cap(DMA_MEMSET, device->cap_mask) &&
!device->device_prep_dma_memset);
- BUG_ON(dma_has_cap(DMA_ZERO_SUM, device->cap_mask) &&
+ BUG_ON(dma_has_cap(DMA_INTERRUPT, device->cap_mask) &&
!device->device_prep_dma_interrupt);
BUG_ON(!device->device_alloc_chan_resources);
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index cc9a68158d9..72692309398 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -57,12 +57,12 @@ static void dma_init(struct fsl_dma_chan *fsl_chan)
}
-static void set_sr(struct fsl_dma_chan *fsl_chan, dma_addr_t val)
+static void set_sr(struct fsl_dma_chan *fsl_chan, u32 val)
{
DMA_OUT(fsl_chan, &fsl_chan->reg_base->sr, val, 32);
}
-static dma_addr_t get_sr(struct fsl_dma_chan *fsl_chan)
+static u32 get_sr(struct fsl_dma_chan *fsl_chan)
{
return DMA_IN(fsl_chan, &fsl_chan->reg_base->sr, 32);
}
@@ -123,6 +123,11 @@ static dma_addr_t get_ndar(struct fsl_dma_chan *fsl_chan)
return DMA_IN(fsl_chan, &fsl_chan->reg_base->ndar, 64);
}
+static u32 get_bcr(struct fsl_dma_chan *fsl_chan)
+{
+ return DMA_IN(fsl_chan, &fsl_chan->reg_base->bcr, 32);
+}
+
static int dma_is_idle(struct fsl_dma_chan *fsl_chan)
{
u32 sr = get_sr(fsl_chan);
@@ -406,6 +411,35 @@ static void fsl_dma_free_chan_resources(struct dma_chan *chan)
dma_pool_destroy(fsl_chan->desc_pool);
}
+static struct dma_async_tx_descriptor *
+fsl_dma_prep_interrupt(struct dma_chan *chan)
+{
+ struct fsl_dma_chan *fsl_chan;
+ struct fsl_desc_sw *new;
+
+ if (!chan)
+ return NULL;
+
+ fsl_chan = to_fsl_chan(chan);
+
+ new = fsl_dma_alloc_descriptor(fsl_chan);
+ if (!new) {
+ dev_err(fsl_chan->dev, "No free memory for link descriptor\n");
+ return NULL;
+ }
+
+ new->async_tx.cookie = -EBUSY;
+ new->async_tx.ack = 0;
+
+ /* Insert the link descriptor to the LD ring */
+ list_add_tail(&new->node, &new->async_tx.tx_list);
+
+ /* Set End-of-link to the last link descriptor of new list*/
+ set_ld_eol(fsl_chan, new);
+
+ return &new->async_tx;
+}
+
static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
struct dma_chan *chan, dma_addr_t dma_dest, dma_addr_t dma_src,
size_t len, unsigned long flags)
@@ -436,7 +470,7 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
dev_dbg(fsl_chan->dev, "new link desc alloc %p\n", new);
#endif
- copy = min(len, FSL_DMA_BCR_MAX_CNT);
+ copy = min(len, (size_t)FSL_DMA_BCR_MAX_CNT);
set_desc_cnt(fsl_chan, &new->hw, copy);
set_desc_src(fsl_chan, &new->hw, dma_src);
@@ -513,7 +547,6 @@ static void fsl_chan_ld_cleanup(struct fsl_dma_chan *fsl_chan)
spin_lock_irqsave(&fsl_chan->desc_lock, flags);
- fsl_dma_update_completed_cookie(fsl_chan);
dev_dbg(fsl_chan->dev, "chan completed_cookie = %d\n",
fsl_chan->completed_cookie);
list_for_each_entry_safe(desc, _desc, &fsl_chan->ld_queue, node) {
@@ -581,8 +614,8 @@ static void fsl_chan_xfer_ld_queue(struct fsl_dma_chan *fsl_chan)
if (ld_node != &fsl_chan->ld_queue) {
/* Get the ld start address from ld_queue */
next_dest_addr = to_fsl_desc(ld_node)->async_tx.phys;
- dev_dbg(fsl_chan->dev, "xfer LDs staring from 0x%016llx\n",
- (u64)next_dest_addr);
+ dev_dbg(fsl_chan->dev, "xfer LDs staring from %p\n",
+ (void *)next_dest_addr);
set_cdar(fsl_chan, next_dest_addr);
dma_start(fsl_chan);
} else {
@@ -662,7 +695,7 @@ static enum dma_status fsl_dma_is_complete(struct dma_chan *chan,
static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data)
{
struct fsl_dma_chan *fsl_chan = (struct fsl_dma_chan *)data;
- dma_addr_t stat;
+ u32 stat;
stat = get_sr(fsl_chan);
dev_dbg(fsl_chan->dev, "event: channel %d, stat = 0x%x\n",
@@ -676,15 +709,32 @@ static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data)
if (stat & FSL_DMA_SR_TE)
dev_err(fsl_chan->dev, "Transfer Error!\n");
+ /* Programming Error
+ * The DMA_INTERRUPT async_tx is a NULL transfer, which will
+ * triger a PE interrupt.
+ */
+ if (stat & FSL_DMA_SR_PE) {
+ dev_dbg(fsl_chan->dev, "event: Programming Error INT\n");
+ if (get_bcr(fsl_chan) == 0) {
+ /* BCR register is 0, this is a DMA_INTERRUPT async_tx.
+ * Now, update the completed cookie, and continue the
+ * next uncompleted transfer.
+ */
+ fsl_dma_update_completed_cookie(fsl_chan);
+ fsl_chan_xfer_ld_queue(fsl_chan);
+ }
+ stat &= ~FSL_DMA_SR_PE;
+ }
+
/* If the link descriptor segment transfer finishes,
* we will recycle the used descriptor.
*/
if (stat & FSL_DMA_SR_EOSI) {
dev_dbg(fsl_chan->dev, "event: End-of-segments INT\n");
- dev_dbg(fsl_chan->dev, "event: clndar 0x%016llx, "
- "nlndar 0x%016llx\n", (u64)get_cdar(fsl_chan),
- (u64)get_ndar(fsl_chan));
+ dev_dbg(fsl_chan->dev, "event: clndar %p, nlndar %p\n",
+ (void *)get_cdar(fsl_chan), (void *)get_ndar(fsl_chan));
stat &= ~FSL_DMA_SR_EOSI;
+ fsl_dma_update_completed_cookie(fsl_chan);
}
/* If it current transfer is the end-of-transfer,
@@ -726,12 +776,15 @@ static void dma_do_tasklet(unsigned long data)
fsl_chan_ld_cleanup(fsl_chan);
}
+#ifdef FSL_DMA_CALLBACKTEST
static void fsl_dma_callback_test(struct fsl_dma_chan *fsl_chan)
{
if (fsl_chan)
dev_info(fsl_chan->dev, "selftest: callback is ok!\n");
}
+#endif
+#ifdef CONFIG_FSL_DMA_SELFTEST
static int fsl_dma_self_test(struct fsl_dma_chan *fsl_chan)
{
struct dma_chan *chan;
@@ -813,6 +866,11 @@ static int fsl_dma_self_test(struct fsl_dma_chan *fsl_chan)
tx3 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0);
async_tx_ack(tx3);
+ /* Interrupt tx test */
+ tx1 = fsl_dma_prep_interrupt(chan);
+ async_tx_ack(tx1);
+ cookie = fsl_dma_tx_submit(tx1);
+
/* Test exchanging the prepared tx sort */
cookie = fsl_dma_tx_submit(tx3);
cookie = fsl_dma_tx_submit(tx2);
@@ -837,9 +895,9 @@ static int fsl_dma_self_test(struct fsl_dma_chan *fsl_chan)
if (err) {
for (i = 0; (*(src + i) == *(dest + i)) && (i < test_size);
i++);
- dev_err(fsl_chan->dev, "selftest: Test failed, data %d/%d is "
+ dev_err(fsl_chan->dev, "selftest: Test failed, data %d/%ld is "
"error! src 0x%x, dest 0x%x\n",
- i, test_size, *(src + i), *(dest + i));
+ i, (long)test_size, *(src + i), *(dest + i));
}
free_resources:
@@ -848,6 +906,7 @@ out:
kfree(src);
return err;
}
+#endif
static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,
const struct of_device_id *match)
@@ -1008,8 +1067,8 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev,
}
dev_info(&dev->dev, "Probe the Freescale DMA driver for %s "
- "controller at 0x%08x...\n",
- match->compatible, fdev->reg.start);
+ "controller at %p...\n",
+ match->compatible, (void *)fdev->reg.start);
fdev->reg_base = ioremap(fdev->reg.start, fdev->reg.end
- fdev->reg.start + 1);
@@ -1017,6 +1076,7 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev,
dma_cap_set(DMA_INTERRUPT, fdev->common.cap_mask);
fdev->common.device_alloc_chan_resources = fsl_dma_alloc_chan_resources;
fdev->common.device_free_chan_resources = fsl_dma_free_chan_resources;
+ fdev->common.device_prep_dma_interrupt = fsl_dma_prep_interrupt;
fdev->common.device_prep_dma_memcpy = fsl_dma_prep_memcpy;
fdev->common.device_is_tx_complete = fsl_dma_is_complete;
fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending;
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
index ba78c42121b..fddd6aee2a6 100644
--- a/drivers/dma/fsldma.h
+++ b/drivers/dma/fsldma.h
@@ -40,6 +40,7 @@
#define FSL_DMA_MR_EOTIE 0x00000080
#define FSL_DMA_SR_CH 0x00000020
+#define FSL_DMA_SR_PE 0x00000010
#define FSL_DMA_SR_CB 0x00000004
#define FSL_DMA_SR_TE 0x00000080
#define FSL_DMA_SR_EOSI 0x00000002
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 3986d54492b..f82b0906d46 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -140,7 +140,7 @@ static void __iop_adma_slot_cleanup(struct iop_adma_chan *iop_chan)
int busy = iop_chan_is_busy(iop_chan);
int seen_current = 0, slot_cnt = 0, slots_per_op = 0;
- dev_dbg(iop_chan->device->common.dev, "%s\n", __FUNCTION__);
+ dev_dbg(iop_chan->device->common.dev, "%s\n", __func__);
/* free completed slots from the chain starting with
* the oldest descriptor
*/
@@ -438,7 +438,7 @@ iop_adma_tx_submit(struct dma_async_tx_descriptor *tx)
spin_unlock_bh(&iop_chan->lock);
dev_dbg(iop_chan->device->common.dev, "%s cookie: %d slot: %d\n",
- __FUNCTION__, sw_desc->async_tx.cookie, sw_desc->idx);
+ __func__, sw_desc->async_tx.cookie, sw_desc->idx);
return cookie;
}
@@ -520,7 +520,7 @@ iop_adma_prep_dma_interrupt(struct dma_chan *chan)
struct iop_adma_desc_slot *sw_desc, *grp_start;
int slot_cnt, slots_per_op;
- dev_dbg(iop_chan->device->common.dev, "%s\n", __FUNCTION__);
+ dev_dbg(iop_chan->device->common.dev, "%s\n", __func__);
spin_lock_bh(&iop_chan->lock);
slot_cnt = iop_chan_interrupt_slot_count(&slots_per_op, iop_chan);
@@ -548,7 +548,7 @@ iop_adma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dma_dest,
BUG_ON(unlikely(len > IOP_ADMA_MAX_BYTE_COUNT));
dev_dbg(iop_chan->device->common.dev, "%s len: %u\n",
- __FUNCTION__, len);
+ __func__, len);
spin_lock_bh(&iop_chan->lock);
slot_cnt = iop_chan_memcpy_slot_count(len, &slots_per_op);
@@ -580,7 +580,7 @@ iop_adma_prep_dma_memset(struct dma_chan *chan, dma_addr_t dma_dest,
BUG_ON(unlikely(len > IOP_ADMA_MAX_BYTE_COUNT));
dev_dbg(iop_chan->device->common.dev, "%s len: %u\n",
- __FUNCTION__, len);
+ __func__, len);
spin_lock_bh(&iop_chan->lock);
slot_cnt = iop_chan_memset_slot_count(len, &slots_per_op);
@@ -614,7 +614,7 @@ iop_adma_prep_dma_xor(struct dma_chan *chan, dma_addr_t dma_dest,
dev_dbg(iop_chan->device->common.dev,
"%s src_cnt: %d len: %u flags: %lx\n",
- __FUNCTION__, src_cnt, len, flags);
+ __func__, src_cnt, len, flags);
spin_lock_bh(&iop_chan->lock);
slot_cnt = iop_chan_xor_slot_count(len, src_cnt, &slots_per_op);
@@ -648,7 +648,7 @@ iop_adma_prep_dma_zero_sum(struct dma_chan *chan, dma_addr_t *dma_src,
return NULL;
dev_dbg(iop_chan->device->common.dev, "%s src_cnt: %d len: %u\n",
- __FUNCTION__, src_cnt, len);
+ __func__, src_cnt, len);
spin_lock_bh(&iop_chan->lock);
slot_cnt = iop_chan_zero_sum_slot_count(len, src_cnt, &slots_per_op);
@@ -659,7 +659,7 @@ iop_adma_prep_dma_zero_sum(struct dma_chan *chan, dma_addr_t *dma_src,
iop_desc_set_zero_sum_byte_count(grp_start, len);
grp_start->xor_check_result = result;
pr_debug("\t%s: grp_start->xor_check_result: %p\n",
- __FUNCTION__, grp_start->xor_check_result);
+ __func__, grp_start->xor_check_result);
sw_desc->unmap_src_cnt = src_cnt;
sw_desc->unmap_len = len;
while (src_cnt--)
@@ -700,7 +700,7 @@ static void iop_adma_free_chan_resources(struct dma_chan *chan)
iop_chan->last_used = NULL;
dev_dbg(iop_chan->device->common.dev, "%s slots_allocated %d\n",
- __FUNCTION__, iop_chan->slots_allocated);
+ __func__, iop_chan->slots_allocated);
spin_unlock_bh(&iop_chan->lock);
/* one is ok since we left it on there on purpose */
@@ -753,7 +753,7 @@ static irqreturn_t iop_adma_eot_handler(int irq, void *data)
{
struct iop_adma_chan *chan = data;
- dev_dbg(chan->device->common.dev, "%s\n", __FUNCTION__);
+ dev_dbg(chan->device->common.dev, "%s\n", __func__);
tasklet_schedule(&chan->irq_tasklet);
@@ -766,7 +766,7 @@ static irqreturn_t iop_adma_eoc_handler(int irq, void *data)
{
struct iop_adma_chan *chan = data;
- dev_dbg(chan->device->common.dev, "%s\n", __FUNCTION__);
+ dev_dbg(chan->device->common.dev, "%s\n", __func__);
tasklet_schedule(&chan->irq_tasklet);
@@ -823,7 +823,7 @@ static int __devinit iop_adma_memcpy_self_test(struct iop_adma_device *device)
int err = 0;
struct iop_adma_chan *iop_chan;
- dev_dbg(device->common.dev, "%s\n", __FUNCTION__);
+ dev_dbg(device->common.dev, "%s\n", __func__);
src = kzalloc(sizeof(u8) * IOP_ADMA_TEST_SIZE, GFP_KERNEL);
if (!src)
@@ -906,7 +906,7 @@ iop_adma_xor_zero_sum_self_test(struct iop_adma_device *device)
int err = 0;
struct iop_adma_chan *iop_chan;
- dev_dbg(device->common.dev, "%s\n", __FUNCTION__);
+ dev_dbg(device->common.dev, "%s\n", __func__);
for (src_idx = 0; src_idx < IOP_ADMA_NUM_SRC_TEST; src_idx++) {
xor_srcs[src_idx] = alloc_page(GFP_KERNEL);
@@ -1159,7 +1159,7 @@ static int __devinit iop_adma_probe(struct platform_device *pdev)
}
dev_dbg(&pdev->dev, "%s: allocted descriptor pool virt %p phys %p\n",
- __FUNCTION__, adev->dma_desc_pool_virt,
+ __func__, adev->dma_desc_pool_virt,
(void *) adev->dma_desc_pool);
adev->id = plat_data->hw_id;
@@ -1289,7 +1289,7 @@ static void iop_chan_start_null_memcpy(struct iop_adma_chan *iop_chan)
dma_cookie_t cookie;
int slot_cnt, slots_per_op;
- dev_dbg(iop_chan->device->common.dev, "%s\n", __FUNCTION__);
+ dev_dbg(iop_chan->device->common.dev, "%s\n", __func__);
spin_lock_bh(&iop_chan->lock);
slot_cnt = iop_chan_memcpy_slot_count(0, &slots_per_op);
@@ -1346,7 +1346,7 @@ static void iop_chan_start_null_xor(struct iop_adma_chan *iop_chan)
dma_cookie_t cookie;
int slot_cnt, slots_per_op;
- dev_dbg(iop_chan->device->common.dev, "%s\n", __FUNCTION__);
+ dev_dbg(iop_chan->device->common.dev, "%s\n", __func__);
spin_lock_bh(&iop_chan->lock);
slot_cnt = iop_chan_xor_slot_count(0, 2, &slots_per_op);
diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
index fe9e768cfbc..25bdc2dd9ce 100644
--- a/drivers/firewire/Kconfig
+++ b/drivers/firewire/Kconfig
@@ -1,5 +1,3 @@
-# -*- shell-script -*-
-
comment "An alternative FireWire stack is available with EXPERIMENTAL=y"
depends on EXPERIMENTAL=n
@@ -21,27 +19,7 @@ config FIREWIRE
NOTE:
You should only build ONE of the stacks, unless you REALLY know what
- you are doing. If you install both, you should configure them only as
- modules rather than link them statically, and you should blacklist one
- of the concurrent low-level drivers in /etc/modprobe.conf. Add either
-
- blacklist firewire-ohci
- or
- blacklist ohci1394
-
- there depending on which driver you DON'T want to have auto-loaded.
- You can optionally do the same with the other IEEE 1394/ FireWire
- drivers.
-
- If you have an old modprobe which doesn't implement the blacklist
- directive, use either
-
- install firewire-ohci /bin/true
- or
- install ohci1394 /bin/true
-
- and so on, depending on which modules you DON't want to have
- auto-loaded.
+ you are doing.
config FIREWIRE_OHCI
tristate "Support for OHCI FireWire host controllers"
@@ -57,8 +35,24 @@ config FIREWIRE_OHCI
NOTE:
- If you also build ohci1394 of the classic stack, blacklist either
- ohci1394 or firewire-ohci to let hotplug load only the desired driver.
+ You should only build ohci1394 or firewire-ohci, but not both.
+ If you nevertheless want to install both, you should configure them
+ only as modules and blacklist the driver(s) which you don't want to
+ have auto-loaded. Add either
+
+ blacklist firewire-ohci
+ or
+ blacklist ohci1394
+ blacklist video1394
+ blacklist dv1394
+
+ to /etc/modprobe.conf or /etc/modprobe.d/* and update modprobe.conf
+ depending on your distribution. The latter two modules should be
+ blacklisted together with ohci1394 because they depend on ohci1394.
+
+ If you have an old modprobe which doesn't implement the blacklist
+ directive, use "install modulename /bin/true" for the modules to be
+ blacklisted.
config FIREWIRE_SBP2
tristate "Support for storage devices (SBP-2 protocol driver)"
@@ -75,9 +69,3 @@ config FIREWIRE_SBP2
You should also enable support for disks, CD-ROMs, etc. in the SCSI
configuration section.
-
- NOTE:
-
- If you also build sbp2 of the classic stack, blacklist either sbp2
- or firewire-sbp2 to let hotplug load only the desired driver.
-
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 7ebad3c14cb..996d61f0d46 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -33,6 +33,10 @@
#include <asm/page.h>
#include <asm/system.h>
+#ifdef CONFIG_PPC_PMAC
+#include <asm/pmac_feature.h>
+#endif
+
#include "fw-ohci.h"
#include "fw-transaction.h"
@@ -175,6 +179,7 @@ struct fw_ohci {
int generation;
int request_generation;
u32 bus_seconds;
+ bool old_uninorth;
/*
* Spinlock for accessing fw_ohci data. Never call out of
@@ -276,19 +281,13 @@ static int ar_context_add_page(struct ar_context *ctx)
{
struct device *dev = ctx->ohci->card.device;
struct ar_buffer *ab;
- dma_addr_t ab_bus;
+ dma_addr_t uninitialized_var(ab_bus);
size_t offset;
- ab = (struct ar_buffer *) __get_free_page(GFP_ATOMIC);
+ ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC);
if (ab == NULL)
return -ENOMEM;
- ab_bus = dma_map_single(dev, ab, PAGE_SIZE, DMA_BIDIRECTIONAL);
- if (dma_mapping_error(ab_bus)) {
- free_page((unsigned long) ab);
- return -ENOMEM;
- }
-
memset(&ab->descriptor, 0, sizeof(ab->descriptor));
ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE |
DESCRIPTOR_STATUS |
@@ -299,8 +298,6 @@ static int ar_context_add_page(struct ar_context *ctx)
ab->descriptor.res_count = cpu_to_le16(PAGE_SIZE - offset);
ab->descriptor.branch_address = 0;
- dma_sync_single_for_device(dev, ab_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
-
ctx->last_buffer->descriptor.branch_address = cpu_to_le32(ab_bus | 1);
ctx->last_buffer->next = ab;
ctx->last_buffer = ab;
@@ -311,15 +308,22 @@ static int ar_context_add_page(struct ar_context *ctx)
return 0;
}
+#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
+#define cond_le32_to_cpu(v) \
+ (ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v))
+#else
+#define cond_le32_to_cpu(v) le32_to_cpu(v)
+#endif
+
static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
{
struct fw_ohci *ohci = ctx->ohci;
struct fw_packet p;
u32 status, length, tcode;
- p.header[0] = le32_to_cpu(buffer[0]);
- p.header[1] = le32_to_cpu(buffer[1]);
- p.header[2] = le32_to_cpu(buffer[2]);
+ p.header[0] = cond_le32_to_cpu(buffer[0]);
+ p.header[1] = cond_le32_to_cpu(buffer[1]);
+ p.header[2] = cond_le32_to_cpu(buffer[2]);
tcode = (p.header[0] >> 4) & 0x0f;
switch (tcode) {
@@ -331,7 +335,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
break;
case TCODE_READ_BLOCK_REQUEST :
- p.header[3] = le32_to_cpu(buffer[3]);
+ p.header[3] = cond_le32_to_cpu(buffer[3]);
p.header_length = 16;
p.payload_length = 0;
break;
@@ -340,7 +344,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
case TCODE_READ_BLOCK_RESPONSE:
case TCODE_LOCK_REQUEST:
case TCODE_LOCK_RESPONSE:
- p.header[3] = le32_to_cpu(buffer[3]);
+ p.header[3] = cond_le32_to_cpu(buffer[3]);
p.header_length = 16;
p.payload_length = p.header[3] >> 16;
break;
@@ -357,7 +361,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
/* FIXME: What to do about evt_* errors? */
length = (p.header_length + p.payload_length + 3) / 4;
- status = le32_to_cpu(buffer[length]);
+ status = cond_le32_to_cpu(buffer[length]);
p.ack = ((status >> 16) & 0x1f) - 16;
p.speed = (status >> 21) & 0x7;
@@ -375,7 +379,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
*/
if (p.ack + 16 == 0x09)
- ohci->request_generation = (buffer[2] >> 16) & 0xff;
+ ohci->request_generation = (p.header[2] >> 16) & 0xff;
else if (ctx == &ohci->ar_request_ctx)
fw_core_handle_request(&ohci->card, &p);
else
@@ -397,6 +401,7 @@ static void ar_context_tasklet(unsigned long data)
if (d->res_count == 0) {
size_t size, rest, offset;
+ dma_addr_t buffer_bus;
/*
* This descriptor is finished and we may have a
@@ -405,9 +410,7 @@ static void ar_context_tasklet(unsigned long data)
*/
offset = offsetof(struct ar_buffer, data);
- dma_unmap_single(ohci->card.device,
- le32_to_cpu(ab->descriptor.data_address) - offset,
- PAGE_SIZE, DMA_BIDIRECTIONAL);
+ buffer_bus = le32_to_cpu(ab->descriptor.data_address) - offset;
buffer = ab;
ab = ab->next;
@@ -423,7 +426,8 @@ static void ar_context_tasklet(unsigned long data)
while (buffer < end)
buffer = handle_ar_packet(ctx, buffer);
- free_page((unsigned long)buffer);
+ dma_free_coherent(ohci->card.device, PAGE_SIZE,
+ buffer, buffer_bus);
ar_context_add_page(ctx);
} else {
buffer = ctx->pointer;
@@ -532,7 +536,7 @@ static int
context_add_buffer(struct context *ctx)
{
struct descriptor_buffer *desc;
- dma_addr_t bus_addr;
+ dma_addr_t uninitialized_var(bus_addr);
int offset;
/*
@@ -1022,13 +1026,14 @@ static void bus_reset_tasklet(unsigned long data)
*/
self_id_count = (reg_read(ohci, OHCI1394_SelfIDCount) >> 3) & 0x3ff;
- generation = (le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff;
+ generation = (cond_le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff;
rmb();
for (i = 1, j = 0; j < self_id_count; i += 2, j++) {
if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1])
fw_error("inconsistent self IDs\n");
- ohci->self_id_buffer[j] = le32_to_cpu(ohci->self_id_cpu[i]);
+ ohci->self_id_buffer[j] =
+ cond_le32_to_cpu(ohci->self_id_cpu[i]);
}
rmb();
@@ -1316,7 +1321,7 @@ ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length)
unsigned long flags;
int retval = -EBUSY;
__be32 *next_config_rom;
- dma_addr_t next_config_rom_bus;
+ dma_addr_t uninitialized_var(next_config_rom_bus);
ohci = fw_ohci(card);
@@ -1487,7 +1492,7 @@ static int handle_ir_dualbuffer_packet(struct context *context,
void *p, *end;
int i;
- if (db->first_res_count > 0 && db->second_res_count > 0) {
+ if (db->first_res_count != 0 && db->second_res_count != 0) {
if (ctx->excess_bytes <= le16_to_cpu(db->second_req_count)) {
/* This descriptor isn't done yet, stop iteration. */
return 0;
@@ -1513,7 +1518,7 @@ static int handle_ir_dualbuffer_packet(struct context *context,
memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
i += ctx->base.header_size;
ctx->excess_bytes +=
- (le32_to_cpu(*(u32 *)(p + 4)) >> 16) & 0xffff;
+ (le32_to_cpu(*(__le32 *)(p + 4)) >> 16) & 0xffff;
p += ctx->base.header_size + 4;
}
ctx->header_length = i;
@@ -2048,6 +2053,18 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
int err;
size_t size;
+#ifdef CONFIG_PPC_PMAC
+ /* Necessary on some machines if fw-ohci was loaded/ unloaded before */
+ if (machine_is(powermac)) {
+ struct device_node *ofn = pci_device_to_OF_node(dev);
+
+ if (ofn) {
+ pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 1);
+ pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1);
+ }
+ }
+#endif /* CONFIG_PPC_PMAC */
+
ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
if (ohci == NULL) {
fw_error("Could not malloc fw_ohci data.\n");
@@ -2066,6 +2083,10 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0);
pci_set_drvdata(dev, ohci);
+#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
+ ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE &&
+ dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW;
+#endif
spin_lock_init(&ohci->lock);
tasklet_init(&ohci->bus_reset_tasklet,
@@ -2182,6 +2203,19 @@ static void pci_remove(struct pci_dev *dev)
pci_disable_device(dev);
fw_card_put(&ohci->card);
+#ifdef CONFIG_PPC_PMAC
+ /* On UniNorth, power down the cable and turn off the chip clock
+ * to save power on laptops */
+ if (machine_is(powermac)) {
+ struct device_node *ofn = pci_device_to_OF_node(dev);
+
+ if (ofn) {
+ pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0);
+ pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 0);
+ }
+ }
+#endif /* CONFIG_PPC_PMAC */
+
fw_notify("Removed fw-ohci device.\n");
}
@@ -2202,6 +2236,16 @@ static int pci_suspend(struct pci_dev *pdev, pm_message_t state)
if (err)
fw_error("pci_set_power_state failed with %d\n", err);
+/* PowerMac suspend code comes last */
+#ifdef CONFIG_PPC_PMAC
+ if (machine_is(powermac)) {
+ struct device_node *ofn = pci_device_to_OF_node(pdev);
+
+ if (ofn)
+ pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0);
+ }
+#endif /* CONFIG_PPC_PMAC */
+
return 0;
}
@@ -2210,6 +2254,16 @@ static int pci_resume(struct pci_dev *pdev)
struct fw_ohci *ohci = pci_get_drvdata(pdev);
int err;
+/* PowerMac resume code comes first */
+#ifdef CONFIG_PPC_PMAC
+ if (machine_is(powermac)) {
+ struct device_node *ofn = pci_device_to_OF_node(pdev);
+
+ if (ofn)
+ pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1);
+ }
+#endif /* CONFIG_PPC_PMAC */
+
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
err = pci_enable_device(pdev);
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index 03069a454c0..62b4e47d0cc 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -173,6 +173,7 @@ struct sbp2_target {
#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */
#define SBP2_ORB_NULL 0x80000000
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
+#define SBP2_RETRY_LIMIT 0xf /* 15 retries */
#define SBP2_DIRECTION_TO_MEDIA 0x0
#define SBP2_DIRECTION_FROM_MEDIA 0x1
@@ -330,6 +331,11 @@ static const struct {
.model = ~0,
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
},
+ /* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ {
+ .firmware_revision = 0x002600,
+ .model = ~0,
+ .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
+ },
/*
* There are iPods (2nd gen, 3rd gen) with model_id == 0, but
@@ -812,6 +818,30 @@ static void sbp2_target_put(struct sbp2_target *tgt)
kref_put(&tgt->kref, sbp2_release_target);
}
+static void
+complete_set_busy_timeout(struct fw_card *card, int rcode,
+ void *payload, size_t length, void *done)
+{
+ complete(done);
+}
+
+static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu)
+{
+ struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
+ DECLARE_COMPLETION_ONSTACK(done);
+ struct fw_transaction t;
+ static __be32 busy_timeout;
+
+ /* FIXME: we should try to set dual-phase cycle_limit too */
+ busy_timeout = cpu_to_be32(SBP2_RETRY_LIMIT);
+
+ fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
+ lu->tgt->node_id, lu->generation, device->max_speed,
+ CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT, &busy_timeout,
+ sizeof(busy_timeout), complete_set_busy_timeout, &done);
+ wait_for_completion(&done);
+}
+
static void sbp2_reconnect(struct work_struct *work);
static void sbp2_login(struct work_struct *work)
@@ -864,10 +894,8 @@ static void sbp2_login(struct work_struct *work)
fw_notify("%s: logged in to LUN %04x (%d retries)\n",
tgt->bus_id, lu->lun, lu->retries);
-#if 0
- /* FIXME: The linux1394 sbp2 does this last step. */
- sbp2_set_busy_timeout(scsi_id);
-#endif
+ /* set appropriate retry limit(s) in BUSY_TIMEOUT register */
+ sbp2_set_busy_timeout(lu);
PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect);
sbp2_agent_reset(lu);
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
index e47bb040197..d2c7a3d7e1c 100644
--- a/drivers/firewire/fw-topology.c
+++ b/drivers/firewire/fw-topology.c
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/wait.h>
#include <linux/errno.h>
+#include <asm/bug.h>
#include <asm/system.h>
#include "fw-transaction.h"
#include "fw-topology.h"
@@ -424,8 +425,8 @@ update_tree(struct fw_card *card, struct fw_node *root)
node1 = fw_node(list1.next);
while (&node0->link != &list0) {
+ WARN_ON(node0->port_count != node1->port_count);
- /* assert(node0->port_count == node1->port_count); */
if (node0->link_on && !node1->link_on)
event = FW_NODE_LINK_OFF;
else if (!node0->link_on && node1->link_on)
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index 7fcc59dedf0..e6f1bda3894 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -736,6 +736,12 @@ fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
break;
}
+ /*
+ * The response handler may be executed while the request handler
+ * is still pending. Cancel the request handler.
+ */
+ card->driver->cancel_packet(card, &t->packet);
+
t->callback(card, rcode, data, data_length, t->callback_data);
}
EXPORT_SYMBOL(fw_core_handle_response);
@@ -751,7 +757,7 @@ handle_topology_map(struct fw_card *card, struct fw_request *request,
void *payload, size_t length, void *callback_data)
{
int i, start, end;
- u32 *map;
+ __be32 *map;
if (!TCODE_IS_READ_REQUEST(tcode)) {
fw_send_response(card, request, RCODE_TYPE_ERROR);
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index 09cb7287045..a43bb22912f 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -86,12 +86,12 @@
static inline void
fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
{
- u32 *dst = _dst;
- u32 *src = _src;
+ u32 *dst = _dst;
+ __be32 *src = _src;
int i;
for (i = 0; i < size / 4; i++)
- dst[i] = cpu_to_be32(src[i]);
+ dst[i] = be32_to_cpu(src[i]);
}
static inline void
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index d73a768e176..f0b00ec1e47 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -968,7 +968,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
size--;
}
- /* dump the report descriptor */
+ /* dump the report */
dbg_hid("report %d (size %u) = ", n, size);
for (i = 0; i < size; i++)
dbg_hid_line(" %02x", data[i]);
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 5a38fb27d69..c3eb3f13e2c 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -98,18 +98,16 @@ struct hidinput_key_translation {
static struct hidinput_key_translation apple_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
- { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
- { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
- { KEY_F3, KEY_CYCLEWINDOWS, APPLE_FLAG_FKEY }, /* Exposé */
- { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */
- { KEY_F5, KEY_FN_F5 },
- { KEY_F6, KEY_FN_F6 },
- { KEY_F7, KEY_BACK, APPLE_FLAG_FKEY },
- { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
- { KEY_F9, KEY_FORWARD, APPLE_FLAG_FKEY },
- { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY },
- { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
- { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
+ { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
+ { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
+ { KEY_F3, KEY_FN_F5, APPLE_FLAG_FKEY }, /* Exposé */
+ { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */
+ { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
+ { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
+ { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY },
+ { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY },
+ { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
+ { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
{ KEY_UP, KEY_PAGEUP },
{ KEY_DOWN, KEY_PAGEDOWN },
{ KEY_LEFT, KEY_HOME },
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index b38e559b7a4..d95979f0e02 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -278,7 +278,7 @@ static int hid_submit_ctrl(struct hid_device *hid)
usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0);
if (maxpacket > 0) {
- padlen = (len + maxpacket - 1) / maxpacket;
+ padlen = DIV_ROUND_UP(len, maxpacket);
padlen *= maxpacket;
if (padlen > usbhid->bufsize)
padlen = usbhid->bufsize;
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index e6d05f6b1c1..e29a057cbea 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -345,6 +345,9 @@
#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
#define USB_DEVICE_ID_N_S_HARMONY 0xc359
+#define USB_VENDOR_ID_NATSU 0x08b7
+#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001
+
#define USB_VENDOR_ID_NEC 0x073e
#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
@@ -426,6 +429,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
@@ -624,7 +628,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS, HID_QUIRK_APPLE_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 368879ff5d8..4dc76bc45c9 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -337,8 +337,9 @@ config SENSORS_IBMPEX
help
If you say yes here you get support for the temperature and
power sensors in various IBM System X servers that support
- PowerExecutive. So far this includes the x3550, x3650, x3655,
- x3755, and certain HS20 blades.
+ PowerExecutive. So far this includes the x3350, x3550, x3650,
+ x3655, and x3755; the x3800, x3850, and x3950 models that have
+ PCI Express; and some of the HS2x, LS2x, and QS2x blades.
This driver can also be built as a module. If so, the module
will be called ibmpex.
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c
index 9c9cdb0685e..4e9b19c6732 100644
--- a/drivers/hwmon/ibmpex.c
+++ b/drivers/hwmon/ibmpex.c
@@ -327,10 +327,14 @@ static int is_temp_sensor(const char *sensor_id, int len)
return 0;
}
-static int power_sensor_multiplier(const char *sensor_id, int len)
+static int power_sensor_multiplier(struct ibmpex_bmc_data *data,
+ const char *sensor_id, int len)
{
int i;
+ if (data->sensor_major == 2)
+ return 1000000;
+
for (i = PEX_SENSOR_TYPE_LEN; i < len - 1; i++)
if (!memcmp(&sensor_id[i], watt_sensor_sig, PEX_MULT_LEN))
return 1000000;
@@ -398,14 +402,15 @@ static int ibmpex_find_sensors(struct ibmpex_bmc_data *data)
num_power++;
sensor_counter = num_power;
data->sensors[i].multiplier =
- power_sensor_multiplier(data->rx_msg_data,
- data->rx_msg_len);
+ power_sensor_multiplier(data,
+ data->rx_msg_data,
+ data->rx_msg_len);
} else if (is_temp_sensor(data->rx_msg_data,
data->rx_msg_len)) {
sensor_type = TEMP_SENSOR;
num_temp++;
sensor_counter = num_temp;
- data->sensors[i].multiplier = 1;
+ data->sensors[i].multiplier = 1000;
} else
continue;
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
index 573abe44084..2fa43183d37 100644
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -335,7 +335,7 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
u8 temp;
/* driver_data might come from user-space, so check it */
- if (id->driver_data > ARRAY_SIZE(chipname))
+ if (id->driver_data >= ARRAY_SIZE(chipname))
return -EINVAL;
if (amd756_ioport) {
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index 501f00cea78..e47aca0ca5a 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -1,6 +1,13 @@
#
# Makefile for miscellaneous I2C chip drivers.
#
+# Think twice before you add a new driver to this directory.
+# Device drivers are better grouped according to the functionality they
+# implement rather than to the bus they are connected to. In particular:
+# * Hardware monitoring chip drivers go to drivers/hwmon
+# * RTC chip drivers go to drivers/rtc
+# * I/O expander drivers go to drivers/gpio
+#
obj-$(CONFIG_DS1682) += ds1682.o
obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 96da22e9a5a..fd84b2a3633 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -90,12 +90,16 @@ static int i2c_device_probe(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_driver *driver = to_i2c_driver(dev->driver);
+ int status;
if (!driver->probe)
return -ENODEV;
client->driver = driver;
dev_dbg(dev, "probe\n");
- return driver->probe(client);
+ status = driver->probe(client);
+ if (status)
+ client->driver = NULL;
+ return status;
}
static int i2c_device_remove(struct device *dev)
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 0518a2e948c..4c86a8d84b4 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -423,6 +423,25 @@ void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
}
/*
+ * We got an interrupt on a task_in case, but no errors and no DRQ.
+ *
+ * It might be a spurious irq (shared irq), but it might be a
+ * command that had no output.
+ */
+static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq, u8 stat)
+{
+ /* Command all done? */
+ if (OK_STAT(stat, READY_STAT, BUSY_STAT)) {
+ task_end_request(drive, rq, stat);
+ return ide_stopped;
+ }
+
+ /* Assume it was a spurious irq */
+ ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
+ return ide_started;
+}
+
+/*
* Handler for command with PIO data-in phase (Read/Read Multiple).
*/
static ide_startstop_t task_in_intr(ide_drive_t *drive)
@@ -431,18 +450,17 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive)
struct request *rq = HWGROUP(drive)->rq;
u8 stat = ide_read_status(drive);
- /* new way for dealing with premature shared PCI interrupts */
- if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) {
- if (stat & (ERR_STAT | DRQ_STAT))
- return task_error(drive, rq, __FUNCTION__, stat);
- /* No data yet, so wait for another IRQ. */
- ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
- return ide_started;
- }
+ /* Error? */
+ if (stat & ERR_STAT)
+ return task_error(drive, rq, __FUNCTION__, stat);
+
+ /* Didn't want any data? Odd. */
+ if (!(stat & DRQ_STAT))
+ return task_in_unexpected(drive, rq, stat);
ide_pio_datablock(drive, rq, 0);
- /* If it was the last datablock check status and finish transfer. */
+ /* Are we done? Check status and finish transfer. */
if (!hwif->nleft) {
stat = wait_drive_not_busy(drive);
if (!OK_STAT(stat, 0, BAD_STAT))
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 9e2b1964d71..f53f72daae3 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -376,6 +376,11 @@ static const struct {
.model_id = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
},
+ /* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ {
+ .firmware_revision = 0x002600,
+ .model_id = SBP2_ROM_VALUE_WILDCARD,
+ .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
+ },
/* iPod 4th generation */ {
.firmware_revision = 0x0a2700,
.model_id = 0x000021,
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index b10ade92efe..4df40515708 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -3759,6 +3759,7 @@ static void cm_remove_one(struct ib_device *device)
port = cm_dev->port[i-1];
ib_modify_port(device, port->port_num, 0, &port_modify);
ib_unregister_mad_agent(port->mad_agent);
+ flush_workqueue(cm.wq);
cm_remove_port_fs(port);
}
kobject_put(&cm_dev->dev_obj);
@@ -3813,6 +3814,7 @@ static void __exit ib_cm_cleanup(void)
cancel_delayed_work(&timewait_info->work.work);
spin_unlock_irq(&cm.lock);
+ ib_unregister_client(&cm_client);
destroy_workqueue(cm.wq);
list_for_each_entry_safe(timewait_info, tmp, &cm.timewait_list, list) {
@@ -3820,7 +3822,6 @@ static void __exit ib_cm_cleanup(void)
kfree(timewait_info);
}
- ib_unregister_client(&cm_client);
class_unregister(&cm_class);
idr_destroy(&cm.local_id_table);
}
diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c
index 7f00347364f..06d502c06a4 100644
--- a/drivers/infiniband/core/fmr_pool.c
+++ b/drivers/infiniband/core/fmr_pool.c
@@ -139,7 +139,7 @@ static inline struct ib_pool_fmr *ib_fmr_cache_lookup(struct ib_fmr_pool *pool,
static void ib_fmr_batch_release(struct ib_fmr_pool *pool)
{
int ret;
- struct ib_pool_fmr *fmr, *next;
+ struct ib_pool_fmr *fmr;
LIST_HEAD(unmap_list);
LIST_HEAD(fmr_list);
@@ -158,20 +158,6 @@ static void ib_fmr_batch_release(struct ib_fmr_pool *pool)
#endif
}
- /*
- * The free_list may hold FMRs that have been put there
- * because they haven't reached the max_remap count.
- * Invalidate their mapping as well.
- */
- list_for_each_entry_safe(fmr, next, &pool->free_list, list) {
- if (fmr->remap_count == 0)
- continue;
- hlist_del_init(&fmr->cache_node);
- fmr->remap_count = 0;
- list_add_tail(&fmr->fmr->list, &fmr_list);
- list_move(&fmr->list, &unmap_list);
- }
-
list_splice(&pool->dirty_list, &unmap_list);
INIT_LIST_HEAD(&pool->dirty_list);
pool->dirty_len = 0;
@@ -384,6 +370,11 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool)
i = 0;
list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) {
+ if (fmr->remap_count) {
+ INIT_LIST_HEAD(&fmr_list);
+ list_add_tail(&fmr->fmr->list, &fmr_list);
+ ib_unmap_fmr(&fmr_list);
+ }
ib_dealloc_fmr(fmr->fmr);
list_del(&fmr->list);
kfree(fmr);
@@ -407,8 +398,23 @@ EXPORT_SYMBOL(ib_destroy_fmr_pool);
*/
int ib_flush_fmr_pool(struct ib_fmr_pool *pool)
{
- int serial = atomic_inc_return(&pool->req_ser);
+ int serial;
+ struct ib_pool_fmr *fmr, *next;
+
+ /*
+ * The free_list holds FMRs that may have been used
+ * but have not been remapped enough times to be dirty.
+ * Put them on the dirty list now so that the cleanup
+ * thread will reap them too.
+ */
+ spin_lock_irq(&pool->pool_lock);
+ list_for_each_entry_safe(fmr, next, &pool->free_list, list) {
+ if (fmr->remap_count > 0)
+ list_move(&fmr->list, &pool->dirty_list);
+ }
+ spin_unlock_irq(&pool->pool_lock);
+ serial = atomic_inc_return(&pool->req_ser);
wake_up_process(pool->thread);
if (wait_event_interruptible(pool->force_wait,
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
index 223b1aa7d92..81c9195b512 100644
--- a/drivers/infiniband/core/iwcm.c
+++ b/drivers/infiniband/core/iwcm.c
@@ -839,6 +839,7 @@ static void cm_work_handler(struct work_struct *_work)
unsigned long flags;
int empty;
int ret = 0;
+ int destroy_id;
spin_lock_irqsave(&cm_id_priv->lock, flags);
empty = list_empty(&cm_id_priv->work_list);
@@ -857,9 +858,9 @@ static void cm_work_handler(struct work_struct *_work)
destroy_cm_id(&cm_id_priv->id);
}
BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
+ destroy_id = test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
if (iwcm_deref_id(cm_id_priv)) {
- if (test_bit(IWCM_F_CALLBACK_DESTROY,
- &cm_id_priv->flags)) {
+ if (destroy_id) {
BUG_ON(!list_empty(&cm_id_priv->work_list));
free_cm_id(cm_id_priv);
}
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index df1838f8f94..b2ea9210467 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -189,7 +189,7 @@ static struct ib_cq *iwch_create_cq(struct ib_device *ibdev, int entries, int ve
return ERR_PTR(-ENOMEM);
}
chp->rhp = rhp;
- chp->ibcq.cqe = (1 << chp->cq.size_log2) - 1;
+ chp->ibcq.cqe = 1 << chp->cq.size_log2;
spin_lock_init(&chp->lock);
atomic_set(&chp->refcnt, 1);
init_waitqueue_head(&chp->wait);
@@ -819,8 +819,11 @@ static struct ib_qp *iwch_create_qp(struct ib_pd *pd,
kfree(qhp);
return ERR_PTR(-ENOMEM);
}
+
attrs->cap.max_recv_wr = rqsize - 1;
attrs->cap.max_send_wr = sqsize;
+ attrs->cap.max_inline_data = T3_MAX_INLINE;
+
qhp->rhp = rhp;
qhp->attr.pd = php->pdid;
qhp->attr.scq = ((struct iwch_cq *) attrs->send_cq)->cq.cqid;
diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h
index 41462109554..591901aab6b 100644
--- a/drivers/infiniband/hw/ipath/ipath_common.h
+++ b/drivers/infiniband/hw/ipath/ipath_common.h
@@ -75,7 +75,7 @@
#define IPATH_IB_LINKDOWN 0
#define IPATH_IB_LINKARM 1
#define IPATH_IB_LINKACTIVE 2
-#define IPATH_IB_LINKINIT 3
+#define IPATH_IB_LINKDOWN_ONLY 3
#define IPATH_IB_LINKDOWN_SLEEP 4
#define IPATH_IB_LINKDOWN_DISABLE 5
#define IPATH_IB_LINK_LOOPBACK 6 /* enable local loopback */
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index d5ff6ca2db3..ca4d0acc678 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -851,8 +851,7 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first,
* -ETIMEDOUT state can have multiple states set, for any of several
* transitions.
*/
-static int ipath_wait_linkstate(struct ipath_devdata *dd, u32 state,
- int msecs)
+int ipath_wait_linkstate(struct ipath_devdata *dd, u32 state, int msecs)
{
dd->ipath_state_wanted = state;
wait_event_interruptible_timeout(ipath_state_wait,
@@ -1656,8 +1655,8 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl)
static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
{
static const char *what[4] = {
- [0] = "DOWN",
- [INFINIPATH_IBCC_LINKCMD_INIT] = "INIT",
+ [0] = "NOP",
+ [INFINIPATH_IBCC_LINKCMD_DOWN] = "DOWN",
[INFINIPATH_IBCC_LINKCMD_ARMED] = "ARMED",
[INFINIPATH_IBCC_LINKCMD_ACTIVE] = "ACTIVE"
};
@@ -1672,9 +1671,9 @@ static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
(dd, dd->ipath_kregs->kr_ibcstatus) >>
INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) &
INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]);
- /* flush all queued sends when going to DOWN or INIT, to be sure that
+ /* flush all queued sends when going to DOWN to be sure that
* they don't block MAD packets */
- if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT)
+ if (linkcmd == INFINIPATH_IBCC_LINKCMD_DOWN)
ipath_cancel_sends(dd, 1);
ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
@@ -1687,6 +1686,13 @@ int ipath_set_linkstate(struct ipath_devdata *dd, u8 newstate)
int ret;
switch (newstate) {
+ case IPATH_IB_LINKDOWN_ONLY:
+ ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_DOWN <<
+ INFINIPATH_IBCC_LINKCMD_SHIFT);
+ /* don't wait */
+ ret = 0;
+ goto bail;
+
case IPATH_IB_LINKDOWN:
ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_POLL <<
INFINIPATH_IBCC_LINKINITCMD_SHIFT);
@@ -1709,16 +1715,6 @@ int ipath_set_linkstate(struct ipath_devdata *dd, u8 newstate)
ret = 0;
goto bail;
- case IPATH_IB_LINKINIT:
- if (dd->ipath_flags & IPATH_LINKINIT) {
- ret = 0;
- goto bail;
- }
- ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_INIT <<
- INFINIPATH_IBCC_LINKCMD_SHIFT);
- lstate = IPATH_LINKINIT;
- break;
-
case IPATH_IB_LINKARM:
if (dd->ipath_flags & IPATH_LINKARMED) {
ret = 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 4cc0f95ea87..ecf3f7ff771 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -767,6 +767,7 @@ void ipath_kreceive(struct ipath_portdata *);
int ipath_setrcvhdrsize(struct ipath_devdata *, unsigned);
int ipath_reset_device(int);
void ipath_get_faststats(unsigned long);
+int ipath_wait_linkstate(struct ipath_devdata *, u32, int);
int ipath_set_linkstate(struct ipath_devdata *, u8);
int ipath_set_mtu(struct ipath_devdata *, u16);
int ipath_set_lid(struct ipath_devdata *, u32, u8);
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c
index d98d5f10370..b34b91d3723 100644
--- a/drivers/infiniband/hw/ipath/ipath_mad.c
+++ b/drivers/infiniband/hw/ipath/ipath_mad.c
@@ -555,10 +555,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp,
/* FALLTHROUGH */
case IB_PORT_DOWN:
if (lstate == 0)
- if (get_linkdowndefaultstate(dd))
- lstate = IPATH_IB_LINKDOWN_SLEEP;
- else
- lstate = IPATH_IB_LINKDOWN;
+ lstate = IPATH_IB_LINKDOWN_ONLY;
else if (lstate == 1)
lstate = IPATH_IB_LINKDOWN_SLEEP;
else if (lstate == 2)
@@ -568,6 +565,8 @@ static int recv_subn_set_portinfo(struct ib_smp *smp,
else
goto err;
ipath_set_linkstate(dd, lstate);
+ ipath_wait_linkstate(dd, IPATH_LINKINIT | IPATH_LINKARMED |
+ IPATH_LINKACTIVE, 1000);
break;
case IB_PORT_ARMED:
ipath_set_linkstate(dd, IPATH_IB_LINKARM);
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
index 80dc623cee4..087ed316647 100644
--- a/drivers/infiniband/hw/ipath/ipath_qp.c
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c
@@ -329,8 +329,9 @@ struct ipath_qp *ipath_lookup_qpn(struct ipath_qp_table *qpt, u32 qpn)
/**
* ipath_reset_qp - initialize the QP state to the reset state
* @qp: the QP to reset
+ * @type: the QP type
*/
-static void ipath_reset_qp(struct ipath_qp *qp)
+static void ipath_reset_qp(struct ipath_qp *qp, enum ib_qp_type type)
{
qp->remote_qpn = 0;
qp->qkey = 0;
@@ -342,7 +343,7 @@ static void ipath_reset_qp(struct ipath_qp *qp)
qp->s_psn = 0;
qp->r_psn = 0;
qp->r_msn = 0;
- if (qp->ibqp.qp_type == IB_QPT_RC) {
+ if (type == IB_QPT_RC) {
qp->s_state = IB_OPCODE_RC_SEND_LAST;
qp->r_state = IB_OPCODE_RC_SEND_LAST;
} else {
@@ -414,7 +415,7 @@ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
wc.wr_id = qp->r_wr_id;
wc.opcode = IB_WC_RECV;
wc.status = err;
- ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1);
+ ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1);
}
wc.status = IB_WC_WR_FLUSH_ERR;
@@ -534,7 +535,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
switch (new_state) {
case IB_QPS_RESET:
- ipath_reset_qp(qp);
+ ipath_reset_qp(qp, ibqp->qp_type);
break;
case IB_QPS_ERR:
@@ -647,7 +648,7 @@ int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
attr->port_num = 1;
attr->timeout = qp->timeout;
attr->retry_cnt = qp->s_retry_cnt;
- attr->rnr_retry = qp->s_rnr_retry;
+ attr->rnr_retry = qp->s_rnr_retry_cnt;
attr->alt_port_num = 0;
attr->alt_timeout = 0;
@@ -839,7 +840,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
goto bail_qp;
}
qp->ip = NULL;
- ipath_reset_qp(qp);
+ ipath_reset_qp(qp, init_attr->qp_type);
break;
default:
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c
index 459e46e2c01..40f3e37d7ad 100644
--- a/drivers/infiniband/hw/ipath/ipath_rc.c
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c
@@ -1196,6 +1196,10 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
list_move_tail(&qp->timerwait,
&dev->pending[dev->pending_index]);
spin_unlock(&dev->pending_lock);
+
+ if (opcode == OP(RDMA_READ_RESPONSE_MIDDLE))
+ qp->s_retry = qp->s_retry_cnt;
+
/*
* Update the RDMA receive state but do the copy w/o
* holding the locks and blocking interrupts.
diff --git a/drivers/infiniband/hw/ipath/ipath_registers.h b/drivers/infiniband/hw/ipath/ipath_registers.h
index 6d2a17f9c1d..92ad73a7fff 100644
--- a/drivers/infiniband/hw/ipath/ipath_registers.h
+++ b/drivers/infiniband/hw/ipath/ipath_registers.h
@@ -185,7 +185,7 @@
#define INFINIPATH_IBCC_LINKINITCMD_SLEEP 3
#define INFINIPATH_IBCC_LINKINITCMD_SHIFT 16
#define INFINIPATH_IBCC_LINKCMD_MASK 0x3ULL
-#define INFINIPATH_IBCC_LINKCMD_INIT 1 /* move to 0x11 */
+#define INFINIPATH_IBCC_LINKCMD_DOWN 1 /* move to 0x11 */
#define INFINIPATH_IBCC_LINKCMD_ARMED 2 /* move to 0x21 */
#define INFINIPATH_IBCC_LINKCMD_ACTIVE 3 /* move to 0x31 */
#define INFINIPATH_IBCC_LINKCMD_SHIFT 18
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 52b1bebfa74..2490b2d79db 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -38,6 +38,7 @@
#include <net/icmp.h>
#include <linux/icmpv6.h>
#include <linux/delay.h>
+#include <linux/vmalloc.h>
#include "ipoib.h"
@@ -637,6 +638,7 @@ static inline int post_send(struct ipoib_dev_priv *priv,
priv->tx_sge[0].addr = addr;
priv->tx_sge[0].length = len;
+ priv->tx_wr.num_sge = 1;
priv->tx_wr.wr_id = wr_id | IPOIB_OP_CM;
return ib_post_send(tx->qp, &priv->tx_wr, &bad_wr);
@@ -1030,13 +1032,13 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn,
struct ipoib_dev_priv *priv = netdev_priv(p->dev);
int ret;
- p->tx_ring = kzalloc(ipoib_sendq_size * sizeof *p->tx_ring,
- GFP_KERNEL);
+ p->tx_ring = vmalloc(ipoib_sendq_size * sizeof *p->tx_ring);
if (!p->tx_ring) {
ipoib_warn(priv, "failed to allocate tx ring\n");
ret = -ENOMEM;
goto err_tx;
}
+ memset(p->tx_ring, 0, ipoib_sendq_size * sizeof *p->tx_ring);
p->qp = ipoib_cm_create_tx_qp(p->dev, p);
if (IS_ERR(p->qp)) {
@@ -1077,6 +1079,7 @@ err_id:
ib_destroy_qp(p->qp);
err_qp:
p->qp = NULL;
+ vfree(p->tx_ring);
err_tx:
return ret;
}
@@ -1127,7 +1130,7 @@ timeout:
if (p->qp)
ib_destroy_qp(p->qp);
- kfree(p->tx_ring);
+ vfree(p->tx_ring);
kfree(p);
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index f96477a8ca5..57282048865 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -41,6 +41,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/kernel.h>
+#include <linux/vmalloc.h>
#include <linux/if_arp.h> /* For ARPHRD_xxx */
@@ -887,13 +888,13 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
goto out;
}
- priv->tx_ring = kzalloc(ipoib_sendq_size * sizeof *priv->tx_ring,
- GFP_KERNEL);
+ priv->tx_ring = vmalloc(ipoib_sendq_size * sizeof *priv->tx_ring);
if (!priv->tx_ring) {
printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n",
ca->name, ipoib_sendq_size);
goto out_rx_ring_cleanup;
}
+ memset(priv->tx_ring, 0, ipoib_sendq_size * sizeof *priv->tx_ring);
/* priv->tx_head, tx_tail & tx_outstanding are already 0 */
@@ -903,7 +904,7 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
return 0;
out_tx_ring_cleanup:
- kfree(priv->tx_ring);
+ vfree(priv->tx_ring);
out_rx_ring_cleanup:
kfree(priv->rx_ring);
@@ -928,7 +929,7 @@ void ipoib_dev_cleanup(struct net_device *dev)
ipoib_ib_dev_cleanup(dev);
kfree(priv->rx_ring);
- kfree(priv->tx_ring);
+ vfree(priv->tx_ring);
priv->rx_ring = NULL;
priv->tx_ring = NULL;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 2628339e3a9..31a53c5bcb1 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -650,7 +650,7 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
*/
spin_lock(&priv->lock);
- if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags) ||
+ if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags) ||
!priv->broadcast ||
!test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) {
++dev->stats.tx_dropped;
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 714b8db02b2..993f0a8ff28 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -237,36 +237,32 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn)
static
struct iser_device *iser_device_find_by_ib_device(struct rdma_cm_id *cma_id)
{
- struct list_head *p_list;
- struct iser_device *device = NULL;
+ struct iser_device *device;
mutex_lock(&ig.device_list_mutex);
- p_list = ig.device_list.next;
- while (p_list != &ig.device_list) {
- device = list_entry(p_list, struct iser_device, ig_list);
+ list_for_each_entry(device, &ig.device_list, ig_list)
/* find if there's a match using the node GUID */
if (device->ib_device->node_guid == cma_id->device->node_guid)
- break;
- }
+ goto inc_refcnt;
- if (device == NULL) {
- device = kzalloc(sizeof *device, GFP_KERNEL);
- if (device == NULL)
- goto out;
- /* assign this device to the device */
- device->ib_device = cma_id->device;
- /* init the device and link it into ig device list */
- if (iser_create_device_ib_res(device)) {
- kfree(device);
- device = NULL;
- goto out;
- }
- list_add(&device->ig_list, &ig.device_list);
+ device = kzalloc(sizeof *device, GFP_KERNEL);
+ if (device == NULL)
+ goto out;
+
+ /* assign this device to the device */
+ device->ib_device = cma_id->device;
+ /* init the device and link it into ig device list */
+ if (iser_create_device_ib_res(device)) {
+ kfree(device);
+ device = NULL;
+ goto out;
}
-out:
- BUG_ON(device == NULL);
+ list_add(&device->ig_list, &ig.device_list);
+
+inc_refcnt:
device->refcount++;
+out:
mutex_unlock(&ig.device_list_mutex);
return device;
}
@@ -372,6 +368,12 @@ static void iser_addr_handler(struct rdma_cm_id *cma_id)
int ret;
device = iser_device_find_by_ib_device(cma_id);
+ if (!device) {
+ iser_err("device lookup/creation failed\n");
+ iser_connect_error(cma_id);
+ return;
+ }
+
ib_conn = (struct iser_conn *)cma_id->context;
ib_conn->device = device;
@@ -380,7 +382,6 @@ static void iser_addr_handler(struct rdma_cm_id *cma_id)
iser_err("resolve route failed: %d\n", ret);
iser_connect_error(cma_id);
}
- return;
}
static void iser_route_handler(struct rdma_cm_id *cma_id)
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c
index 4833b1a8262..5511ef006a6 100644
--- a/drivers/input/misc/cobalt_btns.c
+++ b/drivers/input/misc/cobalt_btns.c
@@ -1,7 +1,7 @@
/*
* Cobalt button interface driver.
*
- * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ * Copyright (C) 2007-2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/init.h>
#include <linux/input-polldev.h>
@@ -55,7 +55,7 @@ static void handle_buttons(struct input_polled_dev *dev)
status = ~readl(bdev->reg) >> 24;
for (i = 0; i < ARRAY_SIZE(bdev->keymap); i++) {
- if (status & (1UL << i)) {
+ if (status & (1U << i)) {
if (++bdev->count[i] == BUTTONS_COUNT_THRESHOLD) {
input_event(input, EV_MSC, MSC_SCAN, i);
input_report_key(input, bdev->keymap[i], 1);
@@ -97,16 +97,16 @@ static int __devinit cobalt_buttons_probe(struct platform_device *pdev)
input->name = "Cobalt buttons";
input->phys = "cobalt/input0";
input->id.bustype = BUS_HOST;
- input->cdev.dev = &pdev->dev;
+ input->dev.parent = &pdev->dev;
- input->keycode = pdev->keymap;
- input->keycodemax = ARRAY_SIZE(pdev->keymap);
+ input->keycode = bdev->keymap;
+ input->keycodemax = ARRAY_SIZE(bdev->keymap);
input->keycodesize = sizeof(unsigned short);
input_set_capability(input, EV_MSC, MSC_SCAN);
__set_bit(EV_KEY, input->evbit);
- for (i = 0; i < ARRAY_SIZE(buttons_map); i++)
- __set_bit(input->keycode[i], input->keybit);
+ for (i = 0; i < ARRAY_SIZE(cobalt_map); i++)
+ __set_bit(bdev->keymap[i], input->keybit);
__clear_bit(KEY_RESERVED, input->keybit);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index b346a3b418e..385e32bcf6a 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -116,8 +116,8 @@ static void alps_process_packet(struct psmouse *psmouse)
}
if (priv->i->flags & ALPS_FW_BK_1) {
- back = packet[2] & 4;
- forward = packet[0] & 0x10;
+ back = packet[0] & 0x10;
+ forward = packet[2] & 4;
}
if (priv->i->flags & ALPS_FW_BK_2) {
@@ -483,6 +483,7 @@ int alps_init(struct psmouse *psmouse)
dev2->id.vendor = 0x0002;
dev2->id.product = PSMOUSE_ALPS;
dev2->id.version = 0x0000;
+ dev2->dev.parent = &psmouse->ps2dev.serio->dev;
dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
dev2->relbit[BIT_WORD(REL_X)] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
diff --git a/drivers/input/serio/i8042-snirm.h b/drivers/input/serio/i8042-snirm.h
new file mode 100644
index 00000000000..409a9341143
--- /dev/null
+++ b/drivers/input/serio/i8042-snirm.h
@@ -0,0 +1,75 @@
+#ifndef _I8042_SNIRM_H
+#define _I8042_SNIRM_H
+
+#include <asm/sni.h>
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+/*
+ * Names.
+ */
+
+#define I8042_KBD_PHYS_DESC "onboard/serio0"
+#define I8042_AUX_PHYS_DESC "onboard/serio1"
+#define I8042_MUX_PHYS_DESC "onboard/serio%d"
+
+/*
+ * IRQs.
+ */
+static int i8042_kbd_irq;
+static int i8042_aux_irq;
+#define I8042_KBD_IRQ i8042_kbd_irq
+#define I8042_AUX_IRQ i8042_aux_irq
+
+static void __iomem *kbd_iobase;
+
+#define I8042_COMMAND_REG (kbd_iobase + 0x64UL)
+#define I8042_DATA_REG (kbd_iobase + 0x60UL)
+
+static inline int i8042_read_data(void)
+{
+ return readb(kbd_iobase + 0x60UL);
+}
+
+static inline int i8042_read_status(void)
+{
+ return readb(kbd_iobase + 0x64UL);
+}
+
+static inline void i8042_write_data(int val)
+{
+ writeb(val, kbd_iobase + 0x60UL);
+}
+
+static inline void i8042_write_command(int val)
+{
+ writeb(val, kbd_iobase + 0x64UL);
+}
+static inline int i8042_platform_init(void)
+{
+ /* RM200 is strange ... */
+ if (sni_brd_type == SNI_BRD_RM200) {
+ kbd_iobase = ioremap(0x16000000, 4);
+ i8042_kbd_irq = 33;
+ i8042_aux_irq = 44;
+ } else {
+ kbd_iobase = ioremap(0x14000000, 4);
+ i8042_kbd_irq = 1;
+ i8042_aux_irq = 12;
+ }
+ if (!kbd_iobase)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static inline void i8042_platform_exit(void)
+{
+
+}
+
+#endif /* _I8042_SNIRM_H */
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 662e84482c2..60931aceb82 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -277,6 +277,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
},
},
+ {
+ .ident = "Lenovo 3000 n100",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"),
+ },
+ },
{ }
};
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 2763394869d..65a74cfc187 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -1151,7 +1151,6 @@ static int __devinit i8042_setup_kbd(void)
static int __devinit i8042_probe(struct platform_device *dev)
{
int error;
- char param;
error = i8042_controller_selftest();
if (error)
@@ -1174,7 +1173,7 @@ static int __devinit i8042_probe(struct platform_device *dev)
}
#ifdef CONFIG_X86
if (i8042_dritek) {
- param = 0x90;
+ char param = 0x90;
error = i8042_command(&param, 0x1059);
if (error)
goto out_fail;
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
index c972e5d03a3..cbc1beb6657 100644
--- a/drivers/input/serio/i8042.h
+++ b/drivers/input/serio/i8042.h
@@ -18,6 +18,8 @@
#include "i8042-jazzio.h"
#elif defined(CONFIG_SGI_HAS_I8042)
#include "i8042-ip22io.h"
+#elif defined(CONFIG_SNI_RM)
+#include "i8042-snirm.h"
#elif defined(CONFIG_PPC)
#include "i8042-ppcio.h"
#elif defined(CONFIG_SPARC)
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h
index 6542edb6f76..acf9830698c 100644
--- a/drivers/input/tablet/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -11,7 +11,7 @@
* Copyright (c) 2000 Daniel Egger <egger@suse.de>
* Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com>
* Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be>
- * Copyright (c) 2002-2007 Ping Cheng <pingc@wacom.com>
+ * Copyright (c) 2002-2008 Ping Cheng <pingc@wacom.com>
*
* ChangeLog:
* v0.1 (vp) - Initial release
@@ -65,6 +65,7 @@
* - and wacom_wac.c deals with Wacom specific code
* - Support Intuos3 4x6
* v1.47 (pc) - Added support for Bamboo
+ * v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX
*/
/*
@@ -85,7 +86,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.47"
+#define DRIVER_VERSION "v1.48"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
#define DRIVER_LICENSE "GPL"
@@ -125,6 +126,7 @@ extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac
extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
+extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
extern __u16 wacom_le16_to_cpu(unsigned char *data);
extern __u16 wacom_be16_to_cpu(unsigned char *data);
extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id);
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index d64b1ea136b..41caaef8e2d 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -171,6 +171,7 @@ void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) |
BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3);
input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
+ input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
}
void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
@@ -180,6 +181,11 @@ void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
}
+void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
+{
+ input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9);
+}
+
void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL);
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index fc03ba256f4..ffe33842143 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -163,7 +163,9 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
}
id = STYLUS_DEVICE_ID;
- if (data[1] & 0x80) { /* in prox */
+ if ((data[1] & 0x80) && ((data[1] & 0x07) || data[2] || data[3] || data[4]
+ || data[5] || data[6] || (data[7] & 0x07))) {
+ /* in prox and not a pad data */
switch ((data[1] >> 5) & 3) {
@@ -233,7 +235,6 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
if (data[7] & 0xf8) {
wacom_input_sync(wcombo); /* sync last event */
wacom->id[1] = 1;
- wacom->serial[1] = (data[7] & 0xf8);
wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);
@@ -252,10 +253,9 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
}
break;
case WACOM_MO:
- if ((data[7] & 0xf8) || (data[8] & 0x80)) {
+ if ((data[7] & 0xf8) || (data[8] & 0xff)) {
wacom_input_sync(wcombo); /* sync last event */
wacom->id[1] = 1;
- wacom->serial[1] = (data[7] & 0xf8);
wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
@@ -434,10 +434,12 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_key(wcombo, BTN_5, (data[6] & 0x02));
wacom_report_key(wcombo, BTN_6, (data[6] & 0x04));
wacom_report_key(wcombo, BTN_7, (data[6] & 0x08));
+ wacom_report_key(wcombo, BTN_8, (data[5] & 0x10));
+ wacom_report_key(wcombo, BTN_9, (data[6] & 0x10));
wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
- if((data[5] & 0x0f) | (data[6] & 0x0f) | (data[1] & 0x1f) |
+ if ((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) |
data[2] | (data[3] & 0x1f) | data[4])
wacom_report_key(wcombo, wacom->tool[1], 1);
else
@@ -481,13 +483,11 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
if (data[1] & 0x02) {
/* Rotation packet */
if (wacom->features->type >= INTUOS3S) {
- /* I3 marker pen rotation reported as wheel
- * due to valuator limitation
- */
+ /* I3 marker pen rotation */
t = (data[6] << 3) | ((data[7] >> 5) & 7);
t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
((t-1) / 2 + 450)) : (450 - t / 2) ;
- wacom_report_abs(wcombo, ABS_WHEEL, t);
+ wacom_report_abs(wcombo, ABS_Z, t);
} else {
/* 4D mouse rotation packet */
t = (data[6] << 3) | ((data[7] >> 5) & 7);
@@ -558,6 +558,7 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
case INTUOS3:
case INTUOS3L:
case CINTIQ:
+ case WACOM_BEE:
return (wacom_intuos_irq(wacom_wac, wcombo));
break;
default:
@@ -577,6 +578,8 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w
case GRAPHIRE:
input_dev_g(input_dev, wacom_wac);
break;
+ case WACOM_BEE:
+ input_dev_bee(input_dev, wacom_wac);
case INTUOS3:
case INTUOS3L:
case CINTIQ:
@@ -607,12 +610,15 @@ static struct wacom_features wacom_features[] = {
{ "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE },
{ "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 },
{ "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 },
+ { "Wacom BambooFun 4x5", 9, 14760, 9225, 511, 63, WACOM_MO },
+ { "Wacom BambooFun 6x8", 9, 21648, 13530, 511, 63, WACOM_MO },
{ "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE },
{ "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE },
{ "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE },
{ "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE },
- { "Wacom PenPartner2", 8, 3250, 2320, 255, 63, GRAPHIRE },
+ { "Wacom PenPartner2", 8, 3250, 2320, 511, 63, GRAPHIRE },
{ "Wacom Bamboo", 9, 14760, 9225, 511, 63, WACOM_MO },
+ { "Wacom Bamboo1", 8, 5104, 3712, 511, 63, GRAPHIRE },
{ "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS },
{ "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS },
{ "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS },
@@ -643,6 +649,7 @@ static struct wacom_features wacom_features[] = {
{ "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 },
{ "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S },
{ "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ },
+ { "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, WACOM_BEE },
{ "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS },
{ }
};
@@ -656,12 +663,15 @@ static struct usb_device_id wacom_ids[] = {
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x17) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x18) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x69) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) },
@@ -692,6 +702,7 @@ static struct usb_device_id wacom_ids[] = {
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
{ }
};
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index a302e229bb8..3342bc05847 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -25,6 +25,7 @@ enum {
INTUOS3,
INTUOS3L,
CINTIQ,
+ WACOM_BEE,
WACOM_MO,
MAX_TYPE
};
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 58934a40f5c..57a1c28bf12 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -213,7 +213,7 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
struct ads7846 *ts = dev_get_drvdata(dev);
struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL);
int status;
- int sample;
+ int uninitialized_var(sample);
int use_internal;
if (!req)
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 9cef6fcf587..d4ad6992f77 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -981,13 +981,13 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack)
}
-static __inline int
+static inline int
isdn_minor2drv(int minor)
{
return (dev->drvmap[minor]);
}
-static __inline int
+static inline int
isdn_minor2chan(int minor)
{
return (dev->chanmap[minor]);
diff --git a/drivers/isdn/i4l/isdn_v110.c b/drivers/isdn/i4l/isdn_v110.c
index 5484d3c38a5..c5d02b6aafa 100644
--- a/drivers/isdn/i4l/isdn_v110.c
+++ b/drivers/isdn/i4l/isdn_v110.c
@@ -62,7 +62,7 @@ static unsigned char V110_OffMatrix_38400[] =
* and to 67452301 when keylen = 2. This is necessary because ordering on
* the isdn line is the other way.
*/
-static __inline unsigned char
+static inline unsigned char
FlipBits(unsigned char c, int keylen)
{
unsigned char b = c;
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c
index 741a2e3f4fc..a348bb0791d 100644
--- a/drivers/macintosh/via-pmu-backlight.c
+++ b/drivers/macintosh/via-pmu-backlight.c
@@ -17,7 +17,7 @@
static struct backlight_ops pmu_backlight_data;
static DEFINE_SPINLOCK(pmu_backlight_lock);
-static int sleeping;
+static int sleeping, uses_pmu_bl;
static u8 bl_curve[FB_BACKLIGHT_LEVELS];
static void pmu_backlight_init_curve(u8 off, u8 min, u8 max)
@@ -128,7 +128,7 @@ void pmu_backlight_set_sleep(int sleep)
spin_lock_irqsave(&pmu_backlight_lock, flags);
sleeping = sleep;
- if (pmac_backlight) {
+ if (pmac_backlight && uses_pmu_bl) {
if (sleep) {
struct adb_request req;
@@ -166,6 +166,7 @@ void __init pmu_backlight_init()
printk(KERN_ERR "PMU Backlight registration failed\n");
return;
}
+ uses_pmu_bl = 1;
bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
pmu_backlight_init_curve(0x7F, 0x46, 0x0E);
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index ebec663d5d3..d6365a9f063 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -2528,7 +2528,7 @@ EXPORT_SYMBOL(pmu_wait_complete);
EXPORT_SYMBOL(pmu_suspend);
EXPORT_SYMBOL(pmu_resume);
EXPORT_SYMBOL(pmu_unlock);
-#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
+#if defined(CONFIG_PPC32)
EXPORT_SYMBOL(pmu_enable_irled);
EXPORT_SYMBOL(pmu_battery_count);
EXPORT_SYMBOL(pmu_batteries);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index ccbbf63727c..61ccbd2683f 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1864,17 +1864,6 @@ static struct rdev_sysfs_entry rdev_state =
__ATTR(state, S_IRUGO|S_IWUSR, state_show, state_store);
static ssize_t
-super_show(mdk_rdev_t *rdev, char *page)
-{
- if (rdev->sb_loaded && rdev->sb_size) {
- memcpy(page, page_address(rdev->sb_page), rdev->sb_size);
- return rdev->sb_size;
- } else
- return 0;
-}
-static struct rdev_sysfs_entry rdev_super = __ATTR_RO(super);
-
-static ssize_t
errors_show(mdk_rdev_t *rdev, char *page)
{
return sprintf(page, "%d\n", atomic_read(&rdev->corrected_errors));
@@ -2060,7 +2049,6 @@ __ATTR(size, S_IRUGO|S_IWUSR, rdev_size_show, rdev_size_store);
static struct attribute *rdev_default_attrs[] = {
&rdev_state.attr,
- &rdev_super.attr,
&rdev_errors.attr,
&rdev_slot.attr,
&rdev_offset.attr,
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 2d6f1a51359..c574cf5efb5 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1143,7 +1143,7 @@ static void raid5_end_read_request(struct bio * bi, int error)
rdev = conf->disks[i].rdev;
printk(KERN_INFO "raid5:%s: read error corrected (%lu sectors at %llu on %s)\n",
mdname(conf->mddev), STRIPE_SECTORS,
- (unsigned long long)sh->sector + rdev->data_offset,
+ (unsigned long long)(sh->sector + rdev->data_offset),
bdevname(rdev->bdev, b));
clear_bit(R5_ReadError, &sh->dev[i].flags);
clear_bit(R5_ReWrite, &sh->dev[i].flags);
@@ -1160,13 +1160,13 @@ static void raid5_end_read_request(struct bio * bi, int error)
if (conf->mddev->degraded)
printk(KERN_WARNING "raid5:%s: read error not correctable (sector %llu on %s).\n",
mdname(conf->mddev),
- (unsigned long long)sh->sector + rdev->data_offset,
+ (unsigned long long)(sh->sector + rdev->data_offset),
bdn);
else if (test_bit(R5_ReWrite, &sh->dev[i].flags))
/* Oh, no!!! */
printk(KERN_WARNING "raid5:%s: read error NOT corrected!! (sector %llu on %s).\n",
mdname(conf->mddev),
- (unsigned long long)sh->sector + rdev->data_offset,
+ (unsigned long long)(sh->sector + rdev->data_offset),
bdn);
else if (atomic_read(&rdev->read_errors)
> conf->max_nr_stripes)
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
index 21935bf7059..302cc67407c 100644
--- a/drivers/media/dvb/dvb-usb/opera1.c
+++ b/drivers/media/dvb/dvb-usb/opera1.c
@@ -478,9 +478,9 @@ static int opera1_xilinx_load_firmware(struct usb_device *dev,
err("could not restart the USB controller CPU.");
ret = -EINVAL;
}
- kfree(p);
}
}
+ kfree(p);
if (fw) {
release_firmware(fw);
}
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 37072a21d8c..1832966f53f 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -305,7 +305,7 @@ comment "MPEG video encoders"
config VIDEO_CX2341X
tristate "Conexant CX2341x MPEG encoders"
- depends on VIDEO_V4L2 && EXPERIMENTAL
+ depends on VIDEO_V4L2 && EXPERIMENTAL && VIDEO_V4L2_COMMON
---help---
Support for the Conexant CX23416 MPEG encoders
and CX23415 MPEG encoder/decoders.
@@ -382,7 +382,7 @@ endmenu # encoder / decoder chips
config VIDEO_VIVI
tristate "Virtual Video Driver"
- depends on VIDEO_V4L2 && !SPARC32 && !SPARC64
+ depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
select VIDEOBUF_VMALLOC
default n
---help---
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 5404fcc5276..a080c149cc6 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -3389,7 +3389,6 @@ static struct video_device bttv_video_template =
.vidiocgmbuf = vidiocgmbuf,
#endif
.vidioc_g_crop = bttv_g_crop,
- .vidioc_g_crop = bttv_g_crop,
.vidioc_s_crop = bttv_s_crop,
.vidioc_g_fbuf = bttv_g_fbuf,
.vidioc_s_fbuf = bttv_s_fbuf,
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index e6b7f518c56..8c9a8adf52d 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -2196,6 +2196,11 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
cx88_reset(core);
cx88_card_setup_pre_i2c(core);
cx88_i2c_init(core, pci);
+
+ /* load tuner module, if needed */
+ if (TUNER_ABSENT != core->board.tuner_type)
+ request_module("tuner");
+
cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
cx88_card_setup(core);
cx88_ir_init(core, pci);
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 7f1931aed20..227179620d1 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1826,8 +1826,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
cx_set(MO_PCI_INTMSK, core->pci_irqmask);
/* load and configure helper modules */
- if (TUNER_ABSENT != core->board.tuner_type)
- request_module("tuner");
if (core->board.audio_chip == AUDIO_CHIP_WM8775)
request_module("wm8775");
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 7d1537cab86..c1caaa855b9 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -267,7 +267,7 @@ static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val)
for (i = 0; i < 10; i++) {
if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
return ret;
- if (!((u8) ret) & 0x01)
+ if (!(ret & 0x01))
return 0;
msleep(5);
}
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index d42f120354e..948ca35e7ee 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -54,7 +54,6 @@
#include "ivtv-vbi.h"
#include "ivtv-routing.h"
#include "ivtv-gpio.h"
-#include "ivtv-yuv.h"
#include <media/tveeprom.h>
#include <media/saa7115.h>
@@ -700,6 +699,9 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced;
+ /* Init the sg table for osd/yuv output */
+ sg_init_table(itv->udma.SGlist, IVTV_DMA_SG_OSD_ENT);
+
/* OSD */
itv->osd_global_alpha_state = 1;
itv->osd_global_alpha = 255;
@@ -1053,9 +1055,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
goto free_io;
}
- /* Check yuv output filter table */
- if (itv->has_cx23415) ivtv_yuv_filter_check(itv);
-
ivtv_gpio_init(itv);
/* active i2c */
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c
index 425eb106390..6dba55b7e25 100644
--- a/drivers/media/video/ivtv/ivtv-firmware.c
+++ b/drivers/media/video/ivtv/ivtv-firmware.c
@@ -22,6 +22,7 @@
#include "ivtv-driver.h"
#include "ivtv-mailbox.h"
#include "ivtv-firmware.h"
+#include "ivtv-yuv.h"
#include <linux/firmware.h>
#define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE
@@ -225,11 +226,14 @@ int ivtv_firmware_init(struct ivtv *itv)
return 0;
itv->dec_mbox.mbox = ivtv_search_mailbox(itv->dec_mem, IVTV_DECODER_SIZE);
- if (itv->dec_mbox.mbox == NULL)
+ if (itv->dec_mbox.mbox == NULL) {
IVTV_ERR("Decoder mailbox not found\n");
- else if (itv->has_cx23415 && ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0)) {
+ } else if (itv->has_cx23415 && ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0)) {
IVTV_ERR("Decoder firmware dead!\n");
itv->dec_mbox.mbox = NULL;
+ } else {
+ /* Firmware okay, so check yuv output filter table */
+ ivtv_yuv_filter_check(itv);
}
return itv->dec_mbox.mbox ? 0 : -ENODEV;
}
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 262830da08c..6f5744286e8 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -2484,27 +2484,28 @@ struct saa7134_board saa7134_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.gpiomask = 0x080200000,
- .inputs = {{
- .name = name_tv,
- .vmux = 4,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 1,
- .amux = LINE2,
- },{
- .name = name_comp2,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
+ .inputs = { {
+ .name = name_tv,
+ .vmux = 4,
+ .amux = TV,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE2,
+ }, {
+ .name = name_comp2,
+ .vmux = 0,
+ .amux = LINE2,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ } },
.radio = {
- .name = name_radio,
- .amux = LINE1,
+ .name = name_radio,
+ .amux = TV,
+ .gpio = 0x0200000,
},
},
[SAA7134_BOARD_ASUSTeK_P7131_DUAL] = {
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 52baa4f7f7d..58ab163fdbd 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1022,12 +1022,13 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
saa7134_i2c_register(dev);
/* initialize hardware #2 */
+ if (TUNER_ABSENT != dev->tuner_type)
+ request_module("tuner");
saa7134_board_init2(dev);
+
saa7134_hwinit2(dev);
/* load i2c helpers */
- if (TUNER_ABSENT != dev->tuner_type)
- request_module("tuner");
if (card_is_empress(dev)) {
request_module("saa6752hs");
}
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 445eba4174d..d28318cb2b8 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -672,7 +672,7 @@ static int tvp5150_set_vbi(struct i2c_client *c,
if (std == V4L2_STD_ALL) {
tvp5150_err("VBI can't be configured without knowing number of lines\n");
return 0;
- } else if (std && V4L2_STD_625_50) {
+ } else if (std & V4L2_STD_625_50) {
/* Don't follow NTSC Line number convension */
line += 3;
}
@@ -719,7 +719,7 @@ static int tvp5150_get_vbi(struct i2c_client *c,
if (std == V4L2_STD_ALL) {
tvp5150_err("VBI can't be configured without knowing number of lines\n");
return 0;
- } else if (std && V4L2_STD_625_50) {
+ } else if (std & V4L2_STD_625_50) {
/* Don't follow NTSC Line number convension */
line += 3;
}
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c
index fb434b5602a..5d363be7bc7 100644
--- a/drivers/media/video/usbvideo/usbvideo.c
+++ b/drivers/media/video/usbvideo/usbvideo.c
@@ -1034,6 +1034,11 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd)
info("%s: iface=%d. endpoint=$%02x paletteBits=$%08lx",
__FUNCTION__, uvd->iface, uvd->video_endp, uvd->paletteBits);
}
+ if (uvd->dev == NULL) {
+ err("%s: uvd->dev == NULL", __FUNCTION__);
+ return -EINVAL;
+ }
+ uvd->vdev.dev=&(uvd->dev->dev);
if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
err("%s: video_register_device failed", __FUNCTION__);
return -EPIPE;
@@ -1041,10 +1046,6 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd)
if (uvd->debug > 1) {
info("%s: video_register_device() successful", __FUNCTION__);
}
- if (uvd->dev == NULL) {
- err("%s: uvd->dev == NULL", __FUNCTION__);
- return -EINVAL;
- }
info("%s on /dev/video%d: canvas=%s videosize=%s",
(uvd->handle != NULL) ? uvd->handle->drvName : "???",
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index dcf22a3b672..50e1ff9f2be 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -303,7 +303,11 @@ v4l_compat_translate_ioctl(struct inode *inode,
{
struct video_capability *cap = arg;
- cap2 = kzalloc(sizeof(*cap2),GFP_KERNEL);
+ cap2 = kzalloc(sizeof(*cap2), GFP_KERNEL);
+ if (!cap2) {
+ err = -ENOMEM;
+ break;
+ }
memset(cap, 0, sizeof(*cap));
memset(&fbuf2, 0, sizeof(fbuf2));
@@ -426,7 +430,11 @@ v4l_compat_translate_ioctl(struct inode *inode,
{
struct video_window *win = arg;
- fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
+ fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
+ if (!fmt2) {
+ err = -ENOMEM;
+ break;
+ }
memset(win,0,sizeof(*win));
fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
@@ -464,7 +472,11 @@ v4l_compat_translate_ioctl(struct inode *inode,
struct video_window *win = arg;
int err1,err2;
- fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
+ fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
+ if (!fmt2) {
+ err = -ENOMEM;
+ break;
+ }
fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
drv(inode, file, VIDIOC_STREAMOFF, &fmt2->type);
err1 = drv(inode, file, VIDIOC_G_FMT, fmt2);
@@ -586,6 +598,12 @@ v4l_compat_translate_ioctl(struct inode *inode,
{
struct video_picture *pict = arg;
+ fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
+ if (!fmt2) {
+ err = -ENOMEM;
+ break;
+ }
+
pict->brightness = get_v4l_control(inode, file,
V4L2_CID_BRIGHTNESS,drv);
pict->hue = get_v4l_control(inode, file,
@@ -597,7 +615,6 @@ v4l_compat_translate_ioctl(struct inode *inode,
pict->whiteness = get_v4l_control(inode, file,
V4L2_CID_WHITENESS, drv);
- fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
err = drv(inode, file, VIDIOC_G_FMT, fmt2);
if (err < 0) {
@@ -617,6 +634,11 @@ v4l_compat_translate_ioctl(struct inode *inode,
struct video_picture *pict = arg;
int mem_err = 0, ovl_err = 0;
+ fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
+ if (!fmt2) {
+ err = -ENOMEM;
+ break;
+ }
memset(&fbuf2, 0, sizeof(fbuf2));
set_v4l_control(inode, file,
@@ -636,7 +658,6 @@ v4l_compat_translate_ioctl(struct inode *inode,
* different pixel formats for memory vs overlay.
*/
- fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
err = drv(inode, file, VIDIOC_G_FMT, fmt2);
/* If VIDIOC_G_FMT failed, then the driver likely doesn't
@@ -890,7 +911,11 @@ v4l_compat_translate_ioctl(struct inode *inode,
{
struct video_mmap *mm = arg;
- fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
+ fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
+ if (!fmt2) {
+ err = -ENOMEM;
+ break;
+ }
memset(&buf2,0,sizeof(buf2));
fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -986,7 +1011,11 @@ v4l_compat_translate_ioctl(struct inode *inode,
{
struct vbi_format *fmt = arg;
- fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
+ fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
+ if (!fmt2) {
+ err = -ENOMEM;
+ break;
+ }
fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
err = drv(inode, file, VIDIOC_G_FMT, fmt2);
@@ -1018,8 +1047,11 @@ v4l_compat_translate_ioctl(struct inode *inode,
break;
}
- fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
-
+ fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
+ if (!fmt2) {
+ err = -ENOMEM;
+ break;
+ }
fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line;
fmt2->fmt.vbi.sampling_rate = fmt->sampling_rate;
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c
index de80dba12f9..946e3d3506a 100644
--- a/drivers/memstick/core/memstick.c
+++ b/drivers/memstick/core/memstick.c
@@ -276,8 +276,6 @@ void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc,
mrq->need_card_int = 1;
else
mrq->need_card_int = 0;
-
- mrq->get_int_reg = 0;
}
EXPORT_SYMBOL(memstick_init_req_sg);
@@ -311,8 +309,6 @@ void memstick_init_req(struct memstick_request *mrq, unsigned char tpc,
mrq->need_card_int = 1;
else
mrq->need_card_int = 0;
-
- mrq->get_int_reg = 0;
}
EXPORT_SYMBOL(memstick_init_req);
@@ -342,6 +338,7 @@ static int h_memstick_read_dev_id(struct memstick_dev *card,
card->id.class = id_reg.class;
}
complete(&card->mrq_complete);
+ dev_dbg(&card->dev, "if_mode = %02x\n", id_reg.if_mode);
return -EAGAIN;
}
}
@@ -422,7 +419,6 @@ static void memstick_power_on(struct memstick_host *host)
{
host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON);
host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_SERIAL);
- msleep(1);
}
static void memstick_check(struct work_struct *work)
@@ -579,7 +575,8 @@ EXPORT_SYMBOL(memstick_suspend_host);
void memstick_resume_host(struct memstick_host *host)
{
mutex_lock(&host->lock);
- host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON);
+ if (host->card)
+ memstick_power_on(host);
mutex_unlock(&host->lock);
memstick_detect_change(host);
}
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index 1d637e4561d..557dbbba5cb 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -133,6 +133,7 @@ struct mspro_devinfo {
struct mspro_block_data {
struct memstick_dev *card;
unsigned int usage_count;
+ unsigned int caps;
struct gendisk *disk;
struct request_queue *queue;
spinlock_t q_lock;
@@ -577,7 +578,6 @@ static int h_mspro_block_wait_for_ced(struct memstick_dev *card,
static int h_mspro_block_transfer_data(struct memstick_dev *card,
struct memstick_request **mrq)
{
- struct memstick_host *host = card->host;
struct mspro_block_data *msb = memstick_get_drvdata(card);
unsigned char t_val = 0;
struct scatterlist t_sg = { 0 };
@@ -591,12 +591,12 @@ static int h_mspro_block_transfer_data(struct memstick_dev *card,
switch ((*mrq)->tpc) {
case MS_TPC_WRITE_REG:
memstick_init_req(*mrq, MS_TPC_SET_CMD, &msb->transfer_cmd, 1);
- (*mrq)->get_int_reg = 1;
+ (*mrq)->need_card_int = 1;
return 0;
case MS_TPC_SET_CMD:
t_val = (*mrq)->int_reg;
memstick_init_req(*mrq, MS_TPC_GET_INT, NULL, 1);
- if (host->caps & MEMSTICK_CAP_AUTO_GET_INT)
+ if (msb->caps & MEMSTICK_CAP_AUTO_GET_INT)
goto has_int_reg;
return 0;
case MS_TPC_GET_INT:
@@ -646,12 +646,12 @@ has_int_reg:
? MS_TPC_READ_LONG_DATA
: MS_TPC_WRITE_LONG_DATA,
&t_sg);
- (*mrq)->get_int_reg = 1;
+ (*mrq)->need_card_int = 1;
return 0;
case MS_TPC_READ_LONG_DATA:
case MS_TPC_WRITE_LONG_DATA:
msb->current_page++;
- if (host->caps & MEMSTICK_CAP_AUTO_GET_INT) {
+ if (msb->caps & MEMSTICK_CAP_AUTO_GET_INT) {
t_val = (*mrq)->int_reg;
goto has_int_reg;
} else {
@@ -816,12 +816,13 @@ static int mspro_block_wait_for_ced(struct memstick_dev *card)
return card->current_mrq.error;
}
-static int mspro_block_switch_to_parallel(struct memstick_dev *card)
+static int mspro_block_set_interface(struct memstick_dev *card,
+ unsigned char sys_reg)
{
struct memstick_host *host = card->host;
struct mspro_block_data *msb = memstick_get_drvdata(card);
struct mspro_param_register param = {
- .system = MEMSTICK_SYS_PAR4,
+ .system = sys_reg,
.data_count = 0,
.data_address = 0,
.tpc_param = 0
@@ -833,41 +834,70 @@ static int mspro_block_switch_to_parallel(struct memstick_dev *card)
sizeof(param));
memstick_new_req(host);
wait_for_completion(&card->mrq_complete);
- if (card->current_mrq.error)
- return card->current_mrq.error;
+ return card->current_mrq.error;
+}
+
+static int mspro_block_switch_interface(struct memstick_dev *card)
+{
+ struct memstick_host *host = card->host;
+ struct mspro_block_data *msb = memstick_get_drvdata(card);
+ int rc = 0;
+
+ if (msb->caps & MEMSTICK_CAP_PAR4)
+ rc = mspro_block_set_interface(card, MEMSTICK_SYS_PAR4);
+ else
+ return 0;
+
+ if (rc) {
+ printk(KERN_WARNING
+ "%s: could not switch to 4-bit mode, error %d\n",
+ card->dev.bus_id, rc);
+ return 0;
+ }
msb->system = MEMSTICK_SYS_PAR4;
host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_PAR4);
+ printk(KERN_INFO "%s: switching to 4-bit parallel mode\n",
+ card->dev.bus_id);
+
+ if (msb->caps & MEMSTICK_CAP_PAR8) {
+ rc = mspro_block_set_interface(card, MEMSTICK_SYS_PAR8);
+
+ if (!rc) {
+ msb->system = MEMSTICK_SYS_PAR8;
+ host->set_param(host, MEMSTICK_INTERFACE,
+ MEMSTICK_PAR8);
+ printk(KERN_INFO
+ "%s: switching to 8-bit parallel mode\n",
+ card->dev.bus_id);
+ } else
+ printk(KERN_WARNING
+ "%s: could not switch to 8-bit mode, error %d\n",
+ card->dev.bus_id, rc);
+ }
card->next_request = h_mspro_block_req_init;
msb->mrq_handler = h_mspro_block_default;
memstick_init_req(&card->current_mrq, MS_TPC_GET_INT, NULL, 1);
memstick_new_req(card->host);
wait_for_completion(&card->mrq_complete);
+ rc = card->current_mrq.error;
- if (card->current_mrq.error) {
+ if (rc) {
+ printk(KERN_WARNING
+ "%s: interface error, trying to fall back to serial\n",
+ card->dev.bus_id);
msb->system = MEMSTICK_SYS_SERIAL;
host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF);
- msleep(1000);
+ msleep(10);
host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON);
host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_SERIAL);
- if (memstick_set_rw_addr(card))
- return card->current_mrq.error;
-
- param.system = msb->system;
-
- card->next_request = h_mspro_block_req_init;
- msb->mrq_handler = h_mspro_block_default;
- memstick_init_req(&card->current_mrq, MS_TPC_WRITE_REG, &param,
- sizeof(param));
- memstick_new_req(host);
- wait_for_completion(&card->mrq_complete);
-
- return -EFAULT;
+ rc = memstick_set_rw_addr(card);
+ if (!rc)
+ rc = mspro_block_set_interface(card, msb->system);
}
-
- return 0;
+ return rc;
}
/* Memory allocated for attributes by this function should be freed by
@@ -1052,16 +1082,18 @@ static int mspro_block_init_card(struct memstick_dev *card)
if (memstick_set_rw_addr(card))
return -EIO;
- if (host->caps & MEMSTICK_CAP_PAR4) {
- if (mspro_block_switch_to_parallel(card))
- printk(KERN_WARNING "%s: could not switch to "
- "parallel interface\n", card->dev.bus_id);
- }
+ msb->caps = host->caps;
+ rc = mspro_block_switch_interface(card);
+ if (rc)
+ return rc;
+ msleep(200);
rc = mspro_block_wait_for_ced(card);
if (rc)
return rc;
dev_dbg(&card->dev, "card activated\n");
+ if (msb->system != MEMSTICK_SYS_SERIAL)
+ msb->caps |= MEMSTICK_CAP_AUTO_GET_INT;
card->next_request = h_mspro_block_req_init;
msb->mrq_handler = h_mspro_block_get_ro;
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index 03fe8783b1e..8770a5fac3b 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -12,6 +12,7 @@
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
+#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/highmem.h>
#include <linux/memstick.h>
@@ -56,8 +57,6 @@ struct jmb38x_ms_host {
unsigned long timeout_jiffies;
struct timer_list timer;
struct memstick_request *req;
- unsigned char eject:1,
- use_dma:1;
unsigned char cmd_flags;
unsigned char io_pos;
unsigned int io_word[2];
@@ -94,9 +93,22 @@ struct jmb38x_ms {
#define HOST_CONTROL_IF_PAR4 0x1
#define HOST_CONTROL_IF_PAR8 0x3
+#define STATUS_BUSY 0x00080000
+#define STATUS_MS_DAT7 0x00040000
+#define STATUS_MS_DAT6 0x00020000
+#define STATUS_MS_DAT5 0x00010000
+#define STATUS_MS_DAT4 0x00008000
+#define STATUS_MS_DAT3 0x00004000
+#define STATUS_MS_DAT2 0x00002000
+#define STATUS_MS_DAT1 0x00001000
+#define STATUS_MS_DAT0 0x00000800
#define STATUS_HAS_MEDIA 0x00000400
#define STATUS_FIFO_EMPTY 0x00000200
#define STATUS_FIFO_FULL 0x00000100
+#define STATUS_MS_CED 0x00000080
+#define STATUS_MS_ERR 0x00000040
+#define STATUS_MS_BRQ 0x00000020
+#define STATUS_MS_CNK 0x00000001
#define INT_STATUS_TPC_ERR 0x00080000
#define INT_STATUS_CRC_ERR 0x00040000
@@ -119,11 +131,17 @@ struct jmb38x_ms {
#define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000
#define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000
+#define CLOCK_CONTROL_40MHZ 0x00000001
+#define CLOCK_CONTROL_50MHZ 0x00000002
+#define CLOCK_CONTROL_60MHZ 0x00000008
+#define CLOCK_CONTROL_62_5MHZ 0x0000000c
+#define CLOCK_CONTROL_OFF 0x00000000
+
enum {
CMD_READY = 0x01,
FIFO_READY = 0x02,
REG_DATA = 0x04,
- AUTO_GET_INT = 0x08
+ DMA_DATA = 0x08
};
static unsigned int jmb38x_ms_read_data(struct jmb38x_ms_host *host,
@@ -273,7 +291,7 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host)
{
unsigned int length;
unsigned int off;
- unsigned int t_size, p_off, p_cnt;
+ unsigned int t_size, p_cnt;
unsigned char *buf;
struct page *pg;
unsigned long flags = 0;
@@ -287,6 +305,8 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host)
}
while (length) {
+ unsigned int uninitialized_var(p_off);
+
if (host->req->long_data) {
pg = nth_page(sg_page(&host->req->sg),
off >> PAGE_SHIFT);
@@ -364,28 +384,27 @@ static int jmb38x_ms_issue_cmd(struct memstick_host *msh)
cmd |= TPC_DIR;
if (host->req->need_card_int)
cmd |= TPC_WAIT_INT;
- if (host->req->get_int_reg)
- cmd |= TPC_GET_INT;
data = host->req->data;
- host->use_dma = !no_dma;
+ if (!no_dma)
+ host->cmd_flags |= DMA_DATA;
if (host->req->long_data) {
data_len = host->req->sg.length;
} else {
data_len = host->req->data_len;
- host->use_dma = 0;
+ host->cmd_flags &= ~DMA_DATA;
}
if (data_len <= 8) {
cmd &= ~(TPC_DATA_SEL | 0xf);
host->cmd_flags |= REG_DATA;
cmd |= data_len & 0xf;
- host->use_dma = 0;
+ host->cmd_flags &= ~DMA_DATA;
}
- if (host->use_dma) {
+ if (host->cmd_flags & DMA_DATA) {
if (1 != pci_map_sg(host->chip->pdev, &host->req->sg, 1,
host->req->data_dir == READ
? PCI_DMA_FROMDEVICE
@@ -448,13 +467,12 @@ static void jmb38x_ms_complete_cmd(struct memstick_host *msh, int last)
readl(host->addr + INT_STATUS));
dev_dbg(msh->cdev.dev, "c hstatus %08x\n", readl(host->addr + STATUS));
- if (host->req->get_int_reg) {
- t_val = readl(host->addr + TPC_P0);
- host->req->int_reg = (t_val & 0xff);
- }
+ host->req->int_reg = readl(host->addr + STATUS) & 0xff;
+
+ writel(0, host->addr + BLOCK);
+ writel(0, host->addr + DMA_CONTROL);
- if (host->use_dma) {
- writel(0, host->addr + DMA_CONTROL);
+ if (host->cmd_flags & DMA_DATA) {
pci_unmap_sg(host->chip->pdev, &host->req->sg, 1,
host->req->data_dir == READ
? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
@@ -506,7 +524,7 @@ static irqreturn_t jmb38x_ms_isr(int irq, void *dev_id)
else
host->req->error = -ETIME;
} else {
- if (host->use_dma) {
+ if (host->cmd_flags & DMA_DATA) {
if (irq_status & INT_STATUS_EOTRAN)
host->cmd_flags |= FIFO_READY;
} else {
@@ -595,19 +613,18 @@ static void jmb38x_ms_reset(struct jmb38x_ms_host *host)
{
unsigned int host_ctl = readl(host->addr + HOST_CONTROL);
- writel(host_ctl | HOST_CONTROL_RESET_REQ | HOST_CONTROL_RESET,
- host->addr + HOST_CONTROL);
+ writel(HOST_CONTROL_RESET_REQ, host->addr + HOST_CONTROL);
while (HOST_CONTROL_RESET_REQ
& (host_ctl = readl(host->addr + HOST_CONTROL))) {
- ndelay(100);
- dev_dbg(&host->chip->pdev->dev, "reset\n");
+ ndelay(20);
+ dev_dbg(&host->chip->pdev->dev, "reset %08x\n", host_ctl);
}
- writel(INT_STATUS_ALL, host->addr + INT_STATUS_ENABLE);
+ writel(HOST_CONTROL_RESET, host->addr + HOST_CONTROL);
+ mmiowb();
writel(INT_STATUS_ALL, host->addr + INT_SIGNAL_ENABLE);
-
- dev_dbg(&host->chip->pdev->dev, "reset\n");
+ writel(INT_STATUS_ALL, host->addr + INT_STATUS_ENABLE);
}
static void jmb38x_ms_set_param(struct memstick_host *msh,
@@ -615,10 +632,8 @@ static void jmb38x_ms_set_param(struct memstick_host *msh,
int value)
{
struct jmb38x_ms_host *host = memstick_priv(msh);
- unsigned int host_ctl;
- unsigned long flags;
-
- spin_lock_irqsave(&host->lock, flags);
+ unsigned int host_ctl = readl(host->addr + HOST_CONTROL);
+ unsigned int clock_ctl = CLOCK_CONTROL_40MHZ, clock_delay = 0;
switch (param) {
case MEMSTICK_POWER:
@@ -626,60 +641,57 @@ static void jmb38x_ms_set_param(struct memstick_host *msh,
jmb38x_ms_reset(host);
writel(host->id ? PAD_PU_PD_ON_MS_SOCK1
- : PAD_PU_PD_ON_MS_SOCK0,
+ : PAD_PU_PD_ON_MS_SOCK0,
host->addr + PAD_PU_PD);
writel(PAD_OUTPUT_ENABLE_MS,
host->addr + PAD_OUTPUT_ENABLE);
- host_ctl = readl(host->addr + HOST_CONTROL);
- host_ctl |= 7;
- writel(host_ctl | (HOST_CONTROL_POWER_EN
- | HOST_CONTROL_CLOCK_EN),
- host->addr + HOST_CONTROL);
+ host_ctl = 7;
+ host_ctl |= HOST_CONTROL_POWER_EN
+ | HOST_CONTROL_CLOCK_EN;
+ writel(host_ctl, host->addr + HOST_CONTROL);
dev_dbg(&host->chip->pdev->dev, "power on\n");
} else if (value == MEMSTICK_POWER_OFF) {
- writel(readl(host->addr + HOST_CONTROL)
- & ~(HOST_CONTROL_POWER_EN
- | HOST_CONTROL_CLOCK_EN),
- host->addr + HOST_CONTROL);
+ host_ctl &= ~(HOST_CONTROL_POWER_EN
+ | HOST_CONTROL_CLOCK_EN);
+ writel(host_ctl, host->addr + HOST_CONTROL);
writel(0, host->addr + PAD_OUTPUT_ENABLE);
writel(PAD_PU_PD_OFF, host->addr + PAD_PU_PD);
dev_dbg(&host->chip->pdev->dev, "power off\n");
}
break;
case MEMSTICK_INTERFACE:
- /* jmb38x_ms_reset(host); */
-
- host_ctl = readl(host->addr + HOST_CONTROL);
host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT);
- /* host_ctl |= 7; */
if (value == MEMSTICK_SERIAL) {
host_ctl &= ~HOST_CONTROL_FAST_CLK;
host_ctl |= HOST_CONTROL_IF_SERIAL
<< HOST_CONTROL_IF_SHIFT;
host_ctl |= HOST_CONTROL_REI;
- writel(0, host->addr + CLOCK_DELAY);
+ clock_ctl = CLOCK_CONTROL_40MHZ;
+ clock_delay = 0;
} else if (value == MEMSTICK_PAR4) {
host_ctl |= HOST_CONTROL_FAST_CLK;
host_ctl |= HOST_CONTROL_IF_PAR4
<< HOST_CONTROL_IF_SHIFT;
host_ctl &= ~HOST_CONTROL_REI;
- writel(4, host->addr + CLOCK_DELAY);
+ clock_ctl = CLOCK_CONTROL_40MHZ;
+ clock_delay = 4;
} else if (value == MEMSTICK_PAR8) {
host_ctl |= HOST_CONTROL_FAST_CLK;
host_ctl |= HOST_CONTROL_IF_PAR8
<< HOST_CONTROL_IF_SHIFT;
host_ctl &= ~HOST_CONTROL_REI;
- writel(4, host->addr + CLOCK_DELAY);
+ clock_ctl = CLOCK_CONTROL_60MHZ;
+ clock_delay = 0;
}
writel(host_ctl, host->addr + HOST_CONTROL);
+ writel(clock_ctl, host->addr + CLOCK_CONTROL);
+ writel(clock_delay, host->addr + CLOCK_DELAY);
break;
};
-
- spin_unlock_irqrestore(&host->lock, flags);
}
#ifdef CONFIG_PM
@@ -772,13 +784,10 @@ static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt)
snprintf(host->host_id, DEVICE_ID_SIZE, DRIVER_NAME ":slot%d",
host->id);
host->irq = jm->pdev->irq;
- host->timeout_jiffies = msecs_to_jiffies(4000);
+ host->timeout_jiffies = msecs_to_jiffies(1000);
msh->request = jmb38x_ms_request;
msh->set_param = jmb38x_ms_set_param;
- /*
- msh->caps = MEMSTICK_CAP_AUTO_GET_INT | MEMSTICK_CAP_PAR4
- | MEMSTICK_CAP_PAR8;
- */
+
msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8;
setup_timer(&host->timer, jmb38x_ms_abort, (unsigned long)msh);
diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c
index 2b5bf52a830..eb150dfb637 100644
--- a/drivers/memstick/host/tifm_ms.c
+++ b/drivers/memstick/host/tifm_ms.c
@@ -340,11 +340,20 @@ static void tifm_ms_complete_cmd(struct tifm_ms *host)
del_timer(&host->timer);
- if (host->use_dma)
+ host->req->int_reg = readl(sock->addr + SOCK_MS_STATUS) & 0xff;
+ host->req->int_reg = (host->req->int_reg & 1)
+ | ((host->req->int_reg << 4) & 0xe0);
+
+ writel(TIFM_FIFO_INT_SETALL,
+ sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
+ writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
+
+ if (host->use_dma) {
tifm_unmap_sg(sock, &host->req->sg, 1,
host->req->data_dir == READ
? PCI_DMA_FROMDEVICE
: PCI_DMA_TODEVICE);
+ }
writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
sock->addr + SOCK_CONTROL);
@@ -424,12 +433,6 @@ static void tifm_ms_card_event(struct tifm_dev *sock)
else if (host_status & TIFM_MS_STAT_CRC)
host->req->error = -EILSEQ;
- if (host->req->error) {
- writel(TIFM_FIFO_INT_SETALL,
- sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
- writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
- }
-
if (host_status & TIFM_MS_STAT_RDY)
host->cmd_flags |= CMD_READY;
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 6b6df867958..c6be6eba7dc 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -1430,6 +1430,98 @@ mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
sprintf(prod_name, "%s", product_str);
}
+/**
+ * mpt_mapresources - map in memory mapped io
+ * @ioc: Pointer to pointer to IOC adapter
+ *
+ **/
+static int
+mpt_mapresources(MPT_ADAPTER *ioc)
+{
+ u8 __iomem *mem;
+ int ii;
+ unsigned long mem_phys;
+ unsigned long port;
+ u32 msize;
+ u32 psize;
+ u8 revision;
+ int r = -ENODEV;
+ struct pci_dev *pdev;
+
+ pdev = ioc->pcidev;
+ ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
+ if (pci_enable_device_mem(pdev)) {
+ printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
+ "failed\n", ioc->name);
+ return r;
+ }
+ if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
+ printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
+ "MEM failed\n", ioc->name);
+ return r;
+ }
+
+ pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
+
+ if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)
+ && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
+ dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
+ ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
+ ioc->name));
+ } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)
+ && !pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+ dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
+ ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
+ ioc->name));
+ } else {
+ printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
+ ioc->name, pci_name(pdev));
+ pci_release_selected_regions(pdev, ioc->bars);
+ return r;
+ }
+
+ mem_phys = msize = 0;
+ port = psize = 0;
+ for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
+ if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
+ if (psize)
+ continue;
+ /* Get I/O space! */
+ port = pci_resource_start(pdev, ii);
+ psize = pci_resource_len(pdev, ii);
+ } else {
+ if (msize)
+ continue;
+ /* Get memmap */
+ mem_phys = pci_resource_start(pdev, ii);
+ msize = pci_resource_len(pdev, ii);
+ }
+ }
+ ioc->mem_size = msize;
+
+ mem = NULL;
+ /* Get logical ptr for PciMem0 space */
+ /*mem = ioremap(mem_phys, msize);*/
+ mem = ioremap(mem_phys, msize);
+ if (mem == NULL) {
+ printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
+ " memory!\n", ioc->name);
+ return -EINVAL;
+ }
+ ioc->memmap = mem;
+ dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n",
+ ioc->name, mem, mem_phys));
+
+ ioc->mem_phys = mem_phys;
+ ioc->chip = (SYSIF_REGS __iomem *)mem;
+
+ /* Save Port IO values in case we need to do downloadboot */
+ ioc->pio_mem_phys = port;
+ ioc->pio_chip = (SYSIF_REGS __iomem *)port;
+
+ return 0;
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_attach - Install a PCI intelligent MPT adapter.
@@ -1452,13 +1544,6 @@ int
mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
{
MPT_ADAPTER *ioc;
- u8 __iomem *mem;
- u8 __iomem *pmem;
- unsigned long mem_phys;
- unsigned long port;
- u32 msize;
- u32 psize;
- int ii;
u8 cb_idx;
int r = -ENODEV;
u8 revision;
@@ -1468,52 +1553,32 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
struct proc_dir_entry *dent, *ent;
#endif
- if (mpt_debug_level)
- printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level);
-
ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
if (ioc == NULL) {
printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
return -ENOMEM;
}
- ioc->debug_level = mpt_debug_level;
+
ioc->id = mpt_ids++;
sprintf(ioc->name, "ioc%d", ioc->id);
- ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
- if (pci_enable_device_mem(pdev)) {
- printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
- "failed\n", ioc->name);
- kfree(ioc);
- return r;
- }
- if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
- printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
- "MEM failed\n", ioc->name);
- kfree(ioc);
- return r;
- }
+ /*
+ * set initial debug level
+ * (refer to mptdebug.h)
+ *
+ */
+ ioc->debug_level = mpt_debug_level;
+ if (mpt_debug_level)
+ printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
- dprintk(ioc, printk(MYIOC_s_INFO_FMT
- ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", ioc->name));
- } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
- printk(MYIOC_s_WARN_FMT ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n",
- ioc->name);
+ ioc->pcidev = pdev;
+ if (mpt_mapresources(ioc)) {
kfree(ioc);
return r;
}
- if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
- dprintk(ioc, printk(MYIOC_s_INFO_FMT
- ": Using 64 bit consistent mask\n", ioc->name));
- } else {
- dprintk(ioc, printk(MYIOC_s_INFO_FMT
- ": Not using 64 bit consistent mask\n", ioc->name));
- }
-
ioc->alloc_total = sizeof(MPT_ADAPTER);
ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
@@ -1551,48 +1616,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
/* Find lookup slot. */
INIT_LIST_HEAD(&ioc->list);
- mem_phys = msize = 0;
- port = psize = 0;
- for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
- if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
- if (psize)
- continue;
- /* Get I/O space! */
- port = pci_resource_start(pdev, ii);
- psize = pci_resource_len(pdev,ii);
- } else {
- if (msize)
- continue;
- /* Get memmap */
- mem_phys = pci_resource_start(pdev, ii);
- msize = pci_resource_len(pdev,ii);
- }
- }
- ioc->mem_size = msize;
-
- mem = NULL;
- /* Get logical ptr for PciMem0 space */
- /*mem = ioremap(mem_phys, msize);*/
- mem = ioremap(mem_phys, msize);
- if (mem == NULL) {
- printk(MYIOC_s_ERR_FMT "Unable to map adapter memory!\n", ioc->name);
- kfree(ioc);
- return -EINVAL;
- }
- ioc->memmap = mem;
- dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n", ioc->name, mem, mem_phys));
-
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
ioc->name, &ioc->facts, &ioc->pfacts[0]));
- ioc->mem_phys = mem_phys;
- ioc->chip = (SYSIF_REGS __iomem *)mem;
-
- /* Save Port IO values in case we need to do downloadboot */
- ioc->pio_mem_phys = port;
- pmem = (u8 __iomem *)port;
- ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
-
pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
@@ -1688,7 +1714,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
list_del(&ioc->list);
if (ioc->alt_ioc)
ioc->alt_ioc->alt_ioc = NULL;
- iounmap(mem);
+ iounmap(ioc->memmap);
+ if (r != -5)
+ pci_release_selected_regions(pdev, ioc->bars);
kfree(ioc);
pci_set_drvdata(pdev, NULL);
return r;
@@ -1784,13 +1812,10 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state)
u32 device_state;
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
- device_state=pci_choose_state(pdev, state);
-
- printk(MYIOC_s_INFO_FMT
- "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
- ioc->name, pdev, pci_name(pdev), device_state);
-
- pci_save_state(pdev);
+ device_state = pci_choose_state(pdev, state);
+ printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
+ "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
+ device_state);
/* put ioc into READY_STATE */
if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
@@ -1805,10 +1830,14 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state)
/* Clear any lingering interrupt */
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ free_irq(ioc->pci_irq, ioc);
+ if (mpt_msi_enable)
+ pci_disable_msi(ioc->pcidev);
+ ioc->pci_irq = -1;
+ pci_save_state(pdev);
pci_disable_device(pdev);
pci_release_selected_regions(pdev, ioc->bars);
pci_set_power_state(pdev, device_state);
-
return 0;
}
@@ -1823,48 +1852,54 @@ mpt_resume(struct pci_dev *pdev)
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
u32 device_state = pdev->current_state;
int recovery_state;
+ int err;
- printk(MYIOC_s_INFO_FMT
- "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
- ioc->name, pdev, pci_name(pdev), device_state);
+ printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
+ "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
+ device_state);
- pci_set_power_state(pdev, 0);
+ pci_set_power_state(pdev, PCI_D0);
+ pci_enable_wake(pdev, PCI_D0, 0);
pci_restore_state(pdev);
- if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) {
- ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
- IORESOURCE_IO);
- if (pci_enable_device(pdev))
- return 0;
- } else {
- ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
- if (pci_enable_device_mem(pdev))
- return 0;
- }
- if (pci_request_selected_regions(pdev, ioc->bars, "mpt"))
- return 0;
+ ioc->pcidev = pdev;
+ err = mpt_mapresources(ioc);
+ if (err)
+ return err;
- /* enable interrupts */
- CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
- ioc->active = 1;
+ printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
+ ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
+ CHIPREG_READ32(&ioc->chip->Doorbell));
- printk(MYIOC_s_INFO_FMT
- "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
- ioc->name,
- (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
- CHIPREG_READ32(&ioc->chip->Doorbell));
+ /*
+ * Errata workaround for SAS pci express:
+ * Upon returning to the D0 state, the contents of the doorbell will be
+ * stale data, and this will incorrectly signal to the host driver that
+ * the firmware is ready to process mpt commands. The workaround is
+ * to issue a diagnostic reset.
+ */
+ if (ioc->bus_type == SAS && (pdev->device ==
+ MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
+ MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
+ if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
+ printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
+ ioc->name);
+ goto out;
+ }
+ }
/* bring ioc to operational state */
- if ((recovery_state = mpt_do_ioc_recovery(ioc,
- MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
- printk(MYIOC_s_INFO_FMT
- "pci-resume: Cannot recover, error:[%x]\n",
- ioc->name, recovery_state);
- } else {
+ printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
+ recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
+ CAN_SLEEP);
+ if (recovery_state != 0)
+ printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
+ "error:[%x]\n", ioc->name, recovery_state);
+ else
printk(MYIOC_s_INFO_FMT
- "pci-resume: success\n", ioc->name);
- }
-
+ "pci-resume: success\n", ioc->name);
+ out:
return 0;
+
}
#endif
@@ -1903,6 +1938,7 @@ mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
* -3 if READY but PrimeIOCFifos Failed
* -4 if READY but IOCInit Failed
* -5 if failed to enable_device and/or request_selected_regions
+ * -6 if failed to upload firmware
*/
static int
mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
@@ -2097,7 +2133,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
} else {
printk(MYIOC_s_WARN_FMT
"firmware upload failure!\n", ioc->name);
- ret = -5;
+ ret = -6;
}
}
}
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 0c252f60c4c..c207bda6723 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1170,6 +1170,10 @@ mptscsih_shutdown(struct pci_dev *pdev)
int
mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
{
+ MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
+
+ scsi_block_requests(ioc->sh);
+ flush_scheduled_work();
mptscsih_shutdown(pdev);
return mpt_suspend(pdev,state);
}
@@ -1183,7 +1187,12 @@ mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
int
mptscsih_resume(struct pci_dev *pdev)
{
- return mpt_resume(pdev);
+ MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
+ int rc;
+
+ rc = mpt_resume(pdev);
+ scsi_unblock_requests(ioc->sh);
+ return rc;
}
#endif
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 982e27b86d1..962817e49fb 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -108,6 +108,7 @@ config ACER_WMI
depends on ACPI
depends on LEDS_CLASS
depends on BACKLIGHT_CLASS_DEVICE
+ depends on SERIO_I8042
select ACPI_WMI
---help---
This is a driver for newer Acer (and Wistron) laptops. It adds
diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c
index 74d12b4a3ab..dd13a374992 100644
--- a/drivers/misc/acer-wmi.c
+++ b/drivers/misc/acer-wmi.c
@@ -219,6 +219,15 @@ static struct dmi_system_id acer_quirks[] = {
},
{
.callback = dmi_matched,
+ .ident = "Acer Aspire 3610",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3610"),
+ },
+ .driver_data = &quirk_acer_travelmate_2490,
+ },
+ {
+ .callback = dmi_matched,
.ident = "Acer Aspire 5100",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -228,6 +237,15 @@ static struct dmi_system_id acer_quirks[] = {
},
{
.callback = dmi_matched,
+ .ident = "Acer Aspire 5610",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
+ },
+ .driver_data = &quirk_acer_travelmate_2490,
+ },
+ {
+ .callback = dmi_matched,
.ident = "Acer Aspire 5630",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -761,11 +779,11 @@ enum led_brightness value)
}
static struct led_classdev mail_led = {
- .name = "acer-mail:green",
+ .name = "acer-wmi::mail",
.brightness_set = mail_led_set,
};
-static int __init acer_led_init(struct device *dev)
+static int __devinit acer_led_init(struct device *dev)
{
return led_classdev_register(dev, &mail_led);
}
@@ -798,7 +816,7 @@ static struct backlight_ops acer_bl_ops = {
.update_status = update_bl_status,
};
-static int __init acer_backlight_init(struct device *dev)
+static int __devinit acer_backlight_init(struct device *dev)
{
struct backlight_device *bd;
@@ -817,7 +835,7 @@ static int __init acer_backlight_init(struct device *dev)
return 0;
}
-static void __exit acer_backlight_exit(void)
+static void acer_backlight_exit(void)
{
backlight_device_unregister(acer_backlight_device);
}
@@ -1052,11 +1070,12 @@ static int __init acer_wmi_init(void)
if (wmi_has_guid(WMID_GUID2) && interface) {
if (ACPI_FAILURE(WMID_set_capabilities())) {
- printk(ACER_ERR "Unable to detect available devices\n");
+ printk(ACER_ERR "Unable to detect available WMID "
+ "devices\n");
return -ENODEV;
}
} else if (!wmi_has_guid(WMID_GUID2) && interface) {
- printk(ACER_ERR "Unable to detect available devices\n");
+ printk(ACER_ERR "No WMID device detection method found\n");
return -ENODEV;
}
@@ -1064,21 +1083,20 @@ static int __init acer_wmi_init(void)
interface = &AMW0_interface;
if (ACPI_FAILURE(AMW0_set_capabilities())) {
- printk(ACER_ERR "Unable to detect available devices\n");
+ printk(ACER_ERR "Unable to detect available AMW0 "
+ "devices\n");
return -ENODEV;
}
}
- if (wmi_has_guid(AMW0_GUID1)) {
- if (ACPI_FAILURE(AMW0_find_mailled()))
- printk(ACER_ERR "Unable to detect mail LED\n");
- }
+ if (wmi_has_guid(AMW0_GUID1))
+ AMW0_find_mailled();
find_quirks();
if (!interface) {
- printk(ACER_ERR "No or unsupported WMI interface, unable to ");
- printk(KERN_CONT "load.\n");
+ printk(ACER_ERR "No or unsupported WMI interface, unable to "
+ "load\n");
return -ENODEV;
}
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index 899e3f75f28..02ff3d19b1c 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -315,7 +315,7 @@ static void sony_laptop_report_input_event(u8 event)
break;
default:
- if (event > ARRAY_SIZE(sony_laptop_input_index)) {
+ if (event >= ARRAY_SIZE(sony_laptop_input_index)) {
dprintk("sony_laptop_report_input_event, event not known: %d\n", event);
break;
}
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index 20d5c7bd940..1c14a186f00 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -180,7 +180,7 @@ static void tifm_sd_transfer_data(struct tifm_sd *host)
host->sg_pos++;
if (host->sg_pos == host->sg_len) {
if ((r_data->flags & MMC_DATA_WRITE)
- && DATA_CARRY)
+ && (host->cmd_flags & DATA_CARRY))
writel(host->bounce_buf_data[0],
host->dev->addr
+ SOCK_MMCSD_DATA);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index a0f0e605d63..fe7b5ec0970 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2366,15 +2366,15 @@ config GELIC_NET
module will be called ps3_gelic.
config GELIC_WIRELESS
- bool "PS3 Wireless support"
- depends on GELIC_NET
- select WIRELESS_EXT
- help
- This option adds the support for the wireless feature of PS3.
- If you have the wireless-less model of PS3 or have no plan to
- use wireless feature, disabling this option saves memory. As
- the driver automatically distinguishes the models, you can
- safely enable this option even if you have a wireless-less model.
+ bool "PS3 Wireless support"
+ depends on GELIC_NET
+ select WIRELESS_EXT
+ help
+ This option adds the support for the wireless feature of PS3.
+ If you have the wireless-less model of PS3 or have no plan to
+ use wireless feature, disabling this option saves memory. As
+ the driver automatically distinguishes the models, you can
+ safely enable this option even if you have a wireless-less model.
config GIANFAR
tristate "Gianfar Ethernet"
@@ -2519,7 +2519,7 @@ config CHELSIO_T3
config EHEA
tristate "eHEA Ethernet support"
- depends on IBMEBUS && INET
+ depends on IBMEBUS && INET && SPARSEMEM
select INET_LRO
---help---
This driver supports the IBM pSeries eHEA ethernet adapter.
diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c
index 5136d94923a..b1448637107 100644
--- a/drivers/net/ac3200.c
+++ b/drivers/net/ac3200.c
@@ -369,7 +369,7 @@ MODULE_PARM_DESC(mem, "Memory base address(es)");
MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver");
MODULE_LICENSE("GPL");
-int __init init_module(void)
+static int __init ac3200_module_init(void)
{
struct net_device *dev;
int this_dev, found = 0;
@@ -404,8 +404,7 @@ static void cleanup_card(struct net_device *dev)
iounmap(ei_status.mem);
}
-void __exit
-cleanup_module(void)
+static void __exit ac3200_module_exit(void)
{
int this_dev;
@@ -418,4 +417,6 @@ cleanup_module(void)
}
}
}
+module_init(ac3200_module_init);
+module_exit(ac3200_module_exit);
#endif /* MODULE */
diff --git a/drivers/net/apne.c b/drivers/net/apne.c
index c12cbdf368b..47a8275d396 100644
--- a/drivers/net/apne.c
+++ b/drivers/net/apne.c
@@ -569,7 +569,7 @@ static irqreturn_t apne_interrupt(int irq, void *dev_id)
#ifdef MODULE
static struct net_device *apne_dev;
-int __init init_module(void)
+static int __init apne_module_init(void)
{
apne_dev = apne_probe(-1);
if (IS_ERR(apne_dev))
@@ -577,7 +577,7 @@ int __init init_module(void)
return 0;
}
-void __exit cleanup_module(void)
+static void __exit apne_module_exit(void)
{
unregister_netdev(apne_dev);
@@ -591,7 +591,8 @@ void __exit cleanup_module(void)
free_netdev(apne_dev);
}
-
+module_init(apne_module_init);
+module_exit(apne_module_exit);
#endif
static int init_pcmcia(void)
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
index 6ab2c2d4d67..fef5560bc7a 100644
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -1252,7 +1252,7 @@ module_param(irq, int, 0);
module_param(dma, int, 0);
-int __init init_module(void)
+static int __init ltpc_module_init(void)
{
if(io == 0)
printk(KERN_NOTICE
@@ -1263,6 +1263,7 @@ int __init init_module(void)
return PTR_ERR(dev_ltpc);
return 0;
}
+module_init(ltpc_module_init);
#endif
static void __exit ltpc_cleanup(void)
diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c
index cc4610db639..02cb8f1c114 100644
--- a/drivers/net/arcnet/capmode.c
+++ b/drivers/net/arcnet/capmode.c
@@ -80,17 +80,19 @@ void arcnet_cap_init(void)
#ifdef MODULE
-int __init init_module(void)
+static int __init capmode_module_init(void)
{
printk(VERSION);
arcnet_cap_init();
return 0;
}
-void cleanup_module(void)
+static void __exit capmode_module_exit(void)
{
arcnet_unregister_proto(&capmode_proto);
}
+module_init(capmode_module_init);
+module_exit(capmode_module_exit);
MODULE_LICENSE("GPL");
#endif /* MODULE */
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c
index b74dbeef805..13c293b286d 100644
--- a/drivers/net/atarilance.c
+++ b/drivers/net/atarilance.c
@@ -336,8 +336,6 @@ struct lance_addr {
/***************************** Prototypes *****************************/
-static int addr_accessible( volatile void *regp, int wordflag, int
- writeflag );
static unsigned long lance_probe1( struct net_device *dev, struct lance_addr
*init_rec );
static int lance_open( struct net_device *dev );
@@ -406,7 +404,8 @@ struct net_device * __init atarilance_probe(int unit)
/* Derived from hwreg_present() in atari/config.c: */
-static int __init addr_accessible( volatile void *regp, int wordflag, int writeflag )
+static noinline int __init addr_accessible(volatile void *regp, int wordflag,
+ int writeflag)
{
int ret;
long flags;
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 36ba6dc96ac..cdf3090a188 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -2782,16 +2782,13 @@ static void __devexit e100_remove(struct pci_dev *pdev)
}
}
-#ifdef CONFIG_PM
static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct nic *nic = netdev_priv(netdev);
if (netif_running(netdev))
- napi_disable(&nic->napi);
- del_timer_sync(&nic->watchdog);
- netif_carrier_off(nic->netdev);
+ e100_down(nic);
netif_device_detach(netdev);
pci_save_state(pdev);
@@ -2804,14 +2801,13 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
pci_enable_wake(pdev, PCI_D3cold, 0);
}
- free_irq(pdev->irq, netdev);
-
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
return 0;
}
+#ifdef CONFIG_PM
static int e100_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
@@ -2832,26 +2828,7 @@ static int e100_resume(struct pci_dev *pdev)
static void e100_shutdown(struct pci_dev *pdev)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct nic *nic = netdev_priv(netdev);
-
- if (netif_running(netdev))
- napi_disable(&nic->napi);
- del_timer_sync(&nic->watchdog);
- netif_carrier_off(nic->netdev);
-
- if ((nic->flags & wol_magic) | e100_asf(nic)) {
- pci_enable_wake(pdev, PCI_D3hot, 1);
- pci_enable_wake(pdev, PCI_D3cold, 1);
- } else {
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
- }
-
- free_irq(pdev->irq, netdev);
-
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
+ e100_suspend(pdev, PMSG_SUSPEND);
}
/* ------------------ PCI Error Recovery infrastructure -------------- */
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
index 0809a6a5a28..46a90e9ec56 100644
--- a/drivers/net/enc28j60.c
+++ b/drivers/net/enc28j60.c
@@ -900,7 +900,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
if (RSV_GETBIT(rxstat, RSV_LENCHECKERR))
ndev->stats.rx_frame_errors++;
} else {
- skb = dev_alloc_skb(len);
+ skb = dev_alloc_skb(len + NET_IP_ALIGN);
if (!skb) {
if (netif_msg_rx_err(priv))
dev_err(&ndev->dev,
@@ -908,6 +908,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
ndev->stats.rx_dropped++;
} else {
skb->dev = ndev;
+ skb_reserve(skb, NET_IP_ALIGN);
/* copy the packet from the receive buffer */
enc28j60_mem_read(priv, priv->next_pk_ptr + sizeof(rsv),
len, skb_put(skb, len));
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 23d0a4afe0e..c2095ce531c 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -2133,7 +2133,7 @@ static void ixgbe_watchdog(unsigned long data)
(link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
"10 Gbps" :
(link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
- "1 Gpbs" : "unknown speed")),
+ "1 Gbps" : "unknown speed")),
((FLOW_RX && FLOW_TX) ? "RX/TX" :
(FLOW_RX ? "RX" :
(FLOW_TX ? "TX" : "None"))));
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index b528ce77c40..771139e283a 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -2104,6 +2104,7 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR( "Rabeeh Khoury, Assaf Hoffman, Matthew Dharm, Manish Lachwani"
" and Dale Farnsworth");
MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX");
+MODULE_ALIAS("platform:mv643xx_eth");
/*
* The second part is the low level driver of the gigE ethernet ports.
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index e8a63e483a2..ce95c5d168f 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -1268,7 +1268,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
}
}
- if (interrupts && ei_debug)
+ if (interrupts && ei_debug > 3)
{
handled = 1;
if (nr_serviced >= MAX_SERVICE)
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index f4ca0591231..3ac8529bb92 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -67,6 +67,7 @@ config REALTEK_PHY
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
+ depends on PHYLIB=y
---help---
Adds the platform "fixed" MDIO Bus to cover the boards that use
PHYs that are not connected to the real MDIO bus.
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c
index 7ed632db00d..d926168bc78 100644
--- a/drivers/net/phy/davicom.c
+++ b/drivers/net/phy/davicom.c
@@ -37,6 +37,7 @@
#define MII_DM9161_SCR 0x10
#define MII_DM9161_SCR_INIT 0x0610
+#define MII_DM9161_SCR_RMII 0x0100
/* DM9161 Interrupt Register */
#define MII_DM9161_INTR 0x15
@@ -103,7 +104,7 @@ static int dm9161_config_aneg(struct phy_device *phydev)
static int dm9161_config_init(struct phy_device *phydev)
{
- int err;
+ int err, temp;
/* Isolate the PHY */
err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE);
@@ -111,9 +112,19 @@ static int dm9161_config_init(struct phy_device *phydev)
if (err < 0)
return err;
- /* Do not bypass the scrambler/descrambler */
- err = phy_write(phydev, MII_DM9161_SCR, MII_DM9161_SCR_INIT);
+ switch (phydev->interface) {
+ case PHY_INTERFACE_MODE_MII:
+ temp = MII_DM9161_SCR_INIT;
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ temp = MII_DM9161_SCR_INIT | MII_DM9161_SCR_RMII;
+ break;
+ default:
+ return -EINVAL;
+ }
+ /* Do not bypass the scrambler/descrambler */
+ err = phy_write(phydev, MII_DM9161_SCR, temp);
if (err < 0)
return err;
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index 86e5dba079f..3d10ca050b7 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -302,14 +302,14 @@ pppol2tp_session_find(struct pppol2tp_tunnel *tunnel, u16 session_id)
struct pppol2tp_session *session;
struct hlist_node *walk;
- read_lock(&tunnel->hlist_lock);
+ read_lock_bh(&tunnel->hlist_lock);
hlist_for_each_entry(session, walk, session_list, hlist) {
if (session->tunnel_addr.s_session == session_id) {
- read_unlock(&tunnel->hlist_lock);
+ read_unlock_bh(&tunnel->hlist_lock);
return session;
}
}
- read_unlock(&tunnel->hlist_lock);
+ read_unlock_bh(&tunnel->hlist_lock);
return NULL;
}
@@ -320,14 +320,14 @@ static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id)
{
struct pppol2tp_tunnel *tunnel = NULL;
- read_lock(&pppol2tp_tunnel_list_lock);
+ read_lock_bh(&pppol2tp_tunnel_list_lock);
list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) {
if (tunnel->stats.tunnel_id == tunnel_id) {
- read_unlock(&pppol2tp_tunnel_list_lock);
+ read_unlock_bh(&pppol2tp_tunnel_list_lock);
return tunnel;
}
}
- read_unlock(&pppol2tp_tunnel_list_lock);
+ read_unlock_bh(&pppol2tp_tunnel_list_lock);
return NULL;
}
@@ -342,10 +342,11 @@ static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id)
static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_buff *skb)
{
struct sk_buff *skbp;
+ struct sk_buff *tmp;
u16 ns = PPPOL2TP_SKB_CB(skb)->ns;
- spin_lock(&session->reorder_q.lock);
- skb_queue_walk(&session->reorder_q, skbp) {
+ spin_lock_bh(&session->reorder_q.lock);
+ skb_queue_walk_safe(&session->reorder_q, skbp, tmp) {
if (PPPOL2TP_SKB_CB(skbp)->ns > ns) {
__skb_insert(skb, skbp->prev, skbp, &session->reorder_q);
PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
@@ -360,7 +361,7 @@ static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_
__skb_queue_tail(&session->reorder_q, skb);
out:
- spin_unlock(&session->reorder_q.lock);
+ spin_unlock_bh(&session->reorder_q.lock);
}
/* Dequeue a single skb.
@@ -371,10 +372,9 @@ static void pppol2tp_recv_dequeue_skb(struct pppol2tp_session *session, struct s
int length = PPPOL2TP_SKB_CB(skb)->length;
struct sock *session_sock = NULL;
- /* We're about to requeue the skb, so unlink it and return resources
+ /* We're about to requeue the skb, so return resources
* to its current owner (a socket receive buffer).
*/
- skb_unlink(skb, &session->reorder_q);
skb_orphan(skb);
tunnel->stats.rx_packets++;
@@ -442,7 +442,7 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session)
* expect to send up next, dequeue it and any other
* in-sequence packets behind it.
*/
- spin_lock(&session->reorder_q.lock);
+ spin_lock_bh(&session->reorder_q.lock);
skb_queue_walk_safe(&session->reorder_q, skb, tmp) {
if (time_after(jiffies, PPPOL2TP_SKB_CB(skb)->expires)) {
session->stats.rx_seq_discards++;
@@ -470,13 +470,18 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session)
goto out;
}
}
- spin_unlock(&session->reorder_q.lock);
+ __skb_unlink(skb, &session->reorder_q);
+
+ /* Process the skb. We release the queue lock while we
+ * do so to let other contexts process the queue.
+ */
+ spin_unlock_bh(&session->reorder_q.lock);
pppol2tp_recv_dequeue_skb(session, skb);
- spin_lock(&session->reorder_q.lock);
+ spin_lock_bh(&session->reorder_q.lock);
}
out:
- spin_unlock(&session->reorder_q.lock);
+ spin_unlock_bh(&session->reorder_q.lock);
}
/* Internal receive frame. Do the real work of receiving an L2TP data frame
@@ -1059,7 +1064,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
/* Get routing info from the tunnel socket */
dst_release(skb->dst);
- skb->dst = sk_dst_get(sk_tun);
+ skb->dst = dst_clone(__sk_dst_get(sk_tun));
skb_orphan(skb);
skb->sk = sk_tun;
@@ -1107,7 +1112,7 @@ static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel)
PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
"%s: closing all sessions...\n", tunnel->name);
- write_lock(&tunnel->hlist_lock);
+ write_lock_bh(&tunnel->hlist_lock);
for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) {
again:
hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {
@@ -1129,7 +1134,7 @@ again:
* disappear as we're jumping between locks.
*/
sock_hold(sk);
- write_unlock(&tunnel->hlist_lock);
+ write_unlock_bh(&tunnel->hlist_lock);
lock_sock(sk);
if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
@@ -1154,11 +1159,11 @@ again:
* list so we are guaranteed to make forward
* progress.
*/
- write_lock(&tunnel->hlist_lock);
+ write_lock_bh(&tunnel->hlist_lock);
goto again;
}
}
- write_unlock(&tunnel->hlist_lock);
+ write_unlock_bh(&tunnel->hlist_lock);
}
/* Really kill the tunnel.
@@ -1167,9 +1172,9 @@ again:
static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel)
{
/* Remove from socket list */
- write_lock(&pppol2tp_tunnel_list_lock);
+ write_lock_bh(&pppol2tp_tunnel_list_lock);
list_del_init(&tunnel->list);
- write_unlock(&pppol2tp_tunnel_list_lock);
+ write_unlock_bh(&pppol2tp_tunnel_list_lock);
atomic_dec(&pppol2tp_tunnel_count);
kfree(tunnel);
@@ -1245,9 +1250,9 @@ static void pppol2tp_session_destruct(struct sock *sk)
/* Delete the session socket from the
* hash
*/
- write_lock(&tunnel->hlist_lock);
+ write_lock_bh(&tunnel->hlist_lock);
hlist_del_init(&session->hlist);
- write_unlock(&tunnel->hlist_lock);
+ write_unlock_bh(&tunnel->hlist_lock);
atomic_dec(&pppol2tp_session_count);
}
@@ -1392,9 +1397,9 @@ static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
/* Add tunnel to our list */
INIT_LIST_HEAD(&tunnel->list);
- write_lock(&pppol2tp_tunnel_list_lock);
+ write_lock_bh(&pppol2tp_tunnel_list_lock);
list_add(&tunnel->list, &pppol2tp_tunnel_list);
- write_unlock(&pppol2tp_tunnel_list_lock);
+ write_unlock_bh(&pppol2tp_tunnel_list_lock);
atomic_inc(&pppol2tp_tunnel_count);
/* Bump the reference count. The tunnel context is deleted
@@ -1599,11 +1604,11 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
sk->sk_user_data = session;
/* Add session to the tunnel's hash list */
- write_lock(&tunnel->hlist_lock);
+ write_lock_bh(&tunnel->hlist_lock);
hlist_add_head(&session->hlist,
pppol2tp_session_id_hash(tunnel,
session->tunnel_addr.s_session));
- write_unlock(&tunnel->hlist_lock);
+ write_unlock_bh(&tunnel->hlist_lock);
atomic_inc(&pppol2tp_session_count);
@@ -2205,7 +2210,7 @@ static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, str
int next = 0;
int i;
- read_lock(&tunnel->hlist_lock);
+ read_lock_bh(&tunnel->hlist_lock);
for (i = 0; i < PPPOL2TP_HASH_SIZE; i++) {
hlist_for_each_entry(session, walk, &tunnel->session_hlist[i], hlist) {
if (curr == NULL) {
@@ -2223,7 +2228,7 @@ static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, str
}
}
out:
- read_unlock(&tunnel->hlist_lock);
+ read_unlock_bh(&tunnel->hlist_lock);
if (!found)
session = NULL;
@@ -2234,13 +2239,13 @@ static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr)
{
struct pppol2tp_tunnel *tunnel = NULL;
- read_lock(&pppol2tp_tunnel_list_lock);
+ read_lock_bh(&pppol2tp_tunnel_list_lock);
if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) {
goto out;
}
tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list);
out:
- read_unlock(&pppol2tp_tunnel_list_lock);
+ read_unlock_bh(&pppol2tp_tunnel_list_lock);
return tunnel;
}
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 6179a0a2032..c72787adeba 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -1088,7 +1088,7 @@ static int s2io_print_pci_mode(struct s2io_nic *nic)
* '-1' on failure
*/
-int init_tti(struct s2io_nic *nic, int link)
+static int init_tti(struct s2io_nic *nic, int link)
{
struct XENA_dev_config __iomem *bar0 = nic->bar0;
register u64 val64 = 0;
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index 77d9dd7ea34..567c62757e9 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -910,7 +910,8 @@ static void de_set_media (struct de_private *de)
unsigned media = de->media_type;
u32 macmode = dr32(MacMode);
- BUG_ON(de_is_running(de));
+ if (de_is_running(de))
+ printk(KERN_WARNING "%s: chip is running while changing media!\n", de->dev->name);
if (de->de21040)
dw32(CSR11, FULL_DUPLEX_MAGIC);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 19fd4cb0ddf..b58472cf76f 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -203,8 +203,11 @@ again:
if (received < budget) {
netif_rx_complete(vi->dev, napi);
if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq))
- && netif_rx_reschedule(vi->dev, napi))
+ && napi_schedule_prep(napi)) {
+ vi->rvq->vq_ops->disable_cb(vi->rvq);
+ __netif_rx_schedule(vi->dev, napi);
goto again;
+ }
}
return received;
@@ -278,10 +281,11 @@ again:
pr_debug("%s: virtio not prepared to send\n", dev->name);
netif_stop_queue(dev);
- /* Activate callback for using skbs: if this fails it
+ /* Activate callback for using skbs: if this returns false it
* means some were used in the meantime. */
if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) {
- printk("Unlikely: restart svq failed\n");
+ printk("Unlikely: restart svq race\n");
+ vi->svq->vq_ops->disable_cb(vi->svq);
netif_start_queue(dev);
goto again;
}
@@ -294,6 +298,15 @@ again:
return 0;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void virtnet_netpoll(struct net_device *dev)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+
+ napi_schedule(&vi->napi);
+}
+#endif
+
static int virtnet_open(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
@@ -336,6 +349,9 @@ static int virtnet_probe(struct virtio_device *vdev)
dev->stop = virtnet_close;
dev->hard_start_xmit = start_xmit;
dev->features = NETIF_F_HIGHDMA;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ dev->poll_controller = virtnet_netpoll;
+#endif
SET_NETDEV_DEV(dev, &vdev->dev);
/* Do we support "hardware" checksums? */
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index 15d5c58e57b..e59255a155a 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -751,7 +751,7 @@ upload_data( struct net_device *dev, unsigned framelen, unsigned frameno,
}
-static __inline void
+static inline void
send_complete( struct net_local *nl )
{
#ifdef CONFIG_SBNI_MULTILINE
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index bdc6a1cc210..f0ef7081bde 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -578,7 +578,7 @@ int lbs_process_rx_command(struct lbs_private *priv)
goto done;
}
if (respcmd != CMD_RET(curcmd) &&
- respcmd != CMD_802_11_ASSOCIATE && curcmd != CMD_RET_802_11_ASSOCIATE) {
+ respcmd != CMD_RET_802_11_ASSOCIATE && curcmd != CMD_802_11_ASSOCIATE) {
lbs_pr_info("Invalid CMD_RESP %x to command %x!\n", respcmd, curcmd);
spin_unlock_irqrestore(&priv->driver_lock, flags);
ret = -1;
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index e808db98f2f..93ea212fedd 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2302,9 +2302,9 @@ static void rt61pci_configure_filter(struct ieee80211_hw *hw,
* Apply some rules to the filters:
* - Some filters imply different filters to be set.
* - Some things we can't filter out at all.
+ * - Multicast filter seems to kill broadcast traffic so never use it.
*/
- if (mc_count)
- *total_flags |= FIF_ALLMULTI;
+ *total_flags |= FIF_ALLMULTI;
if (*total_flags & FIF_OTHER_BSS ||
*total_flags & FIF_PROMISC_IN_BSS)
*total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 4fac2d414d8..8103d41a154 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1869,9 +1869,9 @@ static void rt73usb_configure_filter(struct ieee80211_hw *hw,
* Apply some rules to the filters:
* - Some filters imply different filters to be set.
* - Some things we can't filter out at all.
+ * - Multicast filter seems to kill broadcast traffic so never use it.
*/
- if (mc_count)
- *total_flags |= FIF_ALLMULTI;
+ *total_flags |= FIF_ALLMULTI;
if (*total_flags & FIF_OTHER_BSS ||
*total_flags & FIF_PROMISC_IN_BSS)
*total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
@@ -2098,6 +2098,7 @@ static struct usb_device_id rt73usb_device_table[] = {
/* D-Link */
{ USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) },
/* Gemtek */
{ USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) },
/* Gigabyte */
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c
index de34aa9d313..f9f9a5f1bbd 100644
--- a/drivers/parisc/pdc_stable.c
+++ b/drivers/parisc/pdc_stable.c
@@ -829,7 +829,7 @@ static ssize_t pdcs_autoboot_write(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
- return pdcs_auto_write(kset, attr, buf, count, PF_AUTOBOOT);
+ return pdcs_auto_write(kobj, attr, buf, count, PF_AUTOBOOT);
}
/**
@@ -845,7 +845,7 @@ static ssize_t pdcs_autosearch_write(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
- return pdcs_auto_write(kset, attr, buf, count, PF_AUTOSEARCH);
+ return pdcs_auto_write(kobj, attr, buf, count, PF_AUTOSEARCH);
}
/**
@@ -1066,7 +1066,7 @@ pdc_stable_init(void)
}
/* Don't forget the root entries */
- error = sysfs_create_group(stable_kobj, pdcs_attr_group);
+ error = sysfs_create_group(stable_kobj, &pdcs_attr_group);
/* register the paths kset as a child of the stable kset */
paths_kset = kset_create_and_add("paths", NULL, stable_kobj);
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index bdbe780e21c..8c4d2c13d5f 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -314,8 +314,8 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
#define RESMAP_MASK(n) (~0UL << (BITS_PER_LONG - (n)))
#define RESMAP_IDX_MASK (sizeof(unsigned long) - 1)
-unsigned long ptr_to_pide(struct ioc *ioc, unsigned long *res_ptr,
- unsigned int bitshiftcnt)
+static unsigned long ptr_to_pide(struct ioc *ioc, unsigned long *res_ptr,
+ unsigned int bitshiftcnt)
{
return (((unsigned long)res_ptr - (unsigned long)ioc->res_map) << 3)
+ bitshiftcnt;
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 6a9403d79e0..d708358326e 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -143,14 +143,18 @@ void pci_bus_add_devices(struct pci_bus *bus)
/* register the bus with sysfs as the parent is now
* properly registered. */
child_bus = dev->subordinate;
+ if (child_bus->is_added)
+ continue;
child_bus->dev.parent = child_bus->bridge;
retval = device_register(&child_bus->dev);
if (retval)
dev_err(&dev->dev, "Error registering pci_bus,"
" continuing...\n");
- else
+ else {
+ child_bus->is_added = 1;
retval = device_create_file(&child_bus->dev,
&dev_attr_cpuaffinity);
+ }
if (retval)
dev_err(&dev->dev, "Error creating cpuaffinity"
" file, continuing...\n");
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 7f4836b8e71..5fa4ba0d993 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -467,7 +467,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);
t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
- if (value) {
+ if (value && pciehp_force) {
rc = pciehp_enable_slot(t_slot);
if (rc) /* -ENODEV: shouldn't happen, but deal with it */
value = 0;
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 4a23654184f..72f7476930c 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -272,21 +272,29 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
{
acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
acpi_handle tmp;
- static int state_conv[] = {
- [0] = 0,
- [1] = 1,
- [2] = 2,
- [3] = 3,
- [4] = 3
+ static const u8 state_conv[] = {
+ [PCI_D0] = ACPI_STATE_D0,
+ [PCI_D1] = ACPI_STATE_D1,
+ [PCI_D2] = ACPI_STATE_D2,
+ [PCI_D3hot] = ACPI_STATE_D3,
+ [PCI_D3cold] = ACPI_STATE_D3
};
- int acpi_state = state_conv[(int __force) state];
if (!handle)
return -ENODEV;
/* If the ACPI device has _EJ0, ignore the device */
if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &tmp)))
return 0;
- return acpi_bus_set_power(handle, acpi_state);
+
+ switch (state) {
+ case PCI_D0:
+ case PCI_D1:
+ case PCI_D2:
+ case PCI_D3hot:
+ case PCI_D3cold:
+ return acpi_bus_set_power(handle, state_conv[state]);
+ }
+ return -EINVAL;
}
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index 4065139753b..37993206ae5 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -17,7 +17,6 @@
#include <linux/slab.h>
#include <linux/pnp.h>
#include <linux/io.h>
-#include <linux/dmi.h>
#include <linux/kallsyms.h>
#include "base.h"
@@ -109,42 +108,73 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev)
"pnp: SB audio device quirk - increasing port range\n");
}
-static void quirk_supermicro_h8dce_system(struct pnp_dev *dev)
+
+#include <linux/pci.h>
+
+static void quirk_system_pci_resources(struct pnp_dev *dev)
{
- int i;
- static struct dmi_system_id supermicro_h8dce[] = {
- {
- .ident = "Supermicro H8DCE",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
- DMI_MATCH(DMI_PRODUCT_NAME, "H8DCE"),
- },
- },
- { }
- };
-
- if (!dmi_check_system(supermicro_h8dce))
- return;
+ struct pci_dev *pdev = NULL;
+ resource_size_t pnp_start, pnp_end, pci_start, pci_end;
+ int i, j;
/*
- * On the Supermicro H8DCE, there's a system device with resources
- * that overlap BAR 6 of the built-in SATA PCI adapter. If the PNP
- * system device claims them, the sata_nv driver won't be able to.
- * More details at:
- * https://bugzilla.redhat.com/show_bug.cgi?id=280641
- * https://bugzilla.redhat.com/show_bug.cgi?id=313491
- * http://lkml.org/lkml/2008/1/9/449
- * http://thread.gmane.org/gmane.linux.acpi.devel/27312
+ * Some BIOSes have PNP motherboard devices with resources that
+ * partially overlap PCI BARs. The PNP system driver claims these
+ * motherboard resources, which prevents the normal PCI driver from
+ * requesting them later.
+ *
+ * This patch disables the PNP resources that conflict with PCI BARs
+ * so they won't be claimed by the PNP system driver.
*/
- for (i = 0; i < PNP_MAX_MEM; i++) {
- if (pnp_mem_valid(dev, i) && pnp_mem_len(dev, i) &&
- (pnp_mem_start(dev, i) & 0xdfef0000) == 0xdfef0000) {
- dev_warn(&dev->dev, "disabling 0x%llx-0x%llx to prevent"
- " conflict with sata_nv PCI device\n",
- (unsigned long long) pnp_mem_start(dev, i),
- (unsigned long long) (pnp_mem_start(dev, i) +
- pnp_mem_len(dev, i) - 1));
- pnp_mem_flags(dev, i) = 0;
+ for_each_pci_dev(pdev) {
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM) ||
+ pci_resource_len(pdev, i) == 0)
+ continue;
+
+ pci_start = pci_resource_start(pdev, i);
+ pci_end = pci_resource_end(pdev, i);
+ for (j = 0; j < PNP_MAX_MEM; j++) {
+ if (!pnp_mem_valid(dev, j) ||
+ pnp_mem_len(dev, j) == 0)
+ continue;
+
+ pnp_start = pnp_mem_start(dev, j);
+ pnp_end = pnp_mem_end(dev, j);
+
+ /*
+ * If the PNP region doesn't overlap the PCI
+ * region at all, there's no problem.
+ */
+ if (pnp_end < pci_start || pnp_start > pci_end)
+ continue;
+
+ /*
+ * If the PNP region completely encloses (or is
+ * at least as large as) the PCI region, that's
+ * also OK. For example, this happens when the
+ * PNP device describes a bridge with PCI
+ * behind it.
+ */
+ if (pnp_start <= pci_start &&
+ pnp_end >= pci_end)
+ continue;
+
+ /*
+ * Otherwise, the PNP region overlaps *part* of
+ * the PCI region, and that might prevent a PCI
+ * driver from requesting its resources.
+ */
+ dev_warn(&dev->dev, "mem resource "
+ "(0x%llx-0x%llx) overlaps %s BAR %d "
+ "(0x%llx-0x%llx), disabling\n",
+ (unsigned long long) pnp_start,
+ (unsigned long long) pnp_end,
+ pci_name(pdev), i,
+ (unsigned long long) pci_start,
+ (unsigned long long) pci_end);
+ pnp_mem_flags(dev, j) = 0;
+ }
}
}
}
@@ -169,8 +199,8 @@ static struct pnp_fixup pnp_fixups[] = {
{"CTL0043", quirk_sb16audio_resources},
{"CTL0044", quirk_sb16audio_resources},
{"CTL0045", quirk_sb16audio_resources},
- {"PNP0c01", quirk_supermicro_h8dce_system},
- {"PNP0c02", quirk_supermicro_h8dce_system},
+ {"PNP0c01", quirk_system_pci_resources},
+ {"PNP0c02", quirk_system_pci_resources},
{""}
};
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 82f5ad9c3af..9e7de63b26e 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -16,7 +16,7 @@ menuconfig RTC_CLASS
probably want to enable one or more of the interfaces below.
This driver can also be built as a module. If so, the module
- will be called rtc-class.
+ will be called rtc-core.
if RTC_CLASS
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index bbf10ecf416..56728a2a338 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -274,7 +274,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc)
* SR clears it, so we must only read it in this irq handler!
*/
mr = rtt_readl(rtc, MR) & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN);
- sr = rtt_readl(rtc, SR) & mr;
+ sr = rtt_readl(rtc, SR) & (mr >> 16);
if (!sr)
return IRQ_NONE;
@@ -321,6 +321,10 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
if (!rtc)
return -ENOMEM;
+ /* platform setup code should have handled this; sigh */
+ if (!device_can_wakeup(&pdev->dev))
+ device_init_wakeup(&pdev->dev, 1);
+
platform_set_drvdata(pdev, rtc);
rtc->rtt = (void __force __iomem *) (AT91_VA_BASE_SYS - AT91_BASE_SYS);
rtc->rtt += r->start;
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index c46666a2480..b9d374082b6 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -325,7 +325,7 @@ menuconfig SCSI_LOWLEVEL
depends on SCSI!=n
default y
-if SCSI_LOWLEVEL
+if SCSI_LOWLEVEL && SCSI
config ISCSI_TCP
tristate "iSCSI Initiator over TCP/IP"
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index f608d4a1d6d..792b2e807bf 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -674,12 +674,13 @@ static struct orc_scb *__orc_alloc_scb(struct orc_host * host)
for (index = 0; index < 32; index++) {
if ((host->allocation_map[channel][i] >> index) & 0x01) {
host->allocation_map[channel][i] &= ~(1 << index);
- break;
+ idx = index + 32 * i;
+ /*
+ * Translate the index to a structure instance
+ */
+ return host->scb_virt + idx;
}
}
- idx = index + 32 * i;
- /* Translate the index to a structure instance */
- return (struct orc_scb *) ((unsigned long) host->scb_virt + (idx * sizeof(struct orc_scb)));
}
return NULL;
}
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 3c2d6888bb8..8591585e5cc 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -6439,7 +6439,7 @@ static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
i += 2;
len += 2;
} else {
- unsigned char off = buf[i] * 2;
+ unsigned int off = buf[i] * 2;
unsigned short word = (buf[off + 1] << 8) | buf[off];
AdvWriteWordAutoIncLram(iop_base, word);
len += 2;
diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
index 0393707bdfc..3288be2e49f 100644
--- a/drivers/scsi/arcmsr/arcmsr.h
+++ b/drivers/scsi/arcmsr/arcmsr.h
@@ -341,13 +341,13 @@ struct MessageUnit_B
uint32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE];
uint32_t postq_index;
uint32_t doneq_index;
- uint32_t __iomem *drv2iop_doorbell_reg;
- uint32_t __iomem *drv2iop_doorbell_mask_reg;
- uint32_t __iomem *iop2drv_doorbell_reg;
- uint32_t __iomem *iop2drv_doorbell_mask_reg;
- uint32_t __iomem *msgcode_rwbuffer_reg;
- uint32_t __iomem *ioctl_wbuffer_reg;
- uint32_t __iomem *ioctl_rbuffer_reg;
+ void __iomem *drv2iop_doorbell_reg;
+ void __iomem *drv2iop_doorbell_mask_reg;
+ void __iomem *iop2drv_doorbell_reg;
+ void __iomem *iop2drv_doorbell_mask_reg;
+ void __iomem *msgcode_rwbuffer_reg;
+ void __iomem *ioctl_wbuffer_reg;
+ void __iomem *ioctl_rbuffer_reg;
};
/*
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 27ebd336409..0b2080d3357 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -493,6 +493,12 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
if (!scp)
return -ENOMEM;
+ scp->sense_buffer = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
+ if (!scp->sense_buffer) {
+ kfree(scp);
+ return -ENOMEM;
+ }
+
scp->device = sdev;
memset(&cmndinfo, 0, sizeof(cmndinfo));
@@ -513,6 +519,7 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
rval = cmndinfo.status;
if (info)
*info = cmndinfo.info;
+ kfree(scp->sense_buffer);
kfree(scp);
return rval;
}
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index ba21d97d185..f40898dc2d1 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2162,10 +2162,15 @@ void sdev_evt_send(struct scsi_device *sdev, struct scsi_event *evt)
{
unsigned long flags;
+#if 0
+ /* FIXME: currently this check eliminates all media change events
+ * for polled devices. Need to update to discriminate between AN
+ * and polled events */
if (!test_bit(evt->evt_type, sdev->supported_events)) {
kfree(evt);
return;
}
+#endif
spin_lock_irqsave(&sdev->list_lock, flags);
list_add_tail(&evt->node, &sdev->event_list);
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index ed83cdb6e67..b9b09a70458 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -294,6 +294,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
}
if (sdev->request_queue) {
+ bsg_unregister_queue(sdev->request_queue);
sdev->request_queue->queuedata = NULL;
/* user context needed to free queue */
scsi_free_queue(sdev->request_queue);
@@ -857,7 +858,6 @@ void __scsi_remove_device(struct scsi_device *sdev)
if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
return;
- bsg_unregister_queue(sdev->request_queue);
class_device_unregister(&sdev->sdev_classdev);
transport_remove_device(dev);
device_del(dev);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 7aee64dbfbe..5fe7aaed904 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1654,6 +1654,7 @@ static int sd_probe(struct device *dev)
sdkp->disk = gd;
sdkp->index = index;
sdkp->openers = 0;
+ sdkp->previous_state = 1;
if (!sdp->timeout) {
if (sdp->type != TYPE_MOD)
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 208565bdbe8..7ee86d4a761 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -623,6 +623,7 @@ static int sr_probe(struct device *dev)
cd->disk = disk;
cd->capacity = 0x1fffff;
cd->device->changed = 1; /* force recheck CD type */
+ cd->previous_state = 1;
cd->use = 1;
cd->readcd_known = 0;
cd->readcd_cdda = 0;
diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c
index c47a650183a..41a3d00c451 100644
--- a/drivers/spi/au1550_spi.c
+++ b/drivers/spi/au1550_spi.c
@@ -99,7 +99,7 @@ static dbdev_tab_t au1550_spi_mem_dbdev =
static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw);
-/**
+/*
* compute BRG and DIV bits to setup spi clock based on main input clock rate
* that was specified in platform data structure
* according to au1550 datasheet:
@@ -650,7 +650,7 @@ static int au1550_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
return hw->txrx_bufs(spi, t);
}
-static irqreturn_t au1550_spi_irq(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t au1550_spi_irq(int irq, void *dev)
{
struct au1550_spi *hw = dev;
return hw->irq_callback(hw);
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c
index f7f8580edad..71e881419cd 100644
--- a/drivers/spi/spi_bitbang.c
+++ b/drivers/spi/spi_bitbang.c
@@ -344,12 +344,14 @@ static void bitbang_work(struct work_struct *work)
t->rx_dma = t->tx_dma = 0;
status = bitbang->txrx_bufs(spi, t);
}
+ if (status > 0)
+ m->actual_length += status;
if (status != t->len) {
- if (status > 0)
- status = -EMSGSIZE;
+ /* always report some kind of error */
+ if (status >= 0)
+ status = -EREMOTEIO;
break;
}
- m->actual_length += status;
status = 0;
/* protocol tweaks before next transfer */
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 69f19f22487..17e71d56f31 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -4,7 +4,6 @@
menuconfig THERMAL
bool "Generic Thermal sysfs driver"
- default y
help
Generic Thermal Sysfs driver offers a generic mechanism for
thermal management. Usually it's made up of one or more thermal
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 2ae1e8673b1..9d3f28b92cb 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -1469,6 +1469,7 @@ static void isd200_free_info_ptrs(void *info_)
if (info) {
kfree(info->id);
kfree(info->RegsBuf);
+ kfree(info->srb.sense_buffer);
}
}
@@ -1494,7 +1495,9 @@ static int isd200_init_info(struct us_data *us)
kzalloc(sizeof(struct hd_driveid), GFP_KERNEL);
info->RegsBuf = (unsigned char *)
kmalloc(sizeof(info->ATARegs), GFP_KERNEL);
- if (!info->id || !info->RegsBuf) {
+ info->srb.sense_buffer =
+ kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
+ if (!info->id || !info->RegsBuf || !info->srb.sense_buffer) {
isd200_free_info_ptrs(info);
kfree(info);
retStatus = ISD200_ERROR;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index e0b0580705e..1bd5fb30237 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1893,6 +1893,20 @@ config FB_XILINX
framebuffer. ML300 carries a 640*480 LCD display on the board,
ML403 uses a standard DB15 VGA connector.
+config FB_METRONOME
+ tristate "Metronome display controller support"
+ depends on FB && ARCH_PXA && MMU
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ help
+ This enables support for the Metronome display controller. Tested
+ with an E-Ink 800x600 display and Gumstix Connex through an AMLCD
+ interface. Please read <file:Documentation/fb/metronomefb.txt>
+ for more information.
+
config FB_VIRTUAL
tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
depends on FB
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 03371c78903..11c0e5e05f2 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -103,6 +103,7 @@ obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o
obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
obj-$(CONFIG_FB_MAXINE) += maxinefb.o
+obj-$(CONFIG_FB_METRONOME) += metronomefb.o
obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
obj-$(CONFIG_FB_IMX) += imxfb.o
obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 0f8cfb988c9..24843fdd539 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -4,7 +4,7 @@
* Copyright (C) 2006 Jaya Kumar
*
* This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
+ * License. See the file COPYING in the main directory of this archive
* for more details.
*/
@@ -31,7 +31,7 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma,
unsigned long offset;
struct page *page;
struct fb_info *info = vma->vm_private_data;
- /* info->screen_base is in System RAM */
+ /* info->screen_base is virtual memory */
void *screen_base = (void __force *) info->screen_base;
offset = vmf->pgoff << PAGE_SHIFT;
@@ -43,6 +43,15 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma,
return VM_FAULT_SIGBUS;
get_page(page);
+
+ if (vma->vm_file)
+ page->mapping = vma->vm_file->f_mapping;
+ else
+ printk(KERN_ERR "no mapping available\n");
+
+ BUG_ON(!page->mapping);
+ page->index = vmf->pgoff;
+
vmf->page = page;
return 0;
}
@@ -138,11 +147,20 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_init);
void fb_deferred_io_cleanup(struct fb_info *info)
{
+ void *screen_base = (void __force *) info->screen_base;
struct fb_deferred_io *fbdefio = info->fbdefio;
+ struct page *page;
+ int i;
BUG_ON(!fbdefio);
cancel_delayed_work(&info->deferred_work);
flush_scheduled_work();
+
+ /* clear out the mapping that we setup */
+ for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) {
+ page = vmalloc_to_page(screen_base + i);
+ page->mapping = NULL;
+ }
}
EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup);
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 1d13dd099af..a24e680d2b9 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -1476,7 +1476,7 @@ static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
struct i810fb_par *par = info->par;
u8 __iomem *mmio = par->mmio_start_virtual;
- if (!(par->dev_flags & LOCKUP))
+ if (par->dev_flags & LOCKUP)
return -ENXIO;
if (cursor->image.width > 64 || cursor->image.height > 64)
diff --git a/drivers/video/metronomefb.c b/drivers/video/metronomefb.c
new file mode 100644
index 00000000000..e9a89fd8275
--- /dev/null
+++ b/drivers/video/metronomefb.c
@@ -0,0 +1,999 @@
+/*
+ * linux/drivers/video/metronomefb.c -- FB driver for Metronome controller
+ *
+ * Copyright (C) 2008, Jaya Kumar
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven.
+ *
+ * This work was made possible by help and equipment support from E-Ink
+ * Corporation. http://support.eink.com/community
+ *
+ * This driver is written to be used with the Metronome display controller.
+ * It was tested with an E-Ink 800x600 Vizplex EPD on a Gumstix Connex board
+ * using the Lyre interface board.
+ *
+ * General notes:
+ * - User must set metronomefb_enable=1 to enable it.
+ * - See Documentation/fb/metronomefb.txt for how metronome works.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/list.h>
+#include <linux/firmware.h>
+#include <linux/dma-mapping.h>
+#include <linux/uaccess.h>
+#include <linux/irq.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/unaligned.h>
+
+#define DEBUG 1
+#ifdef DEBUG
+#define DPRINTK(f, a...) printk(KERN_DEBUG "%s: " f, __func__ , ## a)
+#else
+#define DPRINTK(f, a...)
+#endif
+
+
+/* Display specific information */
+#define DPY_W 832
+#define DPY_H 622
+
+struct metromem_desc {
+ u32 mFDADR0;
+ u32 mFSADR0;
+ u32 mFIDR0;
+ u32 mLDCMD0;
+};
+
+struct metromem_cmd {
+ u16 opcode;
+ u16 args[((64-2)/2)];
+ u16 csum;
+};
+
+struct metronomefb_par {
+ unsigned char *metromem;
+ struct metromem_desc *metromem_desc;
+ struct metromem_cmd *metromem_cmd;
+ unsigned char *metromem_wfm;
+ unsigned char *metromem_img;
+ u16 *metromem_img_csum;
+ u16 *csum_table;
+ int metromemsize;
+ dma_addr_t metromem_dma;
+ dma_addr_t metromem_desc_dma;
+ struct fb_info *info;
+ wait_queue_head_t waitq;
+ u8 frame_count;
+};
+
+/* frame differs from image. frame includes non-visible pixels */
+struct epd_frame {
+ int fw; /* frame width */
+ int fh; /* frame height */
+};
+
+static struct epd_frame epd_frame_table[] = {
+ {
+ .fw = 832,
+ .fh = 622
+ },
+};
+
+static struct fb_fix_screeninfo metronomefb_fix __devinitdata = {
+ .id = "metronomefb",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_STATIC_PSEUDOCOLOR,
+ .xpanstep = 0,
+ .ypanstep = 0,
+ .ywrapstep = 0,
+ .line_length = DPY_W,
+ .accel = FB_ACCEL_NONE,
+};
+
+static struct fb_var_screeninfo metronomefb_var __devinitdata = {
+ .xres = DPY_W,
+ .yres = DPY_H,
+ .xres_virtual = DPY_W,
+ .yres_virtual = DPY_H,
+ .bits_per_pixel = 8,
+ .grayscale = 1,
+ .nonstd = 1,
+ .red = { 4, 3, 0 },
+ .green = { 0, 0, 0 },
+ .blue = { 0, 0, 0 },
+ .transp = { 0, 0, 0 },
+};
+
+static unsigned int metronomefb_enable;
+
+struct waveform_hdr {
+ u8 stuff[32];
+
+ u8 wmta[3];
+ u8 fvsn;
+
+ u8 luts;
+ u8 mc;
+ u8 trc;
+ u8 stuff3;
+
+ u8 endb;
+ u8 swtb;
+ u8 stuff2a[2];
+
+ u8 stuff2b[3];
+ u8 wfm_cs;
+} __attribute__ ((packed));
+
+/* main metronomefb functions */
+static u8 calc_cksum(int start, int end, u8 *mem)
+{
+ u8 tmp = 0;
+ int i;
+
+ for (i = start; i < end; i++)
+ tmp += mem[i];
+
+ return tmp;
+}
+
+static u16 calc_img_cksum(u16 *start, int length)
+{
+ u16 tmp = 0;
+
+ while (length--)
+ tmp += *start++;
+
+ return tmp;
+}
+
+/* here we decode the incoming waveform file and populate metromem */
+#define EXP_WFORM_SIZE 47001
+static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t,
+ u8 *frame_count)
+{
+ int tta;
+ int wmta;
+ int trn = 0;
+ int i;
+ unsigned char v;
+ u8 cksum;
+ int cksum_idx;
+ int wfm_idx, owfm_idx;
+ int mem_idx = 0;
+ struct waveform_hdr *wfm_hdr;
+
+ if (size != EXP_WFORM_SIZE) {
+ printk(KERN_ERR "Error: unexpected size %d != %d\n", size,
+ EXP_WFORM_SIZE);
+ return -EINVAL;
+ }
+
+ wfm_hdr = (struct waveform_hdr *) mem;
+
+ if (wfm_hdr->fvsn != 1) {
+ printk(KERN_ERR "Error: bad fvsn %x\n", wfm_hdr->fvsn);
+ return -EINVAL;
+ }
+ if (wfm_hdr->luts != 0) {
+ printk(KERN_ERR "Error: bad luts %x\n", wfm_hdr->luts);
+ return -EINVAL;
+ }
+ cksum = calc_cksum(32, 47, mem);
+ if (cksum != wfm_hdr->wfm_cs) {
+ printk(KERN_ERR "Error: bad cksum %x != %x\n", cksum,
+ wfm_hdr->wfm_cs);
+ return -EINVAL;
+ }
+ wfm_hdr->mc += 1;
+ wfm_hdr->trc += 1;
+ for (i = 0; i < 5; i++) {
+ if (*(wfm_hdr->stuff2a + i) != 0) {
+ printk(KERN_ERR "Error: unexpected value in padding\n");
+ return -EINVAL;
+ }
+ }
+
+ /* calculating trn. trn is something used to index into
+ the waveform. presumably selecting the right one for the
+ desired temperature. it works out the offset of the first
+ v that exceeds the specified temperature */
+ if ((sizeof(*wfm_hdr) + wfm_hdr->trc) > size)
+ return -EINVAL;
+
+ for (i = sizeof(*wfm_hdr); i <= sizeof(*wfm_hdr) + wfm_hdr->trc; i++) {
+ if (mem[i] > t) {
+ trn = i - sizeof(*wfm_hdr) - 1;
+ break;
+ }
+ }
+
+ /* check temperature range table checksum */
+ cksum_idx = sizeof(*wfm_hdr) + wfm_hdr->trc + 1;
+ if (cksum_idx > size)
+ return -EINVAL;
+ cksum = calc_cksum(sizeof(*wfm_hdr), cksum_idx, mem);
+ if (cksum != mem[cksum_idx]) {
+ printk(KERN_ERR "Error: bad temperature range table cksum"
+ " %x != %x\n", cksum, mem[cksum_idx]);
+ return -EINVAL;
+ }
+
+ /* check waveform mode table address checksum */
+ wmta = le32_to_cpu(get_unaligned((__le32 *) wfm_hdr->wmta));
+ wmta &= 0x00FFFFFF;
+ cksum_idx = wmta + m*4 + 3;
+ if (cksum_idx > size)
+ return -EINVAL;
+ cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem);
+ if (cksum != mem[cksum_idx]) {
+ printk(KERN_ERR "Error: bad mode table address cksum"
+ " %x != %x\n", cksum, mem[cksum_idx]);
+ return -EINVAL;
+ }
+
+ /* check waveform temperature table address checksum */
+ tta = le32_to_cpu(get_unaligned((int *) (mem + wmta + m*4)));
+ tta &= 0x00FFFFFF;
+ cksum_idx = tta + trn*4 + 3;
+ if (cksum_idx > size)
+ return -EINVAL;
+ cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem);
+ if (cksum != mem[cksum_idx]) {
+ printk(KERN_ERR "Error: bad temperature table address cksum"
+ " %x != %x\n", cksum, mem[cksum_idx]);
+ return -EINVAL;
+ }
+
+ /* here we do the real work of putting the waveform into the
+ metromem buffer. this does runlength decoding of the waveform */
+ wfm_idx = le32_to_cpu(get_unaligned((__le32 *) (mem + tta + trn*4)));
+ wfm_idx &= 0x00FFFFFF;
+ owfm_idx = wfm_idx;
+ if (wfm_idx > size)
+ return -EINVAL;
+ while (wfm_idx < size) {
+ unsigned char rl;
+ v = mem[wfm_idx++];
+ if (v == wfm_hdr->swtb) {
+ while (((v = mem[wfm_idx++]) != wfm_hdr->swtb) &&
+ wfm_idx < size)
+ metromem[mem_idx++] = v;
+
+ continue;
+ }
+
+ if (v == wfm_hdr->endb)
+ break;
+
+ rl = mem[wfm_idx++];
+ for (i = 0; i <= rl; i++)
+ metromem[mem_idx++] = v;
+ }
+
+ cksum_idx = wfm_idx;
+ if (cksum_idx > size)
+ return -EINVAL;
+ cksum = calc_cksum(owfm_idx, cksum_idx, mem);
+ if (cksum != mem[cksum_idx]) {
+ printk(KERN_ERR "Error: bad waveform data cksum"
+ " %x != %x\n", cksum, mem[cksum_idx]);
+ return -EINVAL;
+ }
+ *frame_count = (mem_idx/64);
+
+ return 0;
+}
+
+/* register offsets for gpio control */
+#define LED_GPIO_PIN 51
+#define STDBY_GPIO_PIN 48
+#define RST_GPIO_PIN 49
+#define RDY_GPIO_PIN 32
+#define ERR_GPIO_PIN 17
+#define PCBPWR_GPIO_PIN 16
+
+#define AF_SEL_GPIO_N 0x3
+#define GAFR0_U_OFFSET(pin) ((pin - 16) * 2)
+#define GAFR1_L_OFFSET(pin) ((pin - 32) * 2)
+#define GAFR1_U_OFFSET(pin) ((pin - 48) * 2)
+#define GPDR1_OFFSET(pin) (pin - 32)
+#define GPCR1_OFFSET(pin) (pin - 32)
+#define GPSR1_OFFSET(pin) (pin - 32)
+#define GPCR0_OFFSET(pin) (pin)
+#define GPSR0_OFFSET(pin) (pin)
+
+static void metronome_set_gpio_output(int pin, int val)
+{
+ u8 index;
+
+ index = pin >> 4;
+
+ switch (index) {
+ case 1:
+ if (val)
+ GPSR0 |= (1 << GPSR0_OFFSET(pin));
+ else
+ GPCR0 |= (1 << GPCR0_OFFSET(pin));
+ break;
+ case 2:
+ break;
+ case 3:
+ if (val)
+ GPSR1 |= (1 << GPSR1_OFFSET(pin));
+ else
+ GPCR1 |= (1 << GPCR1_OFFSET(pin));
+ break;
+ default:
+ printk(KERN_ERR "unimplemented\n");
+ }
+}
+
+static void __devinit metronome_init_gpio_pin(int pin, int dir)
+{
+ u8 index;
+ /* dir 0 is output, 1 is input
+ - do 2 things here:
+ - set gpio alternate function to standard gpio
+ - set gpio direction to input or output */
+
+ index = pin >> 4;
+ switch (index) {
+ case 1:
+ GAFR0_U &= ~(AF_SEL_GPIO_N << GAFR0_U_OFFSET(pin));
+
+ if (dir)
+ GPDR0 &= ~(1 << pin);
+ else
+ GPDR0 |= (1 << pin);
+ break;
+ case 2:
+ GAFR1_L &= ~(AF_SEL_GPIO_N << GAFR1_L_OFFSET(pin));
+
+ if (dir)
+ GPDR1 &= ~(1 << GPDR1_OFFSET(pin));
+ else
+ GPDR1 |= (1 << GPDR1_OFFSET(pin));
+ break;
+ case 3:
+ GAFR1_U &= ~(AF_SEL_GPIO_N << GAFR1_U_OFFSET(pin));
+
+ if (dir)
+ GPDR1 &= ~(1 << GPDR1_OFFSET(pin));
+ else
+ GPDR1 |= (1 << GPDR1_OFFSET(pin));
+ break;
+ default:
+ printk(KERN_ERR "unimplemented\n");
+ }
+}
+
+static void __devinit metronome_init_gpio_regs(void)
+{
+ metronome_init_gpio_pin(LED_GPIO_PIN, 0);
+ metronome_set_gpio_output(LED_GPIO_PIN, 0);
+
+ metronome_init_gpio_pin(STDBY_GPIO_PIN, 0);
+ metronome_set_gpio_output(STDBY_GPIO_PIN, 0);
+
+ metronome_init_gpio_pin(RST_GPIO_PIN, 0);
+ metronome_set_gpio_output(RST_GPIO_PIN, 0);
+
+ metronome_init_gpio_pin(RDY_GPIO_PIN, 1);
+
+ metronome_init_gpio_pin(ERR_GPIO_PIN, 1);
+
+ metronome_init_gpio_pin(PCBPWR_GPIO_PIN, 0);
+ metronome_set_gpio_output(PCBPWR_GPIO_PIN, 0);
+}
+
+static void metronome_disable_lcd_controller(struct metronomefb_par *par)
+{
+ LCSR = 0xffffffff; /* Clear LCD Status Register */
+ LCCR0 |= LCCR0_DIS; /* Disable LCD Controller */
+
+ /* we reset and just wait for things to settle */
+ msleep(200);
+}
+
+static void metronome_enable_lcd_controller(struct metronomefb_par *par)
+{
+ LCSR = 0xffffffff;
+ FDADR0 = par->metromem_desc_dma;
+ LCCR0 |= LCCR0_ENB;
+}
+
+static void __devinit metronome_init_lcdc_regs(struct metronomefb_par *par)
+{
+ /* here we do:
+ - disable the lcd controller
+ - setup lcd control registers
+ - setup dma descriptor
+ - reenable lcd controller
+ */
+
+ /* disable the lcd controller */
+ metronome_disable_lcd_controller(par);
+
+ /* setup lcd control registers */
+ LCCR0 = LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | LCCR0_PAS
+ | LCCR0_QDM | LCCR0_BM | LCCR0_OUM;
+
+ LCCR1 = (epd_frame_table[0].fw/2 - 1) /* pixels per line */
+ | (27 << 10) /* hsync pulse width - 1 */
+ | (33 << 16) /* eol pixel count */
+ | (33 << 24); /* bol pixel count */
+
+ LCCR2 = (epd_frame_table[0].fh - 1) /* lines per panel */
+ | (24 << 10) /* vsync pulse width - 1 */
+ | (2 << 16) /* eof pixel count */
+ | (0 << 24); /* bof pixel count */
+
+ LCCR3 = 2 /* pixel clock divisor */
+ | (24 << 8) /* AC Bias pin freq */
+ | LCCR3_16BPP /* BPP */
+ | LCCR3_PCP; /* PCP falling edge */
+
+ /* setup dma descriptor */
+ par->metromem_desc->mFDADR0 = par->metromem_desc_dma;
+ par->metromem_desc->mFSADR0 = par->metromem_dma;
+ par->metromem_desc->mFIDR0 = 0;
+ par->metromem_desc->mLDCMD0 = epd_frame_table[0].fw
+ * epd_frame_table[0].fh;
+ /* reenable lcd controller */
+ metronome_enable_lcd_controller(par);
+}
+
+static int metronome_display_cmd(struct metronomefb_par *par)
+{
+ int i;
+ u16 cs;
+ u16 opcode;
+ static u8 borderval;
+ u8 *ptr;
+
+ /* setup display command
+ we can't immediately set the opcode since the controller
+ will try parse the command before we've set it all up
+ so we just set cs here and set the opcode at the end */
+
+ ptr = par->metromem;
+
+ if (par->metromem_cmd->opcode == 0xCC40)
+ opcode = cs = 0xCC41;
+ else
+ opcode = cs = 0xCC40;
+
+ /* set the args ( 2 bytes ) for display */
+ i = 0;
+ par->metromem_cmd->args[i] = 1 << 3 /* border update */
+ | ((borderval++ % 4) & 0x0F) << 4
+ | (par->frame_count - 1) << 8;
+ cs += par->metromem_cmd->args[i++];
+
+ /* the rest are 0 */
+ memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2);
+
+ par->metromem_cmd->csum = cs;
+ par->metromem_cmd->opcode = opcode; /* display cmd */
+
+ i = wait_event_interruptible_timeout(par->waitq, (GPLR1 & 0x01), HZ);
+ return i;
+}
+
+static int __devinit metronome_powerup_cmd(struct metronomefb_par *par)
+{
+ int i;
+ u16 cs;
+
+ /* setup power up command */
+ par->metromem_cmd->opcode = 0x1234; /* pwr up pseudo cmd */
+ cs = par->metromem_cmd->opcode;
+
+ /* set pwr1,2,3 to 1024 */
+ for (i = 0; i < 3; i++) {
+ par->metromem_cmd->args[i] = 1024;
+ cs += par->metromem_cmd->args[i];
+ }
+
+ /* the rest are 0 */
+ memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2);
+
+ par->metromem_cmd->csum = cs;
+
+ msleep(1);
+ metronome_set_gpio_output(RST_GPIO_PIN, 1);
+
+ msleep(1);
+ metronome_set_gpio_output(STDBY_GPIO_PIN, 1);
+
+ i = wait_event_timeout(par->waitq, (GPLR1 & 0x01), HZ);
+ return i;
+}
+
+static int __devinit metronome_config_cmd(struct metronomefb_par *par)
+{
+ int i;
+ u16 cs;
+
+ /* setup config command
+ we can't immediately set the opcode since the controller
+ will try parse the command before we've set it all up
+ so we just set cs here and set the opcode at the end */
+
+ cs = 0xCC10;
+
+ /* set the 12 args ( 8 bytes ) for config. see spec for meanings */
+ i = 0;
+ par->metromem_cmd->args[i] = 15 /* sdlew */
+ | 2 << 8 /* sdosz */
+ | 0 << 11 /* sdor */
+ | 0 << 12 /* sdces */
+ | 0 << 15; /* sdcer */
+ cs += par->metromem_cmd->args[i++];
+
+ par->metromem_cmd->args[i] = 42 /* gdspl */
+ | 1 << 8 /* gdr1 */
+ | 1 << 9 /* sdshr */
+ | 0 << 15; /* gdspp */
+ cs += par->metromem_cmd->args[i++];
+
+ par->metromem_cmd->args[i] = 18 /* gdspw */
+ | 0 << 15; /* dispc */
+ cs += par->metromem_cmd->args[i++];
+
+ par->metromem_cmd->args[i] = 599 /* vdlc */
+ | 0 << 11 /* dsi */
+ | 0 << 12; /* dsic */
+ cs += par->metromem_cmd->args[i++];
+
+ /* the rest are 0 */
+ memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2);
+
+ par->metromem_cmd->csum = cs;
+ par->metromem_cmd->opcode = 0xCC10; /* config cmd */
+
+ i = wait_event_timeout(par->waitq, (GPLR1 & 0x01), HZ);
+ return i;
+}
+
+static int __devinit metronome_init_cmd(struct metronomefb_par *par)
+{
+ int i;
+ u16 cs;
+
+ /* setup init command
+ we can't immediately set the opcode since the controller
+ will try parse the command before we've set it all up
+ so we just set cs here and set the opcode at the end */
+
+ cs = 0xCC20;
+
+ /* set the args ( 2 bytes ) for init */
+ i = 0;
+ par->metromem_cmd->args[i] = 0;
+ cs += par->metromem_cmd->args[i++];
+
+ /* the rest are 0 */
+ memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2);
+
+ par->metromem_cmd->csum = cs;
+ par->metromem_cmd->opcode = 0xCC20; /* init cmd */
+
+ i = wait_event_timeout(par->waitq, (GPLR1 & 0x01), HZ);
+ return i;
+}
+
+static int __devinit metronome_init_regs(struct metronomefb_par *par)
+{
+ int res;
+
+ metronome_init_gpio_regs();
+ metronome_init_lcdc_regs(par);
+
+ res = metronome_powerup_cmd(par);
+ if (res)
+ return res;
+
+ res = metronome_config_cmd(par);
+ if (res)
+ return res;
+
+ res = metronome_init_cmd(par);
+ if (res)
+ return res;
+
+ return res;
+}
+
+static void metronomefb_dpy_update(struct metronomefb_par *par)
+{
+ u16 cksum;
+ unsigned char *buf = (unsigned char __force *)par->info->screen_base;
+
+ /* copy from vm to metromem */
+ memcpy(par->metromem_img, buf, DPY_W*DPY_H);
+
+ cksum = calc_img_cksum((u16 *) par->metromem_img,
+ (epd_frame_table[0].fw * DPY_H)/2);
+ *((u16 *) (par->metromem_img) +
+ (epd_frame_table[0].fw * DPY_H)/2) = cksum;
+ metronome_display_cmd(par);
+}
+
+static u16 metronomefb_dpy_update_page(struct metronomefb_par *par, int index)
+{
+ int i;
+ u16 csum = 0;
+ u16 *buf = (u16 __force *) (par->info->screen_base + index);
+ u16 *img = (u16 *) (par->metromem_img + index);
+
+ /* swizzle from vm to metromem and recalc cksum at the same time*/
+ for (i = 0; i < PAGE_SIZE/2; i++) {
+ *(img + i) = (buf[i] << 5) & 0xE0E0;
+ csum += *(img + i);
+ }
+ return csum;
+}
+
+/* this is called back from the deferred io workqueue */
+static void metronomefb_dpy_deferred_io(struct fb_info *info,
+ struct list_head *pagelist)
+{
+ u16 cksum;
+ struct page *cur;
+ struct fb_deferred_io *fbdefio = info->fbdefio;
+ struct metronomefb_par *par = info->par;
+
+ /* walk the written page list and swizzle the data */
+ list_for_each_entry(cur, &fbdefio->pagelist, lru) {
+ cksum = metronomefb_dpy_update_page(par,
+ (cur->index << PAGE_SHIFT));
+ par->metromem_img_csum -= par->csum_table[cur->index];
+ par->csum_table[cur->index] = cksum;
+ par->metromem_img_csum += cksum;
+ }
+
+ metronome_display_cmd(par);
+}
+
+static void metronomefb_fillrect(struct fb_info *info,
+ const struct fb_fillrect *rect)
+{
+ struct metronomefb_par *par = info->par;
+
+ cfb_fillrect(info, rect);
+ metronomefb_dpy_update(par);
+}
+
+static void metronomefb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area)
+{
+ struct metronomefb_par *par = info->par;
+
+ cfb_copyarea(info, area);
+ metronomefb_dpy_update(par);
+}
+
+static void metronomefb_imageblit(struct fb_info *info,
+ const struct fb_image *image)
+{
+ struct metronomefb_par *par = info->par;
+
+ cfb_imageblit(info, image);
+ metronomefb_dpy_update(par);
+}
+
+/*
+ * this is the slow path from userspace. they can seek and write to
+ * the fb. it is based on fb_sys_write
+ */
+static ssize_t metronomefb_write(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct metronomefb_par *par = info->par;
+ unsigned long p = *ppos;
+ void *dst;
+ int err = 0;
+ unsigned long total_size;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return -EPERM;
+
+ total_size = info->fix.smem_len;
+
+ if (p > total_size)
+ return -EFBIG;
+
+ if (count > total_size) {
+ err = -EFBIG;
+ count = total_size;
+ }
+
+ if (count + p > total_size) {
+ if (!err)
+ err = -ENOSPC;
+
+ count = total_size - p;
+ }
+
+ dst = (void __force *) (info->screen_base + p);
+
+ if (copy_from_user(dst, buf, count))
+ err = -EFAULT;
+
+ if (!err)
+ *ppos += count;
+
+ metronomefb_dpy_update(par);
+
+ return (err) ? err : count;
+}
+
+static struct fb_ops metronomefb_ops = {
+ .owner = THIS_MODULE,
+ .fb_write = metronomefb_write,
+ .fb_fillrect = metronomefb_fillrect,
+ .fb_copyarea = metronomefb_copyarea,
+ .fb_imageblit = metronomefb_imageblit,
+};
+
+static struct fb_deferred_io metronomefb_defio = {
+ .delay = HZ,
+ .deferred_io = metronomefb_dpy_deferred_io,
+};
+
+static irqreturn_t metronome_handle_irq(int irq, void *dev_id)
+{
+ struct fb_info *info = dev_id;
+ struct metronomefb_par *par = info->par;
+
+ wake_up_interruptible(&par->waitq);
+ return IRQ_HANDLED;
+}
+
+static int __devinit metronomefb_probe(struct platform_device *dev)
+{
+ struct fb_info *info;
+ int retval = -ENOMEM;
+ int videomemorysize;
+ unsigned char *videomemory;
+ struct metronomefb_par *par;
+ const struct firmware *fw_entry;
+ int cmd_size, wfm_size, img_size, padding_size, totalsize;
+ int i;
+
+ /* we have two blocks of memory.
+ info->screen_base which is vm, and is the fb used by apps.
+ par->metromem which is physically contiguous memory and
+ contains the display controller commands, waveform,
+ processed image data and padding. this is the data pulled
+ by the pxa255's LCD controller and pushed to Metronome */
+
+ videomemorysize = (DPY_W*DPY_H);
+ videomemory = vmalloc(videomemorysize);
+ if (!videomemory)
+ return retval;
+
+ memset(videomemory, 0, videomemorysize);
+
+ info = framebuffer_alloc(sizeof(struct metronomefb_par), &dev->dev);
+ if (!info)
+ goto err_vfree;
+
+ info->screen_base = (char __iomem *) videomemory;
+ info->fbops = &metronomefb_ops;
+
+ info->var = metronomefb_var;
+ info->fix = metronomefb_fix;
+ info->fix.smem_len = videomemorysize;
+ par = info->par;
+ par->info = info;
+ init_waitqueue_head(&par->waitq);
+
+ /* this table caches per page csum values. */
+ par->csum_table = vmalloc(videomemorysize/PAGE_SIZE);
+ if (!par->csum_table)
+ goto err_csum_table;
+
+ /* the metromem buffer is divided as follows:
+ command | CRC | padding
+ 16kb waveform data | CRC | padding
+ image data | CRC
+ and an extra 256 bytes for dma descriptors
+ eg: IW=832 IH=622 WS=128
+ */
+
+ cmd_size = 1 * epd_frame_table[0].fw;
+ wfm_size = ((16*1024 + 2 + epd_frame_table[0].fw - 1)
+ / epd_frame_table[0].fw) * epd_frame_table[0].fw;
+ img_size = epd_frame_table[0].fh * epd_frame_table[0].fw;
+ padding_size = 4 * epd_frame_table[0].fw;
+ totalsize = cmd_size + wfm_size + img_size + padding_size;
+ par->metromemsize = PAGE_ALIGN(totalsize + 256);
+ DPRINTK("desired memory size = %d\n", par->metromemsize);
+ dev->dev.coherent_dma_mask = 0xffffffffull;
+ par->metromem = dma_alloc_writecombine(&dev->dev, par->metromemsize,
+ &par->metromem_dma, GFP_KERNEL);
+ if (!par->metromem) {
+ printk(KERN_ERR
+ "metronomefb: unable to allocate dma buffer\n");
+ goto err_vfree;
+ }
+
+ info->fix.smem_start = par->metromem_dma;
+ par->metromem_cmd = (struct metromem_cmd *) par->metromem;
+ par->metromem_wfm = par->metromem + cmd_size;
+ par->metromem_img = par->metromem + cmd_size + wfm_size;
+ par->metromem_img_csum = (u16 *) (par->metromem_img +
+ (epd_frame_table[0].fw * DPY_H));
+ DPRINTK("img offset=0x%x\n", cmd_size + wfm_size);
+ par->metromem_desc = (struct metromem_desc *) (par->metromem + cmd_size
+ + wfm_size + img_size + padding_size);
+ par->metromem_desc_dma = par->metromem_dma + cmd_size + wfm_size
+ + img_size + padding_size;
+
+ /* load the waveform in. assume mode 3, temp 31 for now */
+ /* a) request the waveform file from userspace
+ b) process waveform and decode into metromem */
+
+ retval = request_firmware(&fw_entry, "waveform.wbf", &dev->dev);
+ if (retval < 0) {
+ printk(KERN_ERR "metronomefb: couldn't get waveform\n");
+ goto err_dma_free;
+ }
+
+ retval = load_waveform((u8 *) fw_entry->data, fw_entry->size,
+ par->metromem_wfm, 3, 31, &par->frame_count);
+ if (retval < 0) {
+ printk(KERN_ERR "metronomefb: couldn't process waveform\n");
+ goto err_ld_wfm;
+ }
+ release_firmware(fw_entry);
+
+ retval = request_irq(IRQ_GPIO(RDY_GPIO_PIN), metronome_handle_irq,
+ IRQF_DISABLED, "Metronome", info);
+ if (retval) {
+ dev_err(&dev->dev, "request_irq failed: %d\n", retval);
+ goto err_ld_wfm;
+ }
+ set_irq_type(IRQ_GPIO(RDY_GPIO_PIN), IRQT_FALLING);
+
+ retval = metronome_init_regs(par);
+ if (retval < 0)
+ goto err_free_irq;
+
+ info->flags = FBINFO_FLAG_DEFAULT;
+
+ info->fbdefio = &metronomefb_defio;
+ fb_deferred_io_init(info);
+
+ retval = fb_alloc_cmap(&info->cmap, 8, 0);
+ if (retval < 0) {
+ printk(KERN_ERR "Failed to allocate colormap\n");
+ goto err_fb_rel;
+ }
+
+ /* set cmap */
+ for (i = 0; i < 8; i++)
+ info->cmap.red[i] = (((2*i)+1)*(0xFFFF))/16;
+ memcpy(info->cmap.green, info->cmap.red, sizeof(u16)*8);
+ memcpy(info->cmap.blue, info->cmap.red, sizeof(u16)*8);
+
+ retval = register_framebuffer(info);
+ if (retval < 0)
+ goto err_cmap;
+
+ platform_set_drvdata(dev, info);
+
+ printk(KERN_INFO
+ "fb%d: Metronome frame buffer device, using %dK of video"
+ " memory\n", info->node, videomemorysize >> 10);
+
+ return 0;
+
+err_cmap:
+ fb_dealloc_cmap(&info->cmap);
+err_fb_rel:
+ framebuffer_release(info);
+err_free_irq:
+ free_irq(IRQ_GPIO(RDY_GPIO_PIN), info);
+err_ld_wfm:
+ release_firmware(fw_entry);
+err_dma_free:
+ dma_free_writecombine(&dev->dev, par->metromemsize, par->metromem,
+ par->metromem_dma);
+err_csum_table:
+ vfree(par->csum_table);
+err_vfree:
+ vfree(videomemory);
+ return retval;
+}
+
+static int __devexit metronomefb_remove(struct platform_device *dev)
+{
+ struct fb_info *info = platform_get_drvdata(dev);
+
+ if (info) {
+ struct metronomefb_par *par = info->par;
+ fb_deferred_io_cleanup(info);
+ dma_free_writecombine(&dev->dev, par->metromemsize,
+ par->metromem, par->metromem_dma);
+ fb_dealloc_cmap(&info->cmap);
+ vfree(par->csum_table);
+ unregister_framebuffer(info);
+ vfree((void __force *)info->screen_base);
+ free_irq(IRQ_GPIO(RDY_GPIO_PIN), info);
+ framebuffer_release(info);
+ }
+ return 0;
+}
+
+static struct platform_driver metronomefb_driver = {
+ .probe = metronomefb_probe,
+ .remove = metronomefb_remove,
+ .driver = {
+ .name = "metronomefb",
+ },
+};
+
+static struct platform_device *metronomefb_device;
+
+static int __init metronomefb_init(void)
+{
+ int ret;
+
+ if (!metronomefb_enable) {
+ printk(KERN_ERR
+ "Use metronomefb_enable to enable the device\n");
+ return -ENXIO;
+ }
+
+ ret = platform_driver_register(&metronomefb_driver);
+ if (!ret) {
+ metronomefb_device = platform_device_alloc("metronomefb", 0);
+ if (metronomefb_device)
+ ret = platform_device_add(metronomefb_device);
+ else
+ ret = -ENOMEM;
+
+ if (ret) {
+ platform_device_put(metronomefb_device);
+ platform_driver_unregister(&metronomefb_driver);
+ }
+ }
+ return ret;
+
+}
+
+static void __exit metronomefb_exit(void)
+{
+ platform_device_unregister(metronomefb_device);
+ platform_driver_unregister(&metronomefb_driver);
+}
+
+module_param(metronomefb_enable, uint, 0);
+MODULE_PARM_DESC(metronomefb_enable, "Enable communication with Metronome");
+
+module_init(metronomefb_init);
+module_exit(metronomefb_exit);
+
+MODULE_DESCRIPTION("fbdev driver for Metronome controller");
+MODULE_AUTHOR("Jaya Kumar");
+MODULE_LICENSE("GPL");
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index c8a4332d113..0b3efc31ee6 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -152,7 +152,7 @@ static void virtballoon_changed(struct virtio_device *vdev)
wake_up(&vb->config_change);
}
-static inline int towards_target(struct virtio_balloon *vb)
+static inline s64 towards_target(struct virtio_balloon *vb)
{
u32 v;
__virtio_config_val(vb->vdev,
@@ -176,7 +176,7 @@ static int balloon(void *_vballoon)
set_freezable();
while (!kthread_should_stop()) {
- int diff;
+ s64 diff;
try_to_freeze();
wait_event_interruptible(vb->config_change,
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index 26f787ddd5f..59a8f73dec7 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -177,6 +177,7 @@ static irqreturn_t vp_interrupt(int irq, void *opaque)
struct virtio_pci_device *vp_dev = opaque;
struct virtio_pci_vq_info *info;
irqreturn_t ret = IRQ_NONE;
+ unsigned long flags;
u8 isr;
/* reading the ISR has the effect of also clearing it so it's very
@@ -197,12 +198,12 @@ static irqreturn_t vp_interrupt(int irq, void *opaque)
drv->config_changed(&vp_dev->vdev);
}
- spin_lock(&vp_dev->lock);
+ spin_lock_irqsave(&vp_dev->lock, flags);
list_for_each_entry(info, &vp_dev->virtqueues, node) {
if (vring_interrupt(irq, info->vq) == IRQ_HANDLED)
ret = IRQ_HANDLED;
}
- spin_unlock(&vp_dev->lock);
+ spin_unlock_irqrestore(&vp_dev->lock, flags);
return ret;
}
@@ -214,6 +215,7 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index,
struct virtio_pci_device *vp_dev = to_vp_device(vdev);
struct virtio_pci_vq_info *info;
struct virtqueue *vq;
+ unsigned long flags;
u16 num;
int err;
@@ -255,9 +257,9 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index,
vq->priv = info;
info->vq = vq;
- spin_lock(&vp_dev->lock);
+ spin_lock_irqsave(&vp_dev->lock, flags);
list_add(&info->node, &vp_dev->virtqueues);
- spin_unlock(&vp_dev->lock);
+ spin_unlock_irqrestore(&vp_dev->lock, flags);
return vq;
@@ -274,10 +276,11 @@ static void vp_del_vq(struct virtqueue *vq)
{
struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
struct virtio_pci_vq_info *info = vq->priv;
+ unsigned long flags;
- spin_lock(&vp_dev->lock);
+ spin_lock_irqsave(&vp_dev->lock, flags);
list_del(&info->node);
- spin_unlock(&vp_dev->lock);
+ spin_unlock_irqrestore(&vp_dev->lock, flags);
vring_del_virtqueue(vq);
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 3a28c138213..aa714028641 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -232,7 +232,6 @@ static bool vring_enable_cb(struct virtqueue *_vq)
vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
mb();
if (unlikely(more_used(vq))) {
- vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
END_USE(vq);
return false;
}