summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig11
-rw-r--r--drivers/acpi/asus_acpi.c2
-rw-r--r--drivers/acpi/battery.c11
-rw-r--r--drivers/acpi/dock.c1
-rw-r--r--drivers/acpi/ec.c11
-rw-r--r--drivers/acpi/osl.c84
-rw-r--r--drivers/acpi/processor_idle.c12
-rw-r--r--drivers/acpi/video.c60
-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/fore200e.c110
-rw-r--r--drivers/atm/fore200e.h106
-rw-r--r--drivers/block/Kconfig10
-rw-r--r--drivers/block/Makefile1
-rw-r--r--drivers/block/ps2esdi.c1079
-rw-r--r--drivers/block/virtio_blk.c1
-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/rocket.c37
-rw-r--r--drivers/char/rocket_int.h83
-rw-r--r--drivers/dma/fsldma.c30
-rw-r--r--drivers/dma/fsldma.h1
-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/ide/ide-lib.c10
-rw-r--r--drivers/ide/ide-tape.c5
-rw-r--r--drivers/ide/ide-taskfile.c36
-rw-r--r--drivers/ide/ide.c20
-rw-r--r--drivers/ieee1394/sbp2.c5
-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/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/mmc/core/Makefile2
-rw-r--r--drivers/mmc/core/bus.c23
-rw-r--r--drivers/mmc/core/bus.h11
-rw-r--r--drivers/mmc/core/core.h2
-rw-r--r--drivers/mmc/core/mmc.c90
-rw-r--r--drivers/mmc/core/sd.c95
-rw-r--r--drivers/mmc/core/sdio.c2
-rw-r--r--drivers/mmc/core/sysfs.c43
-rw-r--r--drivers/mmc/core/sysfs.h26
-rw-r--r--drivers/mmc/host/tifm_sd.c2
-rw-r--r--drivers/net/3c501.c16
-rw-r--r--drivers/net/atl1/atl1_main.c3
-rw-r--r--drivers/net/cxgb3/sge.c12
-rw-r--r--drivers/net/epic100.c47
-rw-r--r--drivers/net/forcedeth.c118
-rw-r--r--drivers/net/ibm_newemac/core.c7
-rw-r--r--drivers/net/ibm_newemac/tah.c4
-rw-r--r--drivers/net/ifb.c15
-rw-r--r--drivers/net/igb/igb_main.c21
-rw-r--r--drivers/net/ioc3-eth.c3
-rw-r--r--drivers/net/ipg.c10
-rw-r--r--drivers/net/ne2k-pci.c8
-rw-r--r--drivers/net/ps3_gelic_wireless.c29
-rw-r--r--drivers/net/r6040.c10
-rw-r--r--drivers/net/tg3.c6
-rw-r--r--drivers/net/tulip/de2104x.c10
-rw-r--r--drivers/net/ucc_geth.c6
-rw-r--r--drivers/net/usb/rndis_host.c12
-rw-r--r--drivers/net/virtio_net.c22
-rw-r--r--drivers/net/wan/farsync.c17
-rw-r--r--drivers/net/wireless/ath5k/hw.c2
-rw-r--r--drivers/net/wireless/b43/phy.c2
-rw-r--r--drivers/net/wireless/p54usb.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c38
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h20
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00rfkill.c116
-rw-r--r--drivers/parisc/pdc_stable.c6
-rw-r--r--drivers/parisc/sba_iommu.c4
-rw-r--r--drivers/pci/hotplug/pciehp_core.c2
-rw-r--r--drivers/pnp/isapnp/core.c25
-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/serial/sh-sci.c4
-rw-r--r--drivers/sn/ioc3.c22
-rw-r--r--drivers/thermal/Kconfig2
-rw-r--r--drivers/thermal/thermal.c169
-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
145 files changed, 2812 insertions, 2586 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index fbcaa069be86..b4f5e8542829 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -300,17 +300,6 @@ config ACPI_CUSTOM_DSDT
bool
default ACPI_CUSTOM_DSDT_FILE != ""
-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 you are not using this feature now, but may use it later,
- it is safe to say Y here.
-
config ACPI_BLACKLIST_YEAR
int "Disable ACPI for systems before Jan 1st this year" if X86_32
default 0
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index d25ef961415c..44ad90c03c2e 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 f6215e809808..d5729d5dc190 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/dock.c b/drivers/acpi/dock.c
index 307cef65c247..fa44fb96fc34 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 e7e197e3a4ff..7222a18a0319 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -129,7 +129,6 @@ static struct acpi_ec {
struct mutex lock;
wait_queue_head_t wait;
struct list_head list;
- atomic_t irq_count;
u8 handlers_installed;
} *boot_ec, *first_ec;
@@ -182,8 +181,6 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
{
int ret = 0;
- atomic_set(&ec->irq_count, 0);
-
if (unlikely(event == ACPI_EC_EVENT_OBF_1 &&
test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags)))
force_poll = 1;
@@ -230,7 +227,6 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
while (time_before(jiffies, delay)) {
if (acpi_ec_check_status(ec, event))
goto end;
- msleep(5);
}
}
pr_err(PREFIX "acpi_ec_wait timeout,"
@@ -533,13 +529,6 @@ static u32 acpi_ec_gpe_handler(void *data)
struct acpi_ec *ec = data;
pr_debug(PREFIX "~~~> interrupt\n");
- atomic_inc(&ec->irq_count);
- if (atomic_read(&ec->irq_count) > 5) {
- pr_err(PREFIX "GPE storm detected, disabling EC GPE\n");
- acpi_disable_gpe(NULL, ec->gpe, ACPI_ISR);
- clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
- return ACPI_INTERRUPT_HANDLED;
- }
clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
wake_up(&ec->wait);
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 065819ba87c7..a697fb6cf050 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;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 6f3b217699e9..e8e2d8869236 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/video.c b/drivers/acpi/video.c
index 1bc0c74f2755..12fb44f16766 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -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.
*/
@@ -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/ata/Kconfig b/drivers/ata/Kconfig
index e469647330de..25aba69b59b4 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 6978469eb16d..17ee6ed985d9 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 0770cb7391a4..bf98a566adac 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 7e68edf3c0f3..8786455c901d 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/fore200e.c b/drivers/atm/fore200e.c
index 9427a61f62b0..432181ed7bb5 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -1988,19 +1988,19 @@ fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats __user *arg)
if (fore200e_getstats(fore200e) < 0)
return -EIO;
- tmp.section_bip = cpu_to_be32(fore200e->stats->oc3.section_bip8_errors);
- tmp.line_bip = cpu_to_be32(fore200e->stats->oc3.line_bip24_errors);
- tmp.path_bip = cpu_to_be32(fore200e->stats->oc3.path_bip8_errors);
- tmp.line_febe = cpu_to_be32(fore200e->stats->oc3.line_febe_errors);
- tmp.path_febe = cpu_to_be32(fore200e->stats->oc3.path_febe_errors);
- tmp.corr_hcs = cpu_to_be32(fore200e->stats->oc3.corr_hcs_errors);
- tmp.uncorr_hcs = cpu_to_be32(fore200e->stats->oc3.ucorr_hcs_errors);
- tmp.tx_cells = cpu_to_be32(fore200e->stats->aal0.cells_transmitted) +
- cpu_to_be32(fore200e->stats->aal34.cells_transmitted) +
- cpu_to_be32(fore200e->stats->aal5.cells_transmitted);
- tmp.rx_cells = cpu_to_be32(fore200e->stats->aal0.cells_received) +
- cpu_to_be32(fore200e->stats->aal34.cells_received) +
- cpu_to_be32(fore200e->stats->aal5.cells_received);
+ tmp.section_bip = be32_to_cpu(fore200e->stats->oc3.section_bip8_errors);
+ tmp.line_bip = be32_to_cpu(fore200e->stats->oc3.line_bip24_errors);
+ tmp.path_bip = be32_to_cpu(fore200e->stats->oc3.path_bip8_errors);
+ tmp.line_febe = be32_to_cpu(fore200e->stats->oc3.line_febe_errors);
+ tmp.path_febe = be32_to_cpu(fore200e->stats->oc3.path_febe_errors);
+ tmp.corr_hcs = be32_to_cpu(fore200e->stats->oc3.corr_hcs_errors);
+ tmp.uncorr_hcs = be32_to_cpu(fore200e->stats->oc3.ucorr_hcs_errors);
+ tmp.tx_cells = be32_to_cpu(fore200e->stats->aal0.cells_transmitted) +
+ be32_to_cpu(fore200e->stats->aal34.cells_transmitted) +
+ be32_to_cpu(fore200e->stats->aal5.cells_transmitted);
+ tmp.rx_cells = be32_to_cpu(fore200e->stats->aal0.cells_received) +
+ be32_to_cpu(fore200e->stats->aal34.cells_received) +
+ be32_to_cpu(fore200e->stats->aal5.cells_received);
if (arg)
return copy_to_user(arg, &tmp, sizeof(struct sonet_stats)) ? -EFAULT : 0;
@@ -2587,7 +2587,7 @@ fore200e_start_fw(struct fore200e* fore200e)
static int __devinit
fore200e_load_fw(struct fore200e* fore200e)
{
- u32* fw_data = (u32*) fore200e->bus->fw_data;
+ __le32* fw_data = (__le32*) fore200e->bus->fw_data;
u32 fw_size = (u32) *fore200e->bus->fw_size / sizeof(u32);
struct fw_header* fw_header = (struct fw_header*) fw_data;
@@ -2965,8 +2965,8 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
" 4b5b:\n"
" crc_header_errors:\t\t%10u\n"
" framing_errors:\t\t%10u\n",
- cpu_to_be32(fore200e->stats->phy.crc_header_errors),
- cpu_to_be32(fore200e->stats->phy.framing_errors));
+ be32_to_cpu(fore200e->stats->phy.crc_header_errors),
+ be32_to_cpu(fore200e->stats->phy.framing_errors));
if (!left--)
return sprintf(page, "\n"
@@ -2978,13 +2978,13 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
" path_febe_errors:\t\t%10u\n"
" corr_hcs_errors:\t\t%10u\n"
" ucorr_hcs_errors:\t\t%10u\n",
- cpu_to_be32(fore200e->stats->oc3.section_bip8_errors),
- cpu_to_be32(fore200e->stats->oc3.path_bip8_errors),
- cpu_to_be32(fore200e->stats->oc3.line_bip24_errors),
- cpu_to_be32(fore200e->stats->oc3.line_febe_errors),
- cpu_to_be32(fore200e->stats->oc3.path_febe_errors),
- cpu_to_be32(fore200e->stats->oc3.corr_hcs_errors),
- cpu_to_be32(fore200e->stats->oc3.ucorr_hcs_errors));
+ be32_to_cpu(fore200e->stats->oc3.section_bip8_errors),
+ be32_to_cpu(fore200e->stats->oc3.path_bip8_errors),
+ be32_to_cpu(fore200e->stats->oc3.line_bip24_errors),
+ be32_to_cpu(fore200e->stats->oc3.line_febe_errors),
+ be32_to_cpu(fore200e->stats->oc3.path_febe_errors),
+ be32_to_cpu(fore200e->stats->oc3.corr_hcs_errors),
+ be32_to_cpu(fore200e->stats->oc3.ucorr_hcs_errors));
if (!left--)
return sprintf(page,"\n"
@@ -2995,12 +2995,12 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
" vpi no conn:\t\t%10u\n"
" vci out of range:\t\t%10u\n"
" vci no conn:\t\t%10u\n",
- cpu_to_be32(fore200e->stats->atm.cells_transmitted),
- cpu_to_be32(fore200e->stats->atm.cells_received),
- cpu_to_be32(fore200e->stats->atm.vpi_bad_range),
- cpu_to_be32(fore200e->stats->atm.vpi_no_conn),
- cpu_to_be32(fore200e->stats->atm.vci_bad_range),
- cpu_to_be32(fore200e->stats->atm.vci_no_conn));
+ be32_to_cpu(fore200e->stats->atm.cells_transmitted),
+ be32_to_cpu(fore200e->stats->atm.cells_received),
+ be32_to_cpu(fore200e->stats->atm.vpi_bad_range),
+ be32_to_cpu(fore200e->stats->atm.vpi_no_conn),
+ be32_to_cpu(fore200e->stats->atm.vci_bad_range),
+ be32_to_cpu(fore200e->stats->atm.vci_no_conn));
if (!left--)
return sprintf(page,"\n"
@@ -3008,9 +3008,9 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
" TX:\t\t\t%10u\n"
" RX:\t\t\t%10u\n"
" dropped:\t\t\t%10u\n",
- cpu_to_be32(fore200e->stats->aal0.cells_transmitted),
- cpu_to_be32(fore200e->stats->aal0.cells_received),
- cpu_to_be32(fore200e->stats->aal0.cells_dropped));
+ be32_to_cpu(fore200e->stats->aal0.cells_transmitted),
+ be32_to_cpu(fore200e->stats->aal0.cells_received),
+ be32_to_cpu(fore200e->stats->aal0.cells_dropped));
if (!left--)
return sprintf(page,"\n"
@@ -3026,15 +3026,15 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
" RX:\t\t\t%10u\n"
" dropped:\t\t\t%10u\n"
" protocol errors:\t\t%10u\n",
- cpu_to_be32(fore200e->stats->aal34.cells_transmitted),
- cpu_to_be32(fore200e->stats->aal34.cells_received),
- cpu_to_be32(fore200e->stats->aal34.cells_dropped),
- cpu_to_be32(fore200e->stats->aal34.cells_crc_errors),
- cpu_to_be32(fore200e->stats->aal34.cells_protocol_errors),
- cpu_to_be32(fore200e->stats->aal34.cspdus_transmitted),
- cpu_to_be32(fore200e->stats->aal34.cspdus_received),
- cpu_to_be32(fore200e->stats->aal34.cspdus_dropped),
- cpu_to_be32(fore200e->stats->aal34.cspdus_protocol_errors));
+ be32_to_cpu(fore200e->stats->aal34.cells_transmitted),
+ be32_to_cpu(fore200e->stats->aal34.cells_received),
+ be32_to_cpu(fore200e->stats->aal34.cells_dropped),
+ be32_to_cpu(fore200e->stats->aal34.cells_crc_errors),
+ be32_to_cpu(fore200e->stats->aal34.cells_protocol_errors),
+ be32_to_cpu(fore200e->stats->aal34.cspdus_transmitted),
+ be32_to_cpu(fore200e->stats->aal34.cspdus_received),
+ be32_to_cpu(fore200e->stats->aal34.cspdus_dropped),
+ be32_to_cpu(fore200e->stats->aal34.cspdus_protocol_errors));
if (!left--)
return sprintf(page,"\n"
@@ -3050,15 +3050,15 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
" dropped:\t\t\t%10u\n"
" CRC errors:\t\t%10u\n"
" protocol errors:\t\t%10u\n",
- cpu_to_be32(fore200e->stats->aal5.cells_transmitted),
- cpu_to_be32(fore200e->stats->aal5.cells_received),
- cpu_to_be32(fore200e->stats->aal5.cells_dropped),
- cpu_to_be32(fore200e->stats->aal5.congestion_experienced),
- cpu_to_be32(fore200e->stats->aal5.cspdus_transmitted),
- cpu_to_be32(fore200e->stats->aal5.cspdus_received),
- cpu_to_be32(fore200e->stats->aal5.cspdus_dropped),
- cpu_to_be32(fore200e->stats->aal5.cspdus_crc_errors),
- cpu_to_be32(fore200e->stats->aal5.cspdus_protocol_errors));
+ be32_to_cpu(fore200e->stats->aal5.cells_transmitted),
+ be32_to_cpu(fore200e->stats->aal5.cells_received),
+ be32_to_cpu(fore200e->stats->aal5.cells_dropped),
+ be32_to_cpu(fore200e->stats->aal5.congestion_experienced),
+ be32_to_cpu(fore200e->stats->aal5.cspdus_transmitted),
+ be32_to_cpu(fore200e->stats->aal5.cspdus_received),
+ be32_to_cpu(fore200e->stats->aal5.cspdus_dropped),
+ be32_to_cpu(fore200e->stats->aal5.cspdus_crc_errors),
+ be32_to_cpu(fore200e->stats->aal5.cspdus_protocol_errors));
if (!left--)
return sprintf(page,"\n"
@@ -3069,11 +3069,11 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
" large b2:\t\t\t%10u\n"
" RX PDUs:\t\t\t%10u\n"
" TX PDUs:\t\t\t%10lu\n",
- cpu_to_be32(fore200e->stats->aux.small_b1_failed),
- cpu_to_be32(fore200e->stats->aux.large_b1_failed),
- cpu_to_be32(fore200e->stats->aux.small_b2_failed),
- cpu_to_be32(fore200e->stats->aux.large_b2_failed),
- cpu_to_be32(fore200e->stats->aux.rpd_alloc_failed),
+ be32_to_cpu(fore200e->stats->aux.small_b1_failed),
+ be32_to_cpu(fore200e->stats->aux.large_b1_failed),
+ be32_to_cpu(fore200e->stats->aux.small_b2_failed),
+ be32_to_cpu(fore200e->stats->aux.large_b2_failed),
+ be32_to_cpu(fore200e->stats->aux.rpd_alloc_failed),
fore200e->tx_sat);
if (!left--)
diff --git a/drivers/atm/fore200e.h b/drivers/atm/fore200e.h
index b85a54613dea..183841cc8fdf 100644
--- a/drivers/atm/fore200e.h
+++ b/drivers/atm/fore200e.h
@@ -349,90 +349,90 @@ typedef struct oc3_block {
/* physical encoding statistics */
typedef struct stats_phy {
- u32 crc_header_errors; /* cells received with bad header CRC */
- u32 framing_errors; /* cells received with bad framing */
- u32 pad[ 2 ]; /* i960 padding */
+ __be32 crc_header_errors; /* cells received with bad header CRC */
+ __be32 framing_errors; /* cells received with bad framing */
+ __be32 pad[ 2 ]; /* i960 padding */
} stats_phy_t;
/* OC-3 statistics */
typedef struct stats_oc3 {
- u32 section_bip8_errors; /* section 8 bit interleaved parity */
- u32 path_bip8_errors; /* path 8 bit interleaved parity */
- u32 line_bip24_errors; /* line 24 bit interleaved parity */
- u32 line_febe_errors; /* line far end block errors */
- u32 path_febe_errors; /* path far end block errors */
- u32 corr_hcs_errors; /* correctable header check sequence */
- u32 ucorr_hcs_errors; /* uncorrectable header check sequence */
- u32 pad[ 1 ]; /* i960 padding */
+ __be32 section_bip8_errors; /* section 8 bit interleaved parity */
+ __be32 path_bip8_errors; /* path 8 bit interleaved parity */
+ __be32 line_bip24_errors; /* line 24 bit interleaved parity */
+ __be32 line_febe_errors; /* line far end block errors */
+ __be32 path_febe_errors; /* path far end block errors */
+ __be32 corr_hcs_errors; /* correctable header check sequence */
+ __be32 ucorr_hcs_errors; /* uncorrectable header check sequence */
+ __be32 pad[ 1 ]; /* i960 padding */
} stats_oc3_t;
/* ATM statistics */
typedef struct stats_atm {
- u32 cells_transmitted; /* cells transmitted */
- u32 cells_received; /* cells received */
- u32 vpi_bad_range; /* cell drops: VPI out of range */
- u32 vpi_no_conn; /* cell drops: no connection for VPI */
- u32 vci_bad_range; /* cell drops: VCI out of range */
- u32 vci_no_conn; /* cell drops: no connection for VCI */
- u32 pad[ 2 ]; /* i960 padding */
+ __be32 cells_transmitted; /* cells transmitted */
+ __be32 cells_received; /* cells received */
+ __be32 vpi_bad_range; /* cell drops: VPI out of range */
+ __be32 vpi_no_conn; /* cell drops: no connection for VPI */
+ __be32 vci_bad_range; /* cell drops: VCI out of range */
+ __be32 vci_no_conn; /* cell drops: no connection for VCI */
+ __be32 pad[ 2 ]; /* i960 padding */
} stats_atm_t;
/* AAL0 statistics */
typedef struct stats_aal0 {
- u32 cells_transmitted; /* cells transmitted */
- u32 cells_received; /* cells received */
- u32 cells_dropped; /* cells dropped */
- u32 pad[ 1 ]; /* i960 padding */
+ __be32 cells_transmitted; /* cells transmitted */
+ __be32 cells_received; /* cells received */
+ __be32 cells_dropped; /* cells dropped */
+ __be32 pad[ 1 ]; /* i960 padding */
} stats_aal0_t;
/* AAL3/4 statistics */
typedef struct stats_aal34 {
- u32 cells_transmitted; /* cells transmitted from segmented PDUs */
- u32 cells_received; /* cells reassembled into PDUs */
- u32 cells_crc_errors; /* payload CRC error count */
- u32 cells_protocol_errors; /* SAR or CS layer protocol errors */
- u32 cells_dropped; /* cells dropped: partial reassembly */
- u32 cspdus_transmitted; /* CS PDUs transmitted */
- u32 cspdus_received; /* CS PDUs received */
- u32 cspdus_protocol_errors; /* CS layer protocol errors */
- u32 cspdus_dropped; /* reassembled PDUs drop'd (in cells) */
- u32 pad[ 3 ]; /* i960 padding */
+ __be32 cells_transmitted; /* cells transmitted from segmented PDUs */
+ __be32 cells_received; /* cells reassembled into PDUs */
+ __be32 cells_crc_errors; /* payload CRC error count */
+ __be32 cells_protocol_errors; /* SAR or CS layer protocol errors */
+ __be32 cells_dropped; /* cells dropped: partial reassembly */
+ __be32 cspdus_transmitted; /* CS PDUs transmitted */
+ __be32 cspdus_received; /* CS PDUs received */
+ __be32 cspdus_protocol_errors; /* CS layer protocol errors */
+ __be32 cspdus_dropped; /* reassembled PDUs drop'd (in cells) */
+ __be32 pad[ 3 ]; /* i960 padding */
} stats_aal34_t;
/* AAL5 statistics */
typedef struct stats_aal5 {
- u32 cells_transmitted; /* cells transmitted from segmented SDUs */
- u32 cells_received; /* cells reassembled into SDUs */
- u32 cells_dropped; /* reassembled PDUs dropped (in cells) */
- u32 congestion_experienced; /* CRC error and length wrong */
- u32 cspdus_transmitted; /* CS PDUs transmitted */
- u32 cspdus_received; /* CS PDUs received */
- u32 cspdus_crc_errors; /* CS PDUs CRC errors */
- u32 cspdus_protocol_errors; /* CS layer protocol errors */
- u32 cspdus_dropped; /* reassembled PDUs dropped */
- u32 pad[ 3 ]; /* i960 padding */
+ __be32 cells_transmitted; /* cells transmitted from segmented SDUs */
+ __be32 cells_received; /* cells reassembled into SDUs */
+ __be32 cells_dropped; /* reassembled PDUs dropped (in cells) */
+ __be32 congestion_experienced; /* CRC error and length wrong */
+ __be32 cspdus_transmitted; /* CS PDUs transmitted */
+ __be32 cspdus_received; /* CS PDUs received */
+ __be32 cspdus_crc_errors; /* CS PDUs CRC errors */
+ __be32 cspdus_protocol_errors; /* CS layer protocol errors */
+ __be32 cspdus_dropped; /* reassembled PDUs dropped */
+ __be32 pad[ 3 ]; /* i960 padding */
} stats_aal5_t;
/* auxiliary statistics */
typedef struct stats_aux {
- u32 small_b1_failed; /* receive BD allocation failures */
- u32 large_b1_failed; /* receive BD allocation failures */
- u32 small_b2_failed; /* receive BD allocation failures */
- u32 large_b2_failed; /* receive BD allocation failures */
- u32 rpd_alloc_failed; /* receive PDU allocation failures */
- u32 receive_carrier; /* no carrier = 0, carrier = 1 */
- u32 pad[ 2 ]; /* i960 padding */
+ __be32 small_b1_failed; /* receive BD allocation failures */
+ __be32 large_b1_failed; /* receive BD allocation failures */
+ __be32 small_b2_failed; /* receive BD allocation failures */
+ __be32 large_b2_failed; /* receive BD allocation failures */
+ __be32 rpd_alloc_failed; /* receive PDU allocation failures */
+ __be32 receive_carrier; /* no carrier = 0, carrier = 1 */
+ __be32 pad[ 2 ]; /* i960 padding */
} stats_aux_t;
@@ -643,10 +643,10 @@ typedef struct host_bsq {
/* header of the firmware image */
typedef struct fw_header {
- u32 magic; /* magic number */
- u32 version; /* firmware version id */
- u32 load_offset; /* fw load offset in board memory */
- u32 start_offset; /* fw execution start address in board memory */
+ __le32 magic; /* magic number */
+ __le32 version; /* firmware version id */
+ __le32 load_offset; /* fw load offset in board memory */
+ __le32 start_offset; /* fw execution start address in board memory */
} fw_header_t;
#define FW_HEADER_MAGIC 0x65726f66 /* 'fore' */
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index b6d230b3209f..0d1d2133d9bc 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 01c972415cb2..5e584306be99 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/ps2esdi.c b/drivers/block/ps2esdi.c
deleted file mode 100644
index 3c796e236253..000000000000
--- 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/virtio_blk.c b/drivers/block/virtio_blk.c
index 3b1a68d6eddb..0cfbe8c594a5 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/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index d352dbb4ccf7..e5a0e97cfdda 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 a6789f25009b..8ea9dd1717a9 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 3992f73299cc..f09d4b5002b0 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 bea2a7d5b2b2..12dcdd1832f0 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 715b361f0c2b..a6a499f97e22 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 892e0a589846..f36adbd3aaf5 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 833abc7e55fb..9072e4a1894e 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 94baec692b57..7a339dba6a69 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 33c5197b73c4..409e00afdd07 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/rocket.c b/drivers/char/rocket.c
index 72f289279d8f..f585bc8579e9 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 f3a75791b811..b01d38125a8f 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/fsldma.c b/drivers/dma/fsldma.c
index ad2f938597e2..72692309398a 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -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);
@@ -426,6 +431,9 @@ fsl_dma_prep_interrupt(struct dma_chan *chan)
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);
@@ -701,6 +709,23 @@ 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.
*/
@@ -841,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);
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
index ba78c42121ba..fddd6aee2a63 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/firewire/Kconfig b/drivers/firewire/Kconfig
index fe9e768cfbc4..25bdc2dd9ce1 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 7ebad3c14cb8..996d61f0d460 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 03069a454c07..62b4e47d0cc0 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 e47bb040197a..d2c7a3d7e1cb 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 7fcc59dedf08..e6f1bda38940 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 09cb72870454..a43bb22912f9 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 d73a768e176e..f0b00ec1e47e 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 5a38fb27d69f..c3eb3f13e2ca 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 b38e559b7a46..d95979f0e028 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 e6d05f6b1c1c..e29a057cbea2 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 368879ff5d8c..4dc76bc45c9d 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 9c9cdb0685e4..4e9b19c6732f 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/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 29e2c9719c30..7031a8dcf692 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -122,7 +122,6 @@ static struct ide_pio_info {
const char *name;
int pio;
} ide_pio_blacklist [] = {
-/* { "Conner Peripherals 1275MB - CFS1275A", 4 }, */
{ "Conner Peripherals 540MB - CFS540A", 3 },
{ "WDC AC2700", 3 },
@@ -138,10 +137,8 @@ static struct ide_pio_info {
{ "WDC AC1170", 1 },
{ "WDC AC1210", 1 },
{ "WDC AC280", 0 },
-/* { "WDC AC21000", 4 }, */
{ "WDC AC31000", 3 },
{ "WDC AC31200", 3 },
-/* { "WDC AC31600", 4 }, */
{ "Maxtor 7131 AT", 1 },
{ "Maxtor 7171 AT", 1 },
@@ -155,13 +152,6 @@ static struct ide_pio_info {
{ "SAMSUNG SHD-3122A", 1 },
{ "SAMSUNG SHD-3172A", 1 },
-/* { "ST51080A", 4 },
- * { "ST51270A", 4 },
- * { "ST31220A", 4 },
- * { "ST31640A", 4 },
- * { "ST32140A", 4 },
- * { "ST3780A", 4 },
- */
{ "ST5660A", 3 },
{ "ST3660A", 3 },
{ "ST3630A", 3 },
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 43e0e0557776..0598ecfd5f37 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -3765,11 +3765,6 @@ static int ide_tape_probe(ide_drive_t *drive)
g->fops = &idetape_block_ops;
ide_register_region(g);
- printk(KERN_WARNING "It is possible that this driver does not have any"
- " users anymore and, as a result, it will be REMOVED soon."
- " Please notify Bart <bzolnier@gmail.com> or Boris"
- " <petkovbb@gmail.com> in case you still need it.\n");
-
return 0;
out_free_tape:
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 0518a2e948cf..4c86a8d84b4c 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/ide/ide.c b/drivers/ide/ide.c
index 9976f9d627d4..fc69fe2e3ec0 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1258,7 +1258,7 @@ static int __init ide_setup(char *s)
drive = &hwif->drives[unit];
if (strncmp(s + 4, "ide-", 4) == 0) {
strlcpy(drive->driver_req, s + 4, sizeof(drive->driver_req));
- goto done;
+ goto obsolete_option;
}
switch (match_parm(&s[3], hd_words, vals, 3)) {
case -1: /* "none" */
@@ -1290,13 +1290,13 @@ static int __init ide_setup(char *s)
goto done;
case -12: /* "remap" */
drive->remap_0_to_1 = 1;
- goto done;
+ goto obsolete_option;
case -13: /* "remap63" */
drive->sect0 = 63;
- goto done;
+ goto obsolete_option;
case -14: /* "scsi" */
drive->scsi = 1;
- goto done;
+ goto obsolete_option;
case 3: /* cyl,head,sect */
drive->media = ide_disk;
drive->ready_stat = READY_STAT;
@@ -1370,32 +1370,32 @@ static int __init ide_setup(char *s)
#ifdef CONFIG_BLK_DEV_ALI14XX
case -17: /* "ali14xx" */
probe_ali14xx = 1;
- goto done;
+ goto obsolete_option;
#endif
#ifdef CONFIG_BLK_DEV_UMC8672
case -16: /* "umc8672" */
probe_umc8672 = 1;
- goto done;
+ goto obsolete_option;
#endif
#ifdef CONFIG_BLK_DEV_DTC2278
case -15: /* "dtc2278" */
probe_dtc2278 = 1;
- goto done;
+ goto obsolete_option;
#endif
#ifdef CONFIG_BLK_DEV_CMD640
case -14: /* "cmd640_vlb" */
cmd640_vlb = 1;
- goto done;
+ goto obsolete_option;
#endif
#ifdef CONFIG_BLK_DEV_HT6560B
case -13: /* "ht6560b" */
probe_ht6560b = 1;
- goto done;
+ goto obsolete_option;
#endif
#ifdef CONFIG_BLK_DEV_QD65XX
case -12: /* "qd65xx" */
probe_qd65xx = 1;
- goto done;
+ goto obsolete_option;
#endif
#ifdef CONFIG_BLK_DEV_4DRIVES
case -11: /* "four" drives on one set of ports */
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 9e2b1964d71a..f53f72daae34 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/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c
index 4833b1a82623..5511ef006a66 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 b346a3b418ea..385e32bcf6a6 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 000000000000..409a9341143d
--- /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 662e84482c26..60931aceb828 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 2763394869d2..65a74cfc187b 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 c972e5d03a3f..cbc1beb66574 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 6542edb6f76e..acf9830698cb 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 d64b1ea136b3..41caaef8e2d7 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 fc03ba256f4c..ffe33842143f 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 a302e229bb8a..3342bc05847d 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 58934a40f5ce..57a1c28bf122 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/md/md.c b/drivers/md/md.c
index ccbbf63727cc..61ccbd2683fa 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 2d6f1a51359c..c574cf5efb5c 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 21935bf7059e..302cc67407c3 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 37072a21d8c9..1832966f53f3 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 5404fcc5276d..a080c149cc6c 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 e6b7f518c56e..8c9a8adf52de 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 7f1931aed207..227179620d13 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 7d1537cab867..c1caaa855b99 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 d42f120354e5..948ca35e7ee8 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 425eb1063904..6dba55b7e25a 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 262830da08c8..6f5744286e8c 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 52baa4f7f7dd..58ab163fdbd7 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 445eba4174d7..d28318cb2b8d 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 fb434b5602a3..5d363be7bc73 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 dcf22a3b672a..50e1ff9f2be5 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 de80dba12f9b..946e3d3506ac 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 1d637e4561d3..557dbbba5cb2 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 03fe8783b1ee..8770a5fac3b6 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 2b5bf52a8302..eb150dfb637f 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 6b6df8679585..c6be6eba7dc3 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 0c252f60c4c1..c207bda6723b 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/mmc/core/Makefile b/drivers/mmc/core/Makefile
index 4985807257a8..19a1a254a0c5 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -7,7 +7,7 @@ ifeq ($(CONFIG_MMC_DEBUG),y)
endif
obj-$(CONFIG_MMC) += mmc_core.o
-mmc_core-y := core.o sysfs.o bus.o host.o \
+mmc_core-y := core.o bus.o host.o \
mmc.o mmc_ops.o sd.o sd_ops.o \
sdio.o sdio_ops.o sdio_bus.o \
sdio_cis.o sdio_io.o sdio_irq.o
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index b0c22cad9423..fd95b18e988b 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -17,7 +17,6 @@
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
-#include "sysfs.h"
#include "core.h"
#include "sdio_cis.h"
#include "bus.h"
@@ -43,7 +42,7 @@ static ssize_t mmc_type_show(struct device *dev,
}
static struct device_attribute mmc_dev_attrs[] = {
- MMC_ATTR_RO(type),
+ __ATTR(type, S_IRUGO, mmc_type_show, NULL),
__ATTR_NULL,
};
@@ -189,7 +188,7 @@ static void mmc_release_card(struct device *dev)
/*
* Allocate and initialise a new MMC card structure.
*/
-struct mmc_card *mmc_alloc_card(struct mmc_host *host)
+struct mmc_card *mmc_alloc_card(struct mmc_host *host, struct device_type *type)
{
struct mmc_card *card;
@@ -204,6 +203,7 @@ struct mmc_card *mmc_alloc_card(struct mmc_host *host)
card->dev.parent = mmc_classdev(host);
card->dev.bus = &mmc_bus_type;
card->dev.release = mmc_release_card;
+ card->dev.type = type;
return card;
}
@@ -248,24 +248,10 @@ int mmc_add_card(struct mmc_card *card)
type, card->rca);
}
- card->dev.uevent_suppress = 1;
-
ret = device_add(&card->dev);
if (ret)
return ret;
- if (card->host->bus_ops->sysfs_add) {
- ret = card->host->bus_ops->sysfs_add(card->host, card);
- if (ret) {
- device_del(&card->dev);
- return ret;
- }
- }
-
- card->dev.uevent_suppress = 0;
-
- kobject_uevent(&card->dev.kobj, KOBJ_ADD);
-
mmc_card_set_present(card);
return 0;
@@ -285,9 +271,6 @@ void mmc_remove_card(struct mmc_card *card)
printk(KERN_INFO "%s: card %04x removed\n",
mmc_hostname(card->host), card->rca);
}
-
- if (card->host->bus_ops->sysfs_remove)
- card->host->bus_ops->sysfs_remove(card->host, card);
device_del(&card->dev);
}
diff --git a/drivers/mmc/core/bus.h b/drivers/mmc/core/bus.h
index 4f35431116a8..18178766ab46 100644
--- a/drivers/mmc/core/bus.h
+++ b/drivers/mmc/core/bus.h
@@ -11,7 +11,16 @@
#ifndef _MMC_CORE_BUS_H
#define _MMC_CORE_BUS_H
-struct mmc_card *mmc_alloc_card(struct mmc_host *host);
+#define MMC_DEV_ATTR(name, fmt, args...) \
+static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+ struct mmc_card *card = container_of(dev, struct mmc_card, dev); \
+ return sprintf(buf, fmt, args); \
+} \
+static DEVICE_ATTR(name, S_IRUGO, mmc_##name##_show, NULL)
+
+struct mmc_card *mmc_alloc_card(struct mmc_host *host,
+ struct device_type *type);
int mmc_add_card(struct mmc_card *card);
void mmc_remove_card(struct mmc_card *card);
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 39daf2fb5dc4..cfa8e15b5923 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -18,8 +18,6 @@
struct mmc_bus_ops {
void (*remove)(struct mmc_host *);
void (*detect)(struct mmc_host *);
- int (*sysfs_add)(struct mmc_host *, struct mmc_card *card);
- void (*sysfs_remove)(struct mmc_host *, struct mmc_card *card);
void (*suspend)(struct mmc_host *);
void (*resume)(struct mmc_host *);
};
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 68c0e3b2f0e8..3da29eef8f7d 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -17,7 +17,6 @@
#include <linux/mmc/mmc.h>
#include "core.h"
-#include "sysfs.h"
#include "bus.h"
#include "mmc_ops.h"
@@ -248,6 +247,44 @@ out:
return err;
}
+MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
+ card->raw_cid[2], card->raw_cid[3]);
+MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
+ card->raw_csd[2], card->raw_csd[3]);
+MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year);
+MMC_DEV_ATTR(fwrev, "0x%x\n", card->cid.fwrev);
+MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev);
+MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid);
+MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name);
+MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid);
+MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
+
+static struct attribute *mmc_std_attrs[] = {
+ &dev_attr_cid.attr,
+ &dev_attr_csd.attr,
+ &dev_attr_date.attr,
+ &dev_attr_fwrev.attr,
+ &dev_attr_hwrev.attr,
+ &dev_attr_manfid.attr,
+ &dev_attr_name.attr,
+ &dev_attr_oemid.attr,
+ &dev_attr_serial.attr,
+ NULL,
+};
+
+static struct attribute_group mmc_std_attr_group = {
+ .attrs = mmc_std_attrs,
+};
+
+static struct attribute_group *mmc_attr_groups[] = {
+ &mmc_std_attr_group,
+ NULL,
+};
+
+static struct device_type mmc_type = {
+ .groups = mmc_attr_groups,
+};
+
/*
* Handle the detection and initialisation of a card.
*
@@ -308,7 +345,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
/*
* Allocate card structure.
*/
- card = mmc_alloc_card(host);
+ card = mmc_alloc_card(host, &mmc_type);
if (IS_ERR(card)) {
err = PTR_ERR(card);
goto err;
@@ -459,53 +496,6 @@ static void mmc_detect(struct mmc_host *host)
}
}
-MMC_ATTR_FN(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
- card->raw_cid[2], card->raw_cid[3]);
-MMC_ATTR_FN(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
- card->raw_csd[2], card->raw_csd[3]);
-MMC_ATTR_FN(date, "%02d/%04d\n", card->cid.month, card->cid.year);
-MMC_ATTR_FN(fwrev, "0x%x\n", card->cid.fwrev);
-MMC_ATTR_FN(hwrev, "0x%x\n", card->cid.hwrev);
-MMC_ATTR_FN(manfid, "0x%06x\n", card->cid.manfid);
-MMC_ATTR_FN(name, "%s\n", card->cid.prod_name);
-MMC_ATTR_FN(oemid, "0x%04x\n", card->cid.oemid);
-MMC_ATTR_FN(serial, "0x%08x\n", card->cid.serial);
-
-static struct device_attribute mmc_dev_attrs[] = {
- MMC_ATTR_RO(cid),
- MMC_ATTR_RO(csd),
- MMC_ATTR_RO(date),
- MMC_ATTR_RO(fwrev),
- MMC_ATTR_RO(hwrev),
- MMC_ATTR_RO(manfid),
- MMC_ATTR_RO(name),
- MMC_ATTR_RO(oemid),
- MMC_ATTR_RO(serial),
- __ATTR_NULL,
-};
-
-/*
- * Adds sysfs entries as relevant.
- */
-static int mmc_sysfs_add(struct mmc_host *host, struct mmc_card *card)
-{
- int ret;
-
- ret = mmc_add_attrs(card, mmc_dev_attrs);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-/*
- * Removes the sysfs entries added by mmc_sysfs_add().
- */
-static void mmc_sysfs_remove(struct mmc_host *host, struct mmc_card *card)
-{
- mmc_remove_attrs(card, mmc_dev_attrs);
-}
-
#ifdef CONFIG_MMC_UNSAFE_RESUME
/*
@@ -560,8 +550,6 @@ static void mmc_resume(struct mmc_host *host)
static const struct mmc_bus_ops mmc_ops = {
.remove = mmc_remove,
.detect = mmc_detect,
- .sysfs_add = mmc_sysfs_add,
- .sysfs_remove = mmc_sysfs_remove,
.suspend = mmc_suspend,
.resume = mmc_resume,
};
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index d1c1e0f592f1..7ef3b15c5e3d 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -18,7 +18,6 @@
#include <linux/mmc/sd.h>
#include "core.h"
-#include "sysfs.h"
#include "bus.h"
#include "mmc_ops.h"
#include "sd_ops.h"
@@ -283,6 +282,47 @@ out:
return err;
}
+MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
+ card->raw_cid[2], card->raw_cid[3]);
+MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
+ card->raw_csd[2], card->raw_csd[3]);
+MMC_DEV_ATTR(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]);
+MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year);
+MMC_DEV_ATTR(fwrev, "0x%x\n", card->cid.fwrev);
+MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev);
+MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid);
+MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name);
+MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid);
+MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
+
+
+static struct attribute *sd_std_attrs[] = {
+ &dev_attr_cid.attr,
+ &dev_attr_csd.attr,
+ &dev_attr_scr.attr,
+ &dev_attr_date.attr,
+ &dev_attr_fwrev.attr,
+ &dev_attr_hwrev.attr,
+ &dev_attr_manfid.attr,
+ &dev_attr_name.attr,
+ &dev_attr_oemid.attr,
+ &dev_attr_serial.attr,
+ NULL,
+};
+
+static struct attribute_group sd_std_attr_group = {
+ .attrs = sd_std_attrs,
+};
+
+static struct attribute_group *sd_attr_groups[] = {
+ &sd_std_attr_group,
+ NULL,
+};
+
+static struct device_type sd_type = {
+ .groups = sd_attr_groups,
+};
+
/*
* Handle the detection and initialisation of a card.
*
@@ -352,7 +392,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
/*
* Allocate card structure.
*/
- card = mmc_alloc_card(host);
+ card = mmc_alloc_card(host, &sd_type);
if (IS_ERR(card)) {
err = PTR_ERR(card);
goto err;
@@ -518,55 +558,6 @@ static void mmc_sd_detect(struct mmc_host *host)
}
}
-MMC_ATTR_FN(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
- card->raw_cid[2], card->raw_cid[3]);
-MMC_ATTR_FN(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
- card->raw_csd[2], card->raw_csd[3]);
-MMC_ATTR_FN(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]);
-MMC_ATTR_FN(date, "%02d/%04d\n", card->cid.month, card->cid.year);
-MMC_ATTR_FN(fwrev, "0x%x\n", card->cid.fwrev);
-MMC_ATTR_FN(hwrev, "0x%x\n", card->cid.hwrev);
-MMC_ATTR_FN(manfid, "0x%06x\n", card->cid.manfid);
-MMC_ATTR_FN(name, "%s\n", card->cid.prod_name);
-MMC_ATTR_FN(oemid, "0x%04x\n", card->cid.oemid);
-MMC_ATTR_FN(serial, "0x%08x\n", card->cid.serial);
-
-static struct device_attribute mmc_sd_dev_attrs[] = {
- MMC_ATTR_RO(cid),
- MMC_ATTR_RO(csd),
- MMC_ATTR_RO(scr),
- MMC_ATTR_RO(date),
- MMC_ATTR_RO(fwrev),
- MMC_ATTR_RO(hwrev),
- MMC_ATTR_RO(manfid),
- MMC_ATTR_RO(name),
- MMC_ATTR_RO(oemid),
- MMC_ATTR_RO(serial),
- __ATTR_NULL,
-};
-
-/*
- * Adds sysfs entries as relevant.
- */
-static int mmc_sd_sysfs_add(struct mmc_host *host, struct mmc_card *card)
-{
- int ret;
-
- ret = mmc_add_attrs(card, mmc_sd_dev_attrs);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-/*
- * Removes the sysfs entries added by mmc_sysfs_add().
- */
-static void mmc_sd_sysfs_remove(struct mmc_host *host, struct mmc_card *card)
-{
- mmc_remove_attrs(card, mmc_sd_dev_attrs);
-}
-
#ifdef CONFIG_MMC_UNSAFE_RESUME
/*
@@ -621,8 +612,6 @@ static void mmc_sd_resume(struct mmc_host *host)
static const struct mmc_bus_ops mmc_sd_ops = {
.remove = mmc_sd_remove,
.detect = mmc_sd_detect,
- .sysfs_add = mmc_sd_sysfs_add,
- .sysfs_remove = mmc_sd_sysfs_remove,
.suspend = mmc_sd_suspend,
.resume = mmc_sd_resume,
};
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 87a50f456efc..4eab79e09ccc 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -287,7 +287,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
/*
* Allocate card structure.
*/
- card = mmc_alloc_card(host);
+ card = mmc_alloc_card(host, NULL);
if (IS_ERR(card)) {
err = PTR_ERR(card);
goto err;
diff --git a/drivers/mmc/core/sysfs.c b/drivers/mmc/core/sysfs.c
deleted file mode 100644
index 00a97e70f914..000000000000
--- a/drivers/mmc/core/sysfs.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * linux/drivers/mmc/core/sysfs.c
- *
- * Copyright (C) 2003 Russell King, All Rights Reserved.
- * Copyright 2007 Pierre Ossman
- *
- * 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.
- *
- * MMC sysfs/driver model support.
- */
-#include <linux/device.h>
-
-#include <linux/mmc/card.h>
-
-#include "sysfs.h"
-
-int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs)
-{
- int error = 0;
- int i;
-
- for (i = 0; attr_name(attrs[i]); i++) {
- error = device_create_file(&card->dev, &attrs[i]);
- if (error) {
- while (--i >= 0)
- device_remove_file(&card->dev, &attrs[i]);
- break;
- }
- }
-
- return error;
-}
-
-void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs)
-{
- int i;
-
- for (i = 0; attr_name(attrs[i]); i++)
- device_remove_file(&card->dev, &attrs[i]);
-}
-
diff --git a/drivers/mmc/core/sysfs.h b/drivers/mmc/core/sysfs.h
deleted file mode 100644
index 4b8f670bd10f..000000000000
--- a/drivers/mmc/core/sysfs.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * linux/drivers/mmc/core/sysfs.h
- *
- * Copyright (C) 2003 Russell King, All Rights Reserved.
- * Copyright 2007 Pierre Ossman
- *
- * 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.
- */
-#ifndef _MMC_CORE_SYSFS_H
-#define _MMC_CORE_SYSFS_H
-
-#define MMC_ATTR_FN(name, fmt, args...) \
-static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct mmc_card *card = container_of(dev, struct mmc_card, dev);\
- return sprintf(buf, fmt, args); \
-}
-
-#define MMC_ATTR_RO(name) __ATTR(name, S_IRUGO, mmc_##name##_show, NULL)
-
-int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs);
-void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs);
-
-#endif
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index 20d5c7bd940a..1c14a186f000 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/3c501.c b/drivers/net/3c501.c
index 7d253686ed0d..5ba4bab6d43e 100644
--- a/drivers/net/3c501.c
+++ b/drivers/net/3c501.c
@@ -485,9 +485,7 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
printk(KERN_DEBUG "%s: burped during tx load.\n",
dev->name);
spin_lock_irqsave(&lp->lock, flags);
- }
- while (1);
-
+ } while (1);
}
/**
@@ -612,7 +610,8 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
dev->stats.tx_packets++;
if (el_debug > 6)
printk(KERN_DEBUG " Tx succeeded %s\n",
- (txsr & TX_RDY) ? "." : "but tx is busy!");
+ (txsr & TX_RDY) ? "." :
+ "but tx is busy!");
/*
* This is safe the interrupt is atomic WRT itself.
*/
@@ -693,7 +692,8 @@ static void el_receive(struct net_device *dev)
if (pkt_len < 60 || pkt_len > 1536) {
if (el_debug)
- printk(KERN_DEBUG "%s: bogus packet, length=%d\n", dev->name, pkt_len);
+ printk(KERN_DEBUG "%s: bogus packet, length=%d\n",
+ dev->name, pkt_len);
dev->stats.rx_over_errors++;
return;
}
@@ -711,7 +711,8 @@ static void el_receive(struct net_device *dev)
outw(0x00, GP_LOW);
if (skb == NULL) {
- printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n", dev->name);
+ printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n",
+ dev->name);
dev->stats.rx_dropped++;
return;
} else {
@@ -748,7 +749,8 @@ static void el_reset(struct net_device *dev)
if (el_debug > 2)
printk(KERN_INFO "3c501 reset...");
outb(AX_RESET, AX_CMD); /* Reset the chip */
- outb(AX_LOOP, AX_CMD); /* Aux control, irq and loopback enabled */
+ /* Aux control, irq and loopback enabled */
+ outb(AX_LOOP, AX_CMD);
{
int i;
for (i = 0; i < 6; i++) /* Set the station address. */
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index 9200ee59d854..129b8b3aa773 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -1765,15 +1765,12 @@ static irqreturn_t atl1_intr(int irq, void *data)
{
struct atl1_adapter *adapter = netdev_priv(data);
u32 status;
- u8 update_rx;
int max_ints = 10;
status = adapter->cmb.cmb->int_stats;
if (!status)
return IRQ_NONE;
- update_rx = 0;
-
do {
/* clear CMB interrupt status at once */
adapter->cmb.cmb->int_stats = 0;
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 979f3fc5e765..db586870c5f4 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -1107,9 +1107,15 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
}
q->in_use += ndesc;
- if (unlikely(credits - ndesc < q->stop_thres))
- if (USE_GTS || !should_restart_tx(q))
- t3_stop_queue(dev, qs, q);
+ if (unlikely(credits - ndesc < q->stop_thres)) {
+ t3_stop_queue(dev, qs, q);
+
+ if (should_restart_tx(q) &&
+ test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) {
+ q->restarts++;
+ netif_wake_queue(dev);
+ }
+ }
gen = q->gen;
q->unacked += ndesc;
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 0b365b8d947b..76118ddd1042 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -131,8 +131,8 @@ IIIa. Ring buffers
IVb. References
-http://www.smsc.com/main/datasheets/83c171.pdf
-http://www.smsc.com/main/datasheets/83c175.pdf
+http://www.smsc.com/main/tools/discontinued/83c171.pdf
+http://www.smsc.com/main/tools/discontinued/83c175.pdf
http://scyld.com/expert/NWay.html
http://www.national.com/pf/DP/DP83840A.html
@@ -227,7 +227,12 @@ static const u16 media2miictl[16] = {
0, 0x0C00, 0x0C00, 0x2000, 0x0100, 0x2100, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
-/* The EPIC100 Rx and Tx buffer descriptors. */
+/*
+ * The EPIC100 Rx and Tx buffer descriptors. Note that these
+ * really ARE host-endian; it's not a misannotation. We tell
+ * the card to byteswap them internally on big-endian hosts -
+ * look for #ifdef CONFIG_BIG_ENDIAN in epic_open().
+ */
struct epic_tx_desc {
u32 txstatus;
@@ -418,7 +423,7 @@ static int __devinit epic_init_one (struct pci_dev *pdev,
/* Note: the '175 does not have a serial EEPROM. */
for (i = 0; i < 3; i++)
- ((u16 *)dev->dev_addr)[i] = le16_to_cpu(inw(ioaddr + LAN0 + i*4));
+ ((__le16 *)dev->dev_addr)[i] = cpu_to_le16(inw(ioaddr + LAN0 + i*4));
if (debug > 2) {
dev_printk(KERN_DEBUG, &pdev->dev, "EEPROM contents:\n");
@@ -682,7 +687,8 @@ static int epic_open(struct net_device *dev)
if (ep->chip_flags & MII_PWRDWN)
outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
-#if defined(__powerpc__) || defined(__sparc__) /* Big endian */
+ /* Tell the chip to byteswap descriptors on big-endian hosts */
+#ifdef CONFIG_BIG_ENDIAN
outl(0x4432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
inl(ioaddr + GENCTL);
outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
@@ -695,7 +701,7 @@ static int epic_open(struct net_device *dev)
udelay(20); /* Looks like EPII needs that if you want reliable RX init. FIXME: pci posting bug? */
for (i = 0; i < 3; i++)
- outl(cpu_to_le16(((u16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4);
+ outl(le16_to_cpu(((__le16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4);
ep->tx_threshold = TX_FIFO_THRESH;
outl(ep->tx_threshold, ioaddr + TxThresh);
@@ -798,7 +804,7 @@ static void epic_restart(struct net_device *dev)
for (i = 16; i > 0; i--)
outl(0x0008, ioaddr + TEST1);
-#if defined(__powerpc__) || defined(__sparc__) /* Big endian */
+#ifdef CONFIG_BIG_ENDIAN
outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
#else
outl(0x0412 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
@@ -808,7 +814,7 @@ static void epic_restart(struct net_device *dev)
outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
for (i = 0; i < 3; i++)
- outl(cpu_to_le16(((u16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4);
+ outl(le16_to_cpu(((__le16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4);
ep->tx_threshold = TX_FIFO_THRESH;
outl(ep->tx_threshold, ioaddr + TxThresh);
@@ -919,7 +925,7 @@ static void epic_init_ring(struct net_device *dev)
/* Initialize all Rx descriptors. */
for (i = 0; i < RX_RING_SIZE; i++) {
ep->rx_ring[i].rxstatus = 0;
- ep->rx_ring[i].buflength = cpu_to_le32(ep->rx_buf_sz);
+ ep->rx_ring[i].buflength = ep->rx_buf_sz;
ep->rx_ring[i].next = ep->rx_ring_dma +
(i+1)*sizeof(struct epic_rx_desc);
ep->rx_skbuff[i] = NULL;
@@ -936,7 +942,7 @@ static void epic_init_ring(struct net_device *dev)
skb_reserve(skb, 2); /* 16 byte align the IP header. */
ep->rx_ring[i].bufaddr = pci_map_single(ep->pci_dev,
skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
- ep->rx_ring[i].rxstatus = cpu_to_le32(DescOwn);
+ ep->rx_ring[i].rxstatus = DescOwn;
}
ep->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
@@ -974,20 +980,20 @@ static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev)
ep->tx_ring[entry].bufaddr = pci_map_single(ep->pci_dev, skb->data,
skb->len, PCI_DMA_TODEVICE);
if (free_count < TX_QUEUE_LEN/2) {/* Typical path */
- ctrl_word = cpu_to_le32(0x100000); /* No interrupt */
+ ctrl_word = 0x100000; /* No interrupt */
} else if (free_count == TX_QUEUE_LEN/2) {
- ctrl_word = cpu_to_le32(0x140000); /* Tx-done intr. */
+ ctrl_word = 0x140000; /* Tx-done intr. */
} else if (free_count < TX_QUEUE_LEN - 1) {
- ctrl_word = cpu_to_le32(0x100000); /* No Tx-done intr. */
+ ctrl_word = 0x100000; /* No Tx-done intr. */
} else {
/* Leave room for an additional entry. */
- ctrl_word = cpu_to_le32(0x140000); /* Tx-done intr. */
+ ctrl_word = 0x140000; /* Tx-done intr. */
ep->tx_full = 1;
}
- ep->tx_ring[entry].buflength = ctrl_word | cpu_to_le32(skb->len);
+ ep->tx_ring[entry].buflength = ctrl_word | skb->len;
ep->tx_ring[entry].txstatus =
((skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN) << 16)
- | cpu_to_le32(DescOwn);
+ | DescOwn;
ep->cur_tx++;
if (ep->tx_full)
@@ -1041,7 +1047,7 @@ static void epic_tx(struct net_device *dev, struct epic_private *ep)
for (dirty_tx = ep->dirty_tx; cur_tx - dirty_tx > 0; dirty_tx++) {
struct sk_buff *skb;
int entry = dirty_tx % TX_RING_SIZE;
- int txstatus = le32_to_cpu(ep->tx_ring[entry].txstatus);
+ int txstatus = ep->tx_ring[entry].txstatus;
if (txstatus & DescOwn)
break; /* It still hasn't been Txed */
@@ -1163,8 +1169,8 @@ static int epic_rx(struct net_device *dev, int budget)
rx_work_limit = budget;
/* If we own the next entry, it's a new packet. Send it up. */
- while ((ep->rx_ring[entry].rxstatus & cpu_to_le32(DescOwn)) == 0) {
- int status = le32_to_cpu(ep->rx_ring[entry].rxstatus);
+ while ((ep->rx_ring[entry].rxstatus & DescOwn) == 0) {
+ int status = ep->rx_ring[entry].rxstatus;
if (debug > 4)
printk(KERN_DEBUG " epic_rx() status was %8.8x.\n", status);
@@ -1238,7 +1244,8 @@ static int epic_rx(struct net_device *dev, int budget)
skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
work_done++;
}
- ep->rx_ring[entry].rxstatus = cpu_to_le32(DescOwn);
+ /* AV: shouldn't we add a barrier here? */
+ ep->rx_ring[entry].rxstatus = DescOwn;
}
return work_done;
}
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 801b4d9cd972..6f7e3fde9e7c 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -184,6 +184,7 @@
#define DEV_HAS_PAUSEFRAME_TX_V1 0x08000 /* device supports tx pause frames version 1 */
#define DEV_HAS_PAUSEFRAME_TX_V2 0x10000 /* device supports tx pause frames version 2 */
#define DEV_HAS_PAUSEFRAME_TX_V3 0x20000 /* device supports tx pause frames version 3 */
+#define DEV_NEED_TX_LIMIT 0x40000 /* device needs to limit tx */
enum {
NvRegIrqStatus = 0x000,
@@ -635,6 +636,8 @@ union ring_type {
#define NV_RESTART_TX 0x1
#define NV_RESTART_RX 0x2
+#define NV_TX_LIMIT_COUNT 16
+
/* statistics */
struct nv_ethtool_str {
char name[ETH_GSTRING_LEN];
@@ -743,6 +746,8 @@ struct nv_skb_map {
struct sk_buff *skb;
dma_addr_t dma;
unsigned int dma_len;
+ struct ring_desc_ex *first_tx_desc;
+ struct nv_skb_map *next_tx_ctx;
};
/*
@@ -827,6 +832,10 @@ struct fe_priv {
union ring_type tx_ring;
u32 tx_flags;
int tx_ring_size;
+ int tx_limit;
+ u32 tx_pkts_in_progress;
+ struct nv_skb_map *tx_change_owner;
+ struct nv_skb_map *tx_end_flip;
int tx_stop;
/* vlan fields */
@@ -1707,6 +1716,9 @@ static void nv_init_tx(struct net_device *dev)
np->last_tx.ex = &np->tx_ring.ex[np->tx_ring_size-1];
np->get_tx_ctx = np->put_tx_ctx = np->first_tx_ctx = np->tx_skb;
np->last_tx_ctx = &np->tx_skb[np->tx_ring_size-1];
+ np->tx_pkts_in_progress = 0;
+ np->tx_change_owner = NULL;
+ np->tx_end_flip = NULL;
for (i = 0; i < np->tx_ring_size; i++) {
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
@@ -1720,6 +1732,9 @@ static void nv_init_tx(struct net_device *dev)
}
np->tx_skb[i].skb = NULL;
np->tx_skb[i].dma = 0;
+ np->tx_skb[i].dma_len = 0;
+ np->tx_skb[i].first_tx_desc = NULL;
+ np->tx_skb[i].next_tx_ctx = NULL;
}
}
@@ -1771,7 +1786,14 @@ static void nv_drain_tx(struct net_device *dev)
}
if (nv_release_txskb(dev, &np->tx_skb[i]))
dev->stats.tx_dropped++;
+ np->tx_skb[i].dma = 0;
+ np->tx_skb[i].dma_len = 0;
+ np->tx_skb[i].first_tx_desc = NULL;
+ np->tx_skb[i].next_tx_ctx = NULL;
}
+ np->tx_pkts_in_progress = 0;
+ np->tx_change_owner = NULL;
+ np->tx_end_flip = NULL;
}
static void nv_drain_rx(struct net_device *dev)
@@ -1948,6 +1970,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
struct ring_desc_ex* start_tx;
struct ring_desc_ex* prev_tx;
struct nv_skb_map* prev_tx_ctx;
+ struct nv_skb_map* start_tx_ctx;
/* add fragments to entries count */
for (i = 0; i < fragments; i++) {
@@ -1965,6 +1988,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
}
start_tx = put_tx = np->put_tx.ex;
+ start_tx_ctx = np->put_tx_ctx;
/* setup the header buffer */
do {
@@ -2037,6 +2061,26 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
spin_lock_irq(&np->lock);
+ if (np->tx_limit) {
+ /* Limit the number of outstanding tx. Setup all fragments, but
+ * do not set the VALID bit on the first descriptor. Save a pointer
+ * to that descriptor and also for next skb_map element.
+ */
+
+ if (np->tx_pkts_in_progress == NV_TX_LIMIT_COUNT) {
+ if (!np->tx_change_owner)
+ np->tx_change_owner = start_tx_ctx;
+
+ /* remove VALID bit */
+ tx_flags &= ~NV_TX2_VALID;
+ start_tx_ctx->first_tx_desc = start_tx;
+ start_tx_ctx->next_tx_ctx = np->put_tx_ctx;
+ np->tx_end_flip = np->put_tx_ctx;
+ } else {
+ np->tx_pkts_in_progress++;
+ }
+ }
+
/* set tx flags */
start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra);
np->put_tx.ex = put_tx;
@@ -2060,6 +2104,25 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
+static inline void nv_tx_flip_ownership(struct net_device *dev)
+{
+ struct fe_priv *np = netdev_priv(dev);
+
+ np->tx_pkts_in_progress--;
+ if (np->tx_change_owner) {
+ __le32 flaglen = le32_to_cpu(np->tx_change_owner->first_tx_desc->flaglen);
+ flaglen |= NV_TX2_VALID;
+ np->tx_change_owner->first_tx_desc->flaglen = cpu_to_le32(flaglen);
+ np->tx_pkts_in_progress++;
+
+ np->tx_change_owner = np->tx_change_owner->next_tx_ctx;
+ if (np->tx_change_owner == np->tx_end_flip)
+ np->tx_change_owner = NULL;
+
+ writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
+ }
+}
+
/*
* nv_tx_done: check for completed packets, release the skbs.
*
@@ -2147,6 +2210,10 @@ static void nv_tx_done_optimized(struct net_device *dev, int limit)
dev->stats.tx_packets++;
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
+
+ if (np->tx_limit) {
+ nv_tx_flip_ownership(dev);
+ }
}
if (unlikely(np->get_tx.ex++ == np->last_tx.ex))
np->get_tx.ex = np->first_tx.ex;
@@ -5333,6 +5400,21 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->need_linktimer = 0;
}
+ /* Limit the number of tx's outstanding for hw bug */
+ if (id->driver_data & DEV_NEED_TX_LIMIT) {
+ np->tx_limit = 1;
+ if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_32 ||
+ id->device == PCI_DEVICE_ID_NVIDIA_NVENET_33 ||
+ id->device == PCI_DEVICE_ID_NVIDIA_NVENET_34 ||
+ id->device == PCI_DEVICE_ID_NVIDIA_NVENET_35 ||
+ id->device == PCI_DEVICE_ID_NVIDIA_NVENET_36 ||
+ id->device == PCI_DEVICE_ID_NVIDIA_NVENET_37 ||
+ id->device == PCI_DEVICE_ID_NVIDIA_NVENET_38 ||
+ id->device == PCI_DEVICE_ID_NVIDIA_NVENET_39) &&
+ pci_dev->revision >= 0xA2)
+ np->tx_limit = 0;
+ }
+
/* clear phy state and temporarily halt phy interrupts */
writel(0, base + NvRegMIIMask);
phystate = readl(base + NvRegAdapterControl);
@@ -5563,19 +5645,19 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* CK804 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
},
{ /* CK804 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
},
{ /* MCP04 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
},
{ /* MCP04 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
},
{ /* MCP51 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12),
@@ -5587,11 +5669,11 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* MCP55 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT,
},
{ /* MCP55 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16),
@@ -5611,19 +5693,19 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_NEED_TX_LIMIT,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24),
@@ -5659,35 +5741,35 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
},
{0,},
};
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index e6c69f77259b..0789802d59ed 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -143,6 +143,10 @@ static inline void emac_report_timeout_error(struct emac_instance *dev,
#define STOP_TIMEOUT_1000 13
#define STOP_TIMEOUT_1000_JUMBO 73
+static unsigned char default_mcast_addr[] = {
+ 0x01, 0x80, 0xC2, 0x00, 0x00, 0x01
+};
+
/* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */
static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = {
"rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum",
@@ -618,6 +622,9 @@ static int emac_configure(struct emac_instance *dev)
if (emac_phy_gpcs(dev->phy.mode))
emac_mii_reset_phy(&dev->phy);
+ /* Required for Pause packet support in EMAC */
+ dev_mc_add(ndev, default_mcast_addr, sizeof(default_mcast_addr), 1);
+
return 0;
}
diff --git a/drivers/net/ibm_newemac/tah.c b/drivers/net/ibm_newemac/tah.c
index 96417adec326..b023d10d7e1c 100644
--- a/drivers/net/ibm_newemac/tah.c
+++ b/drivers/net/ibm_newemac/tah.c
@@ -155,6 +155,10 @@ static int __devexit tah_remove(struct of_device *ofdev)
static struct of_device_id tah_match[] =
{
{
+ .compatible = "ibm,tah",
+ },
+ /* For backward compat with old DT */
+ {
.type = "tah",
},
{},
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 15949d3df17e..af233b591534 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -35,6 +35,7 @@
#include <linux/moduleparam.h>
#include <net/pkt_sched.h>
#include <net/net_namespace.h>
+#include <linux/lockdep.h>
#define TX_TIMEOUT (2*HZ)
@@ -227,6 +228,16 @@ static struct rtnl_link_ops ifb_link_ops __read_mostly = {
module_param(numifbs, int, 0);
MODULE_PARM_DESC(numifbs, "Number of ifb devices");
+/*
+ * dev_ifb->queue_lock is usually taken after dev->ingress_lock,
+ * reversely to e.g. qdisc_lock_tree(). It should be safe until
+ * ifb doesn't take dev->queue_lock with dev_ifb->ingress_lock.
+ * But lockdep should know that ifb has different locks from dev.
+ */
+static struct lock_class_key ifb_queue_lock_key;
+static struct lock_class_key ifb_ingress_lock_key;
+
+
static int __init ifb_init_one(int index)
{
struct net_device *dev_ifb;
@@ -246,6 +257,10 @@ static int __init ifb_init_one(int index)
err = register_netdevice(dev_ifb);
if (err < 0)
goto err;
+
+ lockdep_set_class(&dev_ifb->queue_lock, &ifb_queue_lock_key);
+ lockdep_set_class(&dev_ifb->ingress_lock, &ifb_ingress_lock_key);
+
return 0;
err:
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 6a1f23092099..928ce8287e69 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -31,7 +31,6 @@
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/netdevice.h>
-#include <linux/tcp.h>
#include <linux/ipv6.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
@@ -2484,10 +2483,24 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT);
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- if (skb->protocol == htons(ETH_P_IP))
+ switch (skb->protocol) {
+ case __constant_htons(ETH_P_IP):
tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
- if (skb->sk && (skb->sk->sk_protocol == IPPROTO_TCP))
- tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+ if (ip_hdr(skb)->protocol == IPPROTO_TCP)
+ tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+ break;
+ case __constant_htons(ETH_P_IPV6):
+ /* XXX what about other V6 headers?? */
+ if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
+ tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+ break;
+ default:
+ if (unlikely(net_ratelimit()))
+ dev_warn(&adapter->pdev->dev,
+ "partial checksum but proto=%x!\n",
+ skb->protocol);
+ break;
+ }
}
context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 373f72cdbe8e..1f25263dc7eb 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -1221,7 +1221,8 @@ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
}
#endif
-static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int __devinit ioc3_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
unsigned int sw_physid1, sw_physid2;
struct net_device *dev = NULL;
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index 5e5d9b527ed1..9b358f61ed7f 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -472,7 +472,6 @@ static int ipg_config_autoneg(struct net_device *dev)
unsigned int txflowcontrol;
unsigned int rxflowcontrol;
unsigned int fullduplex;
- unsigned int gig;
u32 mac_ctrl_val;
u32 asicctrl;
u8 phyctrl;
@@ -489,7 +488,6 @@ static int ipg_config_autoneg(struct net_device *dev)
fullduplex = 0;
txflowcontrol = 0;
rxflowcontrol = 0;
- gig = 0;
/* To accomodate a problem in 10Mbps operation,
* set a global flag if PHY running in 10Mbps mode.
@@ -511,7 +509,6 @@ static int ipg_config_autoneg(struct net_device *dev)
break;
case IPG_PC_LINK_SPEED_1000MBPS:
printk("1000Mbps.\n");
- gig = 1;
break;
default:
printk("undefined!\n");
@@ -1900,8 +1897,13 @@ static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Specify the TFC field within the TFD. */
txfd->tfc |= cpu_to_le64(IPG_TFC_WORDALIGNDISABLED |
- (IPG_TFC_FRAMEID & cpu_to_le64(sp->tx_current)) |
+ (IPG_TFC_FRAMEID & sp->tx_current) |
(IPG_TFC_FRAGCOUNT & (1 << 24)));
+ /*
+ * 16--17 (WordAlign) <- 3 (disable),
+ * 0--15 (FrameId) <- sp->tx_current,
+ * 24--27 (FragCount) <- 1
+ */
/* Request TxComplete interrupts at an interval defined
* by the constant IPG_FRAMESBETWEENTXCOMPLETES.
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index b569c90da4ba..de0de744a8fa 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -535,9 +535,9 @@ static void ne2k_pci_block_input(struct net_device *dev, int count,
if (count & 3) {
buf += count & ~3;
if (count & 2) {
- u16 *b = (u16 *)buf;
+ __le16 *b = (__le16 *)buf;
- *b++ = le16_to_cpu(inw(NE_BASE + NE_DATAPORT));
+ *b++ = cpu_to_le16(inw(NE_BASE + NE_DATAPORT));
buf = (char *)b;
}
if (count & 1)
@@ -600,9 +600,9 @@ static void ne2k_pci_block_output(struct net_device *dev, int count,
if (count & 3) {
buf += count & ~3;
if (count & 2) {
- u16 *b = (u16 *)buf;
+ __le16 *b = (__le16 *)buf;
- outw(cpu_to_le16(*b++), NE_BASE + NE_DATAPORT);
+ outw(le16_to_cpu(*b++), NE_BASE + NE_DATAPORT);
buf = (char *)b;
}
}
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index daf5abab9534..ddbc6e475e28 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -1644,13 +1644,24 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
}
/* put them in the newtork_list */
- scan_info = wl->buf;
- scan_info_size = 0;
- i = 0;
- while (scan_info_size < data_len) {
+ for (i = 0, scan_info_size = 0, scan_info = wl->buf;
+ scan_info_size < data_len;
+ i++, scan_info_size += be16_to_cpu(scan_info->size),
+ scan_info = (void *)scan_info + be16_to_cpu(scan_info->size)) {
pr_debug("%s:size=%d bssid=%s scan_info=%p\n", __func__,
be16_to_cpu(scan_info->size),
print_mac(mac, &scan_info->bssid[2]), scan_info);
+
+ /*
+ * The wireless firmware may return invalid channel 0 and/or
+ * invalid rate if the AP emits zero length SSID ie. As this
+ * scan information is useless, ignore it
+ */
+ if (!be16_to_cpu(scan_info->channel) || !scan_info->rate[0]) {
+ pr_debug("%s: invalid scan info\n", __func__);
+ continue;
+ }
+
found = 0;
oldest = NULL;
list_for_each_entry(target, &wl->network_list, list) {
@@ -1687,10 +1698,6 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
GFP_KERNEL);
if (!target->hwinfo) {
pr_info("%s: kzalloc failed\n", __func__);
- i++;
- scan_info_size += be16_to_cpu(scan_info->size);
- scan_info = (void *)scan_info +
- be16_to_cpu(scan_info->size);
continue;
}
/* copy hw scan info */
@@ -1709,10 +1716,6 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
if (scan_info->ext_rate[r])
target->rate_ext_len++;
list_move_tail(&target->list, &wl->network_list);
- /* bump pointer */
- i++;
- scan_info_size += be16_to_cpu(scan_info->size);
- scan_info = (void *)scan_info + be16_to_cpu(scan_info->size);
}
memset(&data, 0, sizeof(data));
wireless_send_event(port_to_netdev(wl_port(wl)), SIOCGIWSCAN, &data,
@@ -2389,6 +2392,8 @@ static struct net_device *gelic_wl_alloc(struct gelic_card *card)
if (!netdev)
return NULL;
+ strcpy(netdev->name, "wlan%d");
+
port = netdev_priv(netdev);
port->netdev = netdev;
port->card = card;
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 19184e486ae9..169edc154928 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -239,7 +239,8 @@ static void r6040_free_txbufs(struct net_device *dev)
for (i = 0; i < TX_DCNT; i++) {
if (lp->tx_insert_ptr->skb_ptr) {
- pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf,
+ pci_unmap_single(lp->pdev,
+ le32_to_cpu(lp->tx_insert_ptr->buf),
MAX_BUF_SIZE, PCI_DMA_TODEVICE);
dev_kfree_skb(lp->tx_insert_ptr->skb_ptr);
lp->rx_insert_ptr->skb_ptr = NULL;
@@ -255,7 +256,8 @@ static void r6040_free_rxbufs(struct net_device *dev)
for (i = 0; i < RX_DCNT; i++) {
if (lp->rx_insert_ptr->skb_ptr) {
- pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf,
+ pci_unmap_single(lp->pdev,
+ le32_to_cpu(lp->rx_insert_ptr->buf),
MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
dev_kfree_skb(lp->rx_insert_ptr->skb_ptr);
lp->rx_insert_ptr->skb_ptr = NULL;
@@ -542,7 +544,7 @@ static int r6040_rx(struct net_device *dev, int limit)
skb_ptr->dev = priv->dev;
/* Do not count the CRC */
skb_put(skb_ptr, descptr->len - 4);
- pci_unmap_single(priv->pdev, descptr->buf,
+ pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf),
MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
skb_ptr->protocol = eth_type_trans(skb_ptr, priv->dev);
/* Send to upper layer */
@@ -585,7 +587,7 @@ static void r6040_tx(struct net_device *dev)
if (descptr->status & 0x8000)
break; /* Not complete */
skb_ptr = descptr->skb_ptr;
- pci_unmap_single(priv->pdev, descptr->buf,
+ pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf),
skb_ptr->len, PCI_DMA_TODEVICE);
/* Free buffer */
dev_kfree_skb_irq(skb_ptr);
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 26ffb67f1da2..f9ef8bd8b11e 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -64,8 +64,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.87"
-#define DRV_MODULE_RELDATE "December 20, 2007"
+#define DRV_MODULE_VERSION "3.88"
+#define DRV_MODULE_RELDATE "March 20, 2008"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -11841,7 +11841,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
}
if (!is_valid_ether_addr(&dev->dev_addr[0])) {
-#ifdef CONFIG_SPARC64
+#ifdef CONFIG_SPARC
if (!tg3_get_default_macaddr_sparc(tp))
return 0;
#endif
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index 567c62757e9d..1b5edd646a8c 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -842,7 +842,7 @@ static inline int de_is_running (struct de_private *de)
static void de_stop_rxtx (struct de_private *de)
{
u32 macmode;
- unsigned int work = 1000;
+ unsigned int i = 1300/100;
macmode = dr32(MacMode);
if (macmode & RxTx) {
@@ -850,10 +850,14 @@ static void de_stop_rxtx (struct de_private *de)
dr32(MacMode);
}
- while (--work > 0) {
+ /* wait until in-flight frame completes.
+ * Max time @ 10BT: 1500*8b/10Mbps == 1200us (+ 100us margin)
+ * Typically expect this loop to end in < 50 us on 100BT.
+ */
+ while (--i) {
if (!de_is_running(de))
return;
- cpu_relax();
+ udelay(100);
}
printk(KERN_WARNING "%s: timeout expired stopping DMA\n", de->dev->name);
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index fba0811d2608..8cc316653a39 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -154,8 +154,8 @@ static struct ucc_geth_info ugeth_primary_info = {
.rxQoSMode = UCC_GETH_QOS_MODE_DEFAULT,
.aufc = UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE,
.padAndCrc = MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC,
- .numThreadsTx = UCC_GETH_NUM_OF_THREADS_4,
- .numThreadsRx = UCC_GETH_NUM_OF_THREADS_4,
+ .numThreadsTx = UCC_GETH_NUM_OF_THREADS_1,
+ .numThreadsRx = UCC_GETH_NUM_OF_THREADS_1,
.riscTx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
.riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
};
@@ -3975,6 +3975,8 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
ug_info->uf_info.utfs = UCC_GETH_UTFS_GIGA_INIT;
ug_info->uf_info.utfet = UCC_GETH_UTFET_GIGA_INIT;
ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT;
+ ug_info->numThreadsTx = UCC_GETH_NUM_OF_THREADS_4;
+ ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4;
}
/* Set the bus id */
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index a61324757b17..727547a28992 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -16,10 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
-// #define DEBUG // error path messages, extra info
-// #define VERBOSE // more; success messages
-
#include <linux/module.h>
#include <linux/init.h>
#include <linux/netdevice.h>
@@ -318,6 +314,14 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
net->hard_header_len += sizeof (struct rndis_data_hdr);
dev->hard_mtu = net->mtu + net->hard_header_len;
+ dev->maxpacket = usb_maxpacket(dev->udev, dev->out, 1);
+ if (dev->maxpacket == 0) {
+ if (netif_msg_probe(dev))
+ dev_dbg(&intf->dev, "dev->maxpacket can't be 0\n");
+ retval = -EINVAL;
+ goto fail_and_release;
+ }
+
dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1);
dev->rx_urb_size &= ~(dev->maxpacket - 1);
u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 19fd4cb0ddf8..b58472cf76f8 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/farsync.c b/drivers/net/wan/farsync.c
index cf27bf40d36e..547368e9633d 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -2024,6 +2024,7 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
struct fstioc_write wrthdr;
struct fstioc_info info;
unsigned long flags;
+ void *buf;
dbg(DBG_IOCTL, "ioctl: %x, %p\n", cmd, ifr->ifr_data);
@@ -2065,16 +2066,22 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -ENXIO;
}
- /* Now copy the data to the card.
- * This will probably break on some architectures.
- * I'll fix it when I have something to test on.
- */
- if (copy_from_user(card->mem + wrthdr.offset,
+ /* Now copy the data to the card. */
+
+ buf = kmalloc(wrthdr.size, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ if (copy_from_user(buf,
ifr->ifr_data + sizeof (struct fstioc_write),
wrthdr.size)) {
+ kfree(buf);
return -EFAULT;
}
+ memcpy_toio(card->mem + wrthdr.offset, buf, wrthdr.size);
+ kfree(buf);
+
/* Writes to the memory of a card in the reset state constitute
* a download
*/
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index c2de2d958e8e..01757436353d 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -427,6 +427,8 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
{
ATH5K_TRACE(ah->ah_sc);
+ __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
+
if (ah->ah_rf_banks != NULL)
kfree(ah->ah_rf_banks);
diff --git a/drivers/net/wireless/b43/phy.c b/drivers/net/wireless/b43/phy.c
index 71507b260b6d..575c5436ebdf 100644
--- a/drivers/net/wireless/b43/phy.c
+++ b/drivers/net/wireless/b43/phy.c
@@ -860,7 +860,7 @@ static void b43_phy_ww(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_OFDM(0xBB),
(b43_phy_read(dev, B43_PHY_OFDM(0xBB)) & 0xF000) | 0x0053);
b43_phy_write(dev, B43_PHY_OFDM61,
- (b43_phy_read(dev, B43_PHY_OFDM61 & 0xFE1F)) | 0x0120);
+ (b43_phy_read(dev, B43_PHY_OFDM61) & 0xFE1F) | 0x0120);
b43_phy_write(dev, B43_PHY_OFDM(0x13),
(b43_phy_read(dev, B43_PHY_OFDM(0x13)) & 0x0FFF) | 0x3000);
b43_phy_write(dev, B43_PHY_OFDM(0x14),
diff --git a/drivers/net/wireless/p54usb.c b/drivers/net/wireless/p54usb.c
index e7d4aee8799e..98ddbb3b3273 100644
--- a/drivers/net/wireless/p54usb.c
+++ b/drivers/net/wireless/p54usb.c
@@ -63,6 +63,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
{USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
{USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
{USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
+ {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */
{USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */
{USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
{USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 05927b908f80..6c725422af5a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -620,6 +620,9 @@ struct rt2x00_dev {
* This will only be compiled in when required.
*/
#ifdef CONFIG_RT2X00_LIB_RFKILL
+unsigned long rfkill_state;
+#define RFKILL_STATE_ALLOCATED 1
+#define RFKILL_STATE_REGISTERED 2
struct rfkill *rfkill;
struct input_polled_dev *poll_dev;
#endif /* CONFIG_RT2X00_LIB_RFKILL */
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 0d51f478bcdf..bd305f7f3efd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1098,7 +1098,7 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
return;
/*
- * Unregister rfkill.
+ * Unregister extra components.
*/
rt2x00rfkill_unregister(rt2x00dev);
@@ -1139,17 +1139,12 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
__set_bit(DEVICE_INITIALIZED, &rt2x00dev->flags);
/*
- * Register the rfkill handler.
+ * Register the extra components.
*/
- status = rt2x00rfkill_register(rt2x00dev);
- if (status)
- goto exit_unitialize;
+ rt2x00rfkill_register(rt2x00dev);
return 0;
-exit_unitialize:
- rt2x00lib_uninitialize(rt2x00dev);
-
exit:
rt2x00lib_free_ring_entries(rt2x00dev);
@@ -1313,15 +1308,9 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
}
/*
- * Allocatie rfkill.
- */
- retval = rt2x00rfkill_allocate(rt2x00dev);
- if (retval)
- goto exit;
-
- /*
- * Open the debugfs entry.
+ * Register extra components.
*/
+ rt2x00rfkill_allocate(rt2x00dev);
rt2x00debug_register(rt2x00dev);
__set_bit(DEVICE_PRESENT, &rt2x00dev->flags);
@@ -1350,13 +1339,9 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
rt2x00lib_uninitialize(rt2x00dev);
/*
- * Close debugfs entry.
+ * Free extra components
*/
rt2x00debug_deregister(rt2x00dev);
-
- /*
- * Free rfkill
- */
rt2x00rfkill_free(rt2x00dev);
/*
@@ -1395,11 +1380,15 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
__set_bit(DEVICE_STARTED_SUSPEND, &rt2x00dev->flags);
/*
- * Disable radio and unitialize all items
- * that must be recreated on resume.
+ * Disable radio.
*/
rt2x00lib_stop(rt2x00dev);
rt2x00lib_uninitialize(rt2x00dev);
+
+ /*
+ * Suspend/disable extra components.
+ */
+ rt2x00rfkill_suspend(rt2x00dev);
rt2x00debug_deregister(rt2x00dev);
exit:
@@ -1422,9 +1411,10 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
NOTICE(rt2x00dev, "Waking up.\n");
/*
- * Open the debugfs entry.
+ * Restore/enable extra components.
*/
rt2x00debug_register(rt2x00dev);
+ rt2x00rfkill_resume(rt2x00dev);
/*
* Only continue if mac80211 had open interfaces.
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 1adbd28e0973..ce58c654ade1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -100,28 +100,36 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
* RFkill handlers.
*/
#ifdef CONFIG_RT2X00_LIB_RFKILL
-int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev);
+void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev);
void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev);
-int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev);
+void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev);
void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev);
+void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev);
+void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev);
#else
-static inline int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
+static inline void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
{
- return 0;
}
static inline void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
{
}
-static inline int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
+static inline void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
{
- return 0;
}
static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
{
}
+
+static inline void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev)
+{
+}
+
+static inline void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev)
+{
+}
#endif /* CONFIG_RT2X00_LIB_RFKILL */
#endif /* RT2X00LIB_H */
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index 34a96d44e306..f95577596206 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -69,56 +69,81 @@ static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev)
}
}
-int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
+void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
{
- int retval;
-
- if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
- return 0;
+ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
+ !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
+ return;
- retval = rfkill_register(rt2x00dev->rfkill);
- if (retval) {
+ if (rfkill_register(rt2x00dev->rfkill)) {
ERROR(rt2x00dev, "Failed to register rfkill handler.\n");
- return retval;
+ return;
}
- retval = input_register_polled_device(rt2x00dev->poll_dev);
- if (retval) {
+ if (input_register_polled_device(rt2x00dev->poll_dev)) {
ERROR(rt2x00dev, "Failed to register polled device.\n");
rfkill_unregister(rt2x00dev->rfkill);
- return retval;
+ return;
}
+ __set_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
+
/*
* Force initial poll which will detect the initial device state,
* and correctly sends the signal to the rfkill layer about this
* state.
*/
rt2x00rfkill_poll(rt2x00dev->poll_dev);
-
- return 0;
}
void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
{
- if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
+ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
+ !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
return;
input_unregister_polled_device(rt2x00dev->poll_dev);
rfkill_unregister(rt2x00dev->rfkill);
+
+ __clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
}
-int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
+static struct input_polled_dev *
+rt2x00rfkill_allocate_polldev(struct rt2x00_dev *rt2x00dev)
{
- struct device *device = wiphy_dev(rt2x00dev->hw->wiphy);
+ struct input_polled_dev *poll_dev;
+
+ poll_dev = input_allocate_polled_device();
+ if (!poll_dev)
+ return NULL;
+
+ poll_dev->private = rt2x00dev;
+ poll_dev->poll = rt2x00rfkill_poll;
+ poll_dev->poll_interval = RFKILL_POLL_INTERVAL;
+
+ poll_dev->input->name = rt2x00dev->ops->name;
+ poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy);
+ poll_dev->input->id.bustype = BUS_HOST;
+ poll_dev->input->id.vendor = 0x1814;
+ poll_dev->input->id.product = rt2x00dev->chip.rt;
+ poll_dev->input->id.version = rt2x00dev->chip.rev;
+ poll_dev->input->dev.parent = wiphy_dev(rt2x00dev->hw->wiphy);
+ poll_dev->input->evbit[0] = BIT(EV_KEY);
+ set_bit(KEY_WLAN, poll_dev->input->keybit);
+
+ return poll_dev;
+}
+void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
+{
if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
- return 0;
+ return;
- rt2x00dev->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
+ rt2x00dev->rfkill =
+ rfkill_allocate(wiphy_dev(rt2x00dev->hw->wiphy), RFKILL_TYPE_WLAN);
if (!rt2x00dev->rfkill) {
ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n");
- goto exit;
+ return;
}
rt2x00dev->rfkill->name = rt2x00dev->ops->name;
@@ -126,40 +151,49 @@ int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
rt2x00dev->rfkill->state = -1;
rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
- rt2x00dev->poll_dev = input_allocate_polled_device();
+ rt2x00dev->poll_dev = rt2x00rfkill_allocate_polldev(rt2x00dev);
if (!rt2x00dev->poll_dev) {
ERROR(rt2x00dev, "Failed to allocate polled device.\n");
- goto exit_free_rfkill;
+ rfkill_free(rt2x00dev->rfkill);
+ rt2x00dev->rfkill = NULL;
+ return;
}
- rt2x00dev->poll_dev->private = rt2x00dev;
- rt2x00dev->poll_dev->poll = rt2x00rfkill_poll;
- rt2x00dev->poll_dev->poll_interval = RFKILL_POLL_INTERVAL;
+ return;
+}
- rt2x00dev->poll_dev->input->name = rt2x00dev->ops->name;
- rt2x00dev->poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy);
- rt2x00dev->poll_dev->input->id.bustype = BUS_HOST;
- rt2x00dev->poll_dev->input->id.vendor = 0x1814;
- rt2x00dev->poll_dev->input->id.product = rt2x00dev->chip.rt;
- rt2x00dev->poll_dev->input->id.version = rt2x00dev->chip.rev;
- rt2x00dev->poll_dev->input->dev.parent = device;
- rt2x00dev->poll_dev->input->evbit[0] = BIT(EV_KEY);
- set_bit(KEY_WLAN, rt2x00dev->poll_dev->input->keybit);
+void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
+{
+ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
+ !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
+ return;
- return 0;
+ input_free_polled_device(rt2x00dev->poll_dev);
+ rt2x00dev->poll_dev = NULL;
-exit_free_rfkill:
rfkill_free(rt2x00dev->rfkill);
-
-exit:
- return -ENOMEM;
+ rt2x00dev->rfkill = NULL;
}
-void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
+void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev)
{
- if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
+ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
+ !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
return;
input_free_polled_device(rt2x00dev->poll_dev);
- rfkill_free(rt2x00dev->rfkill);
+ rt2x00dev->poll_dev = NULL;
+}
+
+void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev)
+{
+ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
+ !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
+ return;
+
+ rt2x00dev->poll_dev = rt2x00rfkill_allocate_polldev(rt2x00dev);
+ if (!rt2x00dev->poll_dev) {
+ ERROR(rt2x00dev, "Failed to allocate polled device.\n");
+ return;
+ }
}
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c
index de34aa9d3136..f9f9a5f1bbd0 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 bdbe780e21c5..8c4d2c13d5f2 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/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 7f4836b8e71e..5fa4ba0d9934 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/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 2c925b7cd93e..257f5d827d83 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -88,6 +88,15 @@ MODULE_LICENSE("GPL");
#define _LTAG_MEM32RANGE 0x85
#define _LTAG_FIXEDMEM32RANGE 0x86
+/*
+ * Sizes of ISAPNP logical device configuration register sets.
+ * See PNP-ISA-v1.0a.pdf, Appendix A.
+ */
+#define ISAPNP_MAX_MEM 4
+#define ISAPNP_MAX_PORT 8
+#define ISAPNP_MAX_IRQ 2
+#define ISAPNP_MAX_DMA 2
+
static unsigned char isapnp_checksum_value;
static DEFINE_MUTEX(isapnp_cfg_mutex);
static int isapnp_csn_count;
@@ -945,14 +954,14 @@ static int isapnp_read_resources(struct pnp_dev *dev,
dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
if (dev->active) {
- for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) {
+ for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
ret = isapnp_read_word(ISAPNP_CFG_PORT + (tmp << 1));
if (!ret)
continue;
res->port_resource[tmp].start = ret;
res->port_resource[tmp].flags = IORESOURCE_IO;
}
- for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
+ for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
ret =
isapnp_read_word(ISAPNP_CFG_MEM + (tmp << 3)) << 8;
if (!ret)
@@ -960,7 +969,7 @@ static int isapnp_read_resources(struct pnp_dev *dev,
res->mem_resource[tmp].start = ret;
res->mem_resource[tmp].flags = IORESOURCE_MEM;
}
- for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) {
+ for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
ret =
(isapnp_read_word(ISAPNP_CFG_IRQ + (tmp << 1)) >>
8);
@@ -970,7 +979,7 @@ static int isapnp_read_resources(struct pnp_dev *dev,
res->irq_resource[tmp].end = ret;
res->irq_resource[tmp].flags = IORESOURCE_IRQ;
}
- for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
+ for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp);
if (ret == 4)
continue;
@@ -1002,14 +1011,14 @@ static int isapnp_set_resources(struct pnp_dev *dev,
isapnp_cfg_begin(dev->card->number, dev->number);
dev->active = 1;
for (tmp = 0;
- tmp < PNP_MAX_PORT
+ tmp < ISAPNP_MAX_PORT
&& (res->port_resource[tmp].
flags & (IORESOURCE_IO | IORESOURCE_UNSET)) == IORESOURCE_IO;
tmp++)
isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1),
res->port_resource[tmp].start);
for (tmp = 0;
- tmp < PNP_MAX_IRQ
+ tmp < ISAPNP_MAX_IRQ
&& (res->irq_resource[tmp].
flags & (IORESOURCE_IRQ | IORESOURCE_UNSET)) == IORESOURCE_IRQ;
tmp++) {
@@ -1019,14 +1028,14 @@ static int isapnp_set_resources(struct pnp_dev *dev,
isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq);
}
for (tmp = 0;
- tmp < PNP_MAX_DMA
+ tmp < ISAPNP_MAX_DMA
&& (res->dma_resource[tmp].
flags & (IORESOURCE_DMA | IORESOURCE_UNSET)) == IORESOURCE_DMA;
tmp++)
isapnp_write_byte(ISAPNP_CFG_DMA + tmp,
res->dma_resource[tmp].start);
for (tmp = 0;
- tmp < PNP_MAX_MEM
+ tmp < ISAPNP_MAX_MEM
&& (res->mem_resource[tmp].
flags & (IORESOURCE_MEM | IORESOURCE_UNSET)) == IORESOURCE_MEM;
tmp++)
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 82f5ad9c3af4..9e7de63b26ef 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 bbf10ecf416c..56728a2a3385 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 c46666a24809..b9d374082b65 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 f608d4a1d6da..792b2e807bf3 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 3c2d6888bb8c..8591585e5cc5 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 0393707bdfce..3288be2e49f8 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 27ebd336409b..0b2080d33575 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 ba21d97d1855..f40898dc2d14 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 ed83cdb6e67d..b9b09a704584 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 7aee64dbfbeb..5fe7aaed904c 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 208565bdbe8e..7ee86d4a7618 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/serial/sh-sci.c b/drivers/serial/sh-sci.c
index a8c116b80bff..9d244d1644e1 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -414,12 +414,12 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
defined(CONFIG_CPU_SUBTYPE_SH7785)
static inline int scif_txroom(struct uart_port *port)
{
- return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0x7f);
+ return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff);
}
static inline int scif_rxroom(struct uart_port *port)
{
- return sci_in(port, SCRFDR) & 0x7f;
+ return sci_in(port, SCRFDR) & 0xff;
}
#else
static inline int scif_txroom(struct uart_port *port)
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c
index 29fcd6d0301d..a0aa33dde0a4 100644
--- a/drivers/sn/ioc3.c
+++ b/drivers/sn/ioc3.c
@@ -561,7 +561,7 @@ void ioc3_unregister_submodule(struct ioc3_submodule *is)
printk(KERN_WARNING
"%s: IOC3 submodule %s remove failed "
"for pci_dev %s.\n",
- __FUNCTION__, module_name(is->owner),
+ __func__, module_name(is->owner),
pci_name(idd->pdev));
idd->active[is->id] = 0;
if(is->irq_mask)
@@ -611,7 +611,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
if ((ret = pci_enable_device(pdev))) {
printk(KERN_WARNING
"%s: Failed to enable IOC3 device for pci_dev %s.\n",
- __FUNCTION__, pci_name(pdev));
+ __func__, pci_name(pdev));
goto out;
}
pci_set_master(pdev);
@@ -623,7 +623,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
if (ret < 0) {
printk(KERN_WARNING "%s: Unable to obtain 64 bit DMA "
"for consistent allocations\n",
- __FUNCTION__);
+ __func__);
}
}
#endif
@@ -633,7 +633,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
if (!idd) {
printk(KERN_WARNING
"%s: Failed to allocate IOC3 data for pci_dev %s.\n",
- __FUNCTION__, pci_name(pdev));
+ __func__, pci_name(pdev));
ret = -ENODEV;
goto out_idd;
}
@@ -649,7 +649,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
printk(KERN_WARNING
"%s: Unable to find IOC3 resource "
"for pci_dev %s.\n",
- __FUNCTION__, pci_name(pdev));
+ __func__, pci_name(pdev));
ret = -ENODEV;
goto out_pci;
}
@@ -657,7 +657,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
printk(KERN_WARNING
"%s: Unable to request IOC3 region "
"for pci_dev %s.\n",
- __FUNCTION__, pci_name(pdev));
+ __func__, pci_name(pdev));
ret = -ENODEV;
goto out_pci;
}
@@ -666,7 +666,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
printk(KERN_WARNING
"%s: Unable to remap IOC3 region "
"for pci_dev %s.\n",
- __FUNCTION__, pci_name(pdev));
+ __func__, pci_name(pdev));
ret = -ENODEV;
goto out_misc_region;
}
@@ -709,7 +709,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
} else {
printk(KERN_WARNING
"%s : request_irq fails for IRQ 0x%x\n ",
- __FUNCTION__, pdev->irq);
+ __func__, pdev->irq);
}
if (!request_irq(pdev->irq+2, ioc3_intr_io, IRQF_SHARED,
"ioc3-io", (void *)idd)) {
@@ -717,7 +717,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
} else {
printk(KERN_WARNING
"%s : request_irq fails for IRQ 0x%x\n ",
- __FUNCTION__, pdev->irq+2);
+ __func__, pdev->irq+2);
}
} else {
if (!request_irq(pdev->irq, ioc3_intr_io, IRQF_SHARED,
@@ -726,7 +726,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
} else {
printk(KERN_WARNING
"%s : request_irq fails for IRQ 0x%x\n ",
- __FUNCTION__, pdev->irq);
+ __func__, pdev->irq);
}
}
@@ -769,7 +769,7 @@ static void ioc3_remove(struct pci_dev *pdev)
printk(KERN_WARNING
"%s: IOC3 submodule 0x%s remove failed "
"for pci_dev %s.\n",
- __FUNCTION__,
+ __func__,
module_name(ioc3_submodules[id]->owner),
pci_name(pdev));
idd->active[id] = 0;
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 3ab313ed441c..17e71d56f31e 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -4,8 +4,6 @@
menuconfig THERMAL
bool "Generic Thermal sysfs driver"
- select HWMON
- 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/thermal/thermal.c b/drivers/thermal/thermal.c
index 41bd4c805ace..8b86e53ccf7a 100644
--- a/drivers/thermal/thermal.c
+++ b/drivers/thermal/thermal.c
@@ -30,10 +30,8 @@
#include <linux/idr.h>
#include <linux/thermal.h>
#include <linux/spinlock.h>
-#include <linux/hwmon.h>
-#include <linux/hwmon-sysfs.h>
-MODULE_AUTHOR("Zhang Rui");
+MODULE_AUTHOR("Zhang Rui")
MODULE_DESCRIPTION("Generic thermal management sysfs support");
MODULE_LICENSE("GPL");
@@ -58,9 +56,6 @@ static LIST_HEAD(thermal_tz_list);
static LIST_HEAD(thermal_cdev_list);
static DEFINE_MUTEX(thermal_list_lock);
-static struct device *thermal_hwmon;
-#define MAX_THERMAL_ZONES 10
-
static int get_idr(struct idr *idr, struct mutex *lock, int *id)
{
int err;
@@ -92,67 +87,7 @@ static void release_idr(struct idr *idr, struct mutex *lock, int id)
mutex_unlock(lock);
}
-/* hwmon sys I/F*/
-static ssize_t
-name_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "thermal_sys_class\n");
-}
-
-static ssize_t
-temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct thermal_zone_device *tz;
- struct sensor_device_attribute *sensor_attr
- = to_sensor_dev_attr(attr);
-
- list_for_each_entry(tz, &thermal_tz_list, node)
- if (tz->id == sensor_attr->index)
- return tz->ops->get_temp(tz, buf);
-
- return -ENODEV;
-}
-
-static ssize_t
-temp_crit_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct thermal_zone_device *tz;
- struct sensor_device_attribute *sensor_attr
- = to_sensor_dev_attr(attr);
-
- list_for_each_entry(tz, &thermal_tz_list, node)
- if (tz->id == sensor_attr->index)
- return tz->ops->get_trip_temp(tz, 0, buf);
-
- return -ENODEV;
-}
-
-static DEVICE_ATTR(name, 0444, name_show, NULL);
-static struct sensor_device_attribute sensor_attrs[] = {
- SENSOR_ATTR(temp1_input, 0444, temp_input_show, NULL, 0),
- SENSOR_ATTR(temp1_crit, 0444, temp_crit_show, NULL, 0),
- SENSOR_ATTR(temp2_input, 0444, temp_input_show, NULL, 1),
- SENSOR_ATTR(temp2_crit, 0444, temp_crit_show, NULL, 1),
- SENSOR_ATTR(temp3_input, 0444, temp_input_show, NULL, 2),
- SENSOR_ATTR(temp3_crit, 0444, temp_crit_show, NULL, 2),
- SENSOR_ATTR(temp4_input, 0444, temp_input_show, NULL, 3),
- SENSOR_ATTR(temp4_crit, 0444, temp_crit_show, NULL, 3),
- SENSOR_ATTR(temp5_input, 0444, temp_input_show, NULL, 4),
- SENSOR_ATTR(temp5_crit, 0444, temp_crit_show, NULL, 4),
- SENSOR_ATTR(temp6_input, 0444, temp_input_show, NULL, 5),
- SENSOR_ATTR(temp6_crit, 0444, temp_crit_show, NULL, 5),
- SENSOR_ATTR(temp7_input, 0444, temp_input_show, NULL, 6),
- SENSOR_ATTR(temp7_crit, 0444, temp_crit_show, NULL, 6),
- SENSOR_ATTR(temp8_input, 0444, temp_input_show, NULL, 7),
- SENSOR_ATTR(temp8_crit, 0444, temp_crit_show, NULL, 7),
- SENSOR_ATTR(temp9_input, 0444, temp_input_show, NULL, 8),
- SENSOR_ATTR(temp9_crit, 0444, temp_crit_show, NULL, 8),
- SENSOR_ATTR(temp10_input, 0444, temp_input_show, NULL, 9),
- SENSOR_ATTR(temp10_crit, 0444, temp_crit_show, NULL, 9),
-};
-
-/* thermal zone sys I/F */
+/* sys I/F for thermal zone */
#define to_thermal_zone(_dev) \
container_of(_dev, struct thermal_zone_device, device)
@@ -279,7 +214,7 @@ do { \
device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]); \
} while (0)
-/* cooling device sys I/F */
+/* sys I/F for cooling device */
#define to_cooling_device(_dev) \
container_of(_dev, struct thermal_cooling_device, device)
@@ -512,9 +447,6 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type,
struct thermal_zone_device *pos;
int result;
- if (!type)
- return ERR_PTR(-EINVAL);
-
if (strlen(type) >= THERMAL_NAME_LENGTH)
return ERR_PTR(-EINVAL);
@@ -545,9 +477,11 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type,
}
/* sys I/F */
- result = device_create_file(&cdev->device, &dev_attr_cdev_type);
- if (result)
- goto unregister;
+ if (type) {
+ result = device_create_file(&cdev->device, &dev_attr_cdev_type);
+ if (result)
+ goto unregister;
+ }
result = device_create_file(&cdev->device, &dev_attr_max_state);
if (result)
@@ -613,8 +547,8 @@ void thermal_cooling_device_unregister(struct
tz->ops->unbind(tz, cdev);
}
mutex_unlock(&thermal_list_lock);
-
- device_remove_file(&cdev->device, &dev_attr_cdev_type);
+ if (cdev->type[0])
+ device_remove_file(&cdev->device, &dev_attr_cdev_type);
device_remove_file(&cdev->device, &dev_attr_max_state);
device_remove_file(&cdev->device, &dev_attr_cur_state);
@@ -646,9 +580,6 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
int result;
int count;
- if (!type)
- return ERR_PTR(-EINVAL);
-
if (strlen(type) >= THERMAL_NAME_LENGTH)
return ERR_PTR(-EINVAL);
@@ -670,13 +601,6 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
kfree(tz);
return ERR_PTR(result);
}
- if (tz->id >= MAX_THERMAL_ZONES) {
- printk(KERN_ERR PREFIX
- "Too many thermal zones\n");
- release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
- kfree(tz);
- return ERR_PTR(-EINVAL);
- }
strcpy(tz->type, type);
tz->ops = ops;
@@ -691,27 +615,12 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
return ERR_PTR(result);
}
- /* hwmon sys I/F */
- result = device_create_file(thermal_hwmon,
- &sensor_attrs[tz->id * 2].dev_attr);
- if (result)
- goto unregister;
-
- if (trips > 0) {
- char buf[40];
- result = tz->ops->get_trip_type(tz, 0, buf);
- if (result > 0 && !strcmp(buf, "critical\n")) {
- result = device_create_file(thermal_hwmon,
- &sensor_attrs[tz->id * 2 + 1].dev_attr);
- if (result)
- goto unregister;
- }
- }
-
/* sys I/F */
- result = device_create_file(&tz->device, &dev_attr_type);
- if (result)
- goto unregister;
+ if (type) {
+ result = device_create_file(&tz->device, &dev_attr_type);
+ if (result)
+ goto unregister;
+ }
result = device_create_file(&tz->device, &dev_attr_temp);
if (result)
@@ -778,17 +687,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
tz->ops->unbind(tz, cdev);
mutex_unlock(&thermal_list_lock);
- device_remove_file(thermal_hwmon,
- &sensor_attrs[tz->id * 2].dev_attr);
- if (tz->trips > 0) {
- char buf[40];
- if (tz->ops->get_trip_type(tz, 0, buf) > 0)
- if (!strcmp(buf, "critical\n"))
- device_remove_file(thermal_hwmon,
- &sensor_attrs[tz->id * 2 + 1].dev_attr);
- }
-
- device_remove_file(&tz->device, &dev_attr_type);
+ if (tz->type[0])
+ device_remove_file(&tz->device, &dev_attr_type);
device_remove_file(&tz->device, &dev_attr_temp);
if (tz->ops->get_mode)
device_remove_file(&tz->device, &dev_attr_mode);
@@ -805,19 +705,6 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
EXPORT_SYMBOL(thermal_zone_device_unregister);
-static void thermal_exit(void)
-{
- if (thermal_hwmon) {
- device_remove_file(thermal_hwmon, &dev_attr_name);
- hwmon_device_unregister(thermal_hwmon);
- }
- class_unregister(&thermal_class);
- idr_destroy(&thermal_tz_idr);
- idr_destroy(&thermal_cdev_idr);
- mutex_destroy(&thermal_idr_lock);
- mutex_destroy(&thermal_list_lock);
-}
-
static int __init thermal_init(void)
{
int result = 0;
@@ -829,21 +716,17 @@ static int __init thermal_init(void)
mutex_destroy(&thermal_idr_lock);
mutex_destroy(&thermal_list_lock);
}
-
- thermal_hwmon = hwmon_device_register(NULL);
- if (IS_ERR(thermal_hwmon)) {
- result = PTR_ERR(thermal_hwmon);
- thermal_hwmon = NULL;
- printk(KERN_ERR PREFIX
- "unable to register hwmon device\n");
- thermal_exit();
- return result;
- }
-
- result = device_create_file(thermal_hwmon, &dev_attr_name);
-
return result;
}
+static void __exit thermal_exit(void)
+{
+ class_unregister(&thermal_class);
+ idr_destroy(&thermal_tz_idr);
+ idr_destroy(&thermal_cdev_idr);
+ mutex_destroy(&thermal_idr_lock);
+ mutex_destroy(&thermal_list_lock);
+}
+
subsys_initcall(thermal_init);
module_exit(thermal_exit);
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 2ae1e8673b19..9d3f28b92cbe 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 e0b0580705e4..1bd5fb30237d 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 03371c789039..11c0e5e05f21 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 0f8cfb988c90..24843fdd5395 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 1d13dd099af8..a24e680d2b9c 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 000000000000..e9a89fd82757
--- /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 c8a4332d1132..0b3efc31ee6d 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 26f787ddd5ff..59a8f73dec73 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 3a28c1382131..aa714028641e 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;
}