aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-03-11 19:21:17 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-11 19:21:17 -0500
commitce1e7a2ac721eb9d825b63f74752d0c9e0c635c2 (patch)
treea7c0d18d6486734dffb9498e30db5b226b6e23bf /drivers
parentc2956a3b0d1c17b38da369811a6ce93eb7a01a04 (diff)
parent75deb6fa985bd3162b9472f1fc394e23294da816 (diff)
Merge branch 'upstream'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/atm/fore200e.c36
-rw-r--r--drivers/block/DAC960.c3
-rw-r--r--drivers/char/hw_random.c2
-rw-r--r--drivers/char/mmtimer.c2
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c24
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c23
-rw-r--r--drivers/edac/Kconfig18
-rw-r--r--drivers/edac/edac_mc.c12
-rw-r--r--drivers/firmware/dcdbas.c8
-rw-r--r--drivers/ide/legacy/ide-cs.c1
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c6
-rw-r--r--drivers/input/mouse/psmouse-base.c2
-rw-r--r--drivers/isdn/hisax/config.c2
-rw-r--r--drivers/isdn/hisax/hfc_pci.c2
-rw-r--r--drivers/isdn/hisax/hfc_usb.c32
-rw-r--r--drivers/isdn/i4l/isdn_tty.c1
-rw-r--r--drivers/macintosh/windfarm_core.c7
-rw-r--r--drivers/macintosh/windfarm_cpufreq_clamp.c8
-rw-r--r--drivers/macintosh/windfarm_lm75_sensor.c32
-rw-r--r--drivers/macintosh/windfarm_max6690_sensor.c25
-rw-r--r--drivers/macintosh/windfarm_pid.c4
-rw-r--r--drivers/macintosh/windfarm_pm112.c8
-rw-r--r--drivers/md/raid1.c13
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c2
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c2
-rw-r--r--drivers/media/dvb/bt8xx/dst.c2
-rw-r--r--drivers/media/dvb/dvb-core/demux.h2
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c8
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-init.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h2
-rw-r--r--drivers/media/dvb/frontends/Kconfig2
-rw-r--r--drivers/media/dvb/frontends/mt312.c116
-rw-r--r--drivers/media/dvb/frontends/mt312.h6
-rw-r--r--drivers/media/dvb/frontends/stv0297.c4
-rw-r--r--drivers/media/dvb/ttpci/av7110.c9
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c3
-rw-r--r--drivers/media/dvb/ttpci/av7110_ir.c4
-rw-r--r--drivers/media/video/cpia.c2
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c4
-rw-r--r--drivers/media/video/saa7115.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c21
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c12
-rw-r--r--drivers/media/video/tda8290.c8
-rw-r--r--drivers/media/video/tuner-core.c5
-rw-r--r--drivers/media/video/videocodec.h2
-rw-r--r--drivers/media/video/zr36050.c2
-rw-r--r--drivers/media/video/zr36060.c2
-rw-r--r--drivers/media/video/zr36120_i2c.c2
-rw-r--r--drivers/misc/ibmasm/ibmasm.h9
-rw-r--r--drivers/mmc/au1xmmc.c24
-rw-r--r--drivers/mtd/redboot.c22
-rw-r--r--drivers/net/chelsio/espi.c4
-rw-r--r--drivers/net/e1000/e1000.h3
-rw-r--r--drivers/net/e1000/e1000_main.c119
-rw-r--r--drivers/net/pcmcia/axnet_cs.c1
-rw-r--r--drivers/net/s2io.c1
-rw-r--r--drivers/net/tg3.c87
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c5
-rw-r--r--drivers/parport/parport_serial.c11
-rw-r--r--drivers/pcmcia/ds.c40
-rw-r--r--drivers/s390/block/dasd.c38
-rw-r--r--drivers/s390/block/dasd_genhd.c2
-rw-r--r--drivers/s390/block/dasd_int.h7
-rw-r--r--drivers/s390/block/dasd_proc.c3
-rw-r--r--drivers/s390/cio/chsc.c5
-rw-r--r--drivers/s390/net/smsgiucv.c2
-rw-r--r--drivers/scsi/ahci.c14
-rw-r--r--drivers/scsi/ata_piix.c315
-rw-r--r--drivers/scsi/libata-core.c1003
-rw-r--r--drivers/scsi/libata-scsi.c2
-rw-r--r--drivers/scsi/libata.h1
-rw-r--r--drivers/scsi/sata_promise.c2
-rw-r--r--drivers/scsi/sata_sil.c99
-rw-r--r--drivers/scsi/sata_sil24.c1
-rw-r--r--drivers/scsi/sr_ioctl.c2
-rw-r--r--drivers/serial/ioc4_serial.c6
-rw-r--r--drivers/serial/ip22zilog.c4
-rw-r--r--drivers/serial/serial_core.c32
-rw-r--r--drivers/serial/sn_console.c2
-rw-r--r--drivers/usb/serial/usb-serial.c10
-rw-r--r--drivers/video/arcfb.c5
-rw-r--r--drivers/video/aty/aty128fb.c7
-rw-r--r--drivers/video/aty/radeon_monitor.c4
-rw-r--r--drivers/video/backlight/backlight.c2
-rw-r--r--drivers/video/backlight/lcd.c2
-rw-r--r--drivers/video/imsttfb.c2
-rw-r--r--drivers/video/intelfb/intelfbdrv.c50
-rw-r--r--drivers/video/kyro/STG4000VTG.c2
-rw-r--r--drivers/video/neofb.c4
-rw-r--r--drivers/video/s1d13xxxfb.c3
-rw-r--r--drivers/video/savage/savagefb_driver.c2
-rw-r--r--drivers/video/tdfxfb.c42
93 files changed, 1496 insertions, 1008 deletions
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 14f6a6201da..05983a312d5 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -555,7 +555,7 @@ fore200e_pca_reset(struct fore200e* fore200e)
}
-static int __init
+static int __devinit
fore200e_pca_map(struct fore200e* fore200e)
{
DPRINTK(2, "device %s being mapped in memory\n", fore200e->name);
@@ -589,7 +589,7 @@ fore200e_pca_unmap(struct fore200e* fore200e)
}
-static int __init
+static int __devinit
fore200e_pca_configure(struct fore200e* fore200e)
{
struct pci_dev* pci_dev = (struct pci_dev*)fore200e->bus_dev;
@@ -2125,7 +2125,7 @@ fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags)
}
-static int __init
+static int __devinit
fore200e_irq_request(struct fore200e* fore200e)
{
if (request_irq(fore200e->irq, fore200e_interrupt, SA_SHIRQ, fore200e->name, fore200e->atm_dev) < 0) {
@@ -2148,7 +2148,7 @@ fore200e_irq_request(struct fore200e* fore200e)
}
-static int __init
+static int __devinit
fore200e_get_esi(struct fore200e* fore200e)
{
struct prom_data* prom = fore200e_kmalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA);
@@ -2180,7 +2180,7 @@ fore200e_get_esi(struct fore200e* fore200e)
}
-static int __init
+static int __devinit
fore200e_alloc_rx_buf(struct fore200e* fore200e)
{
int scheme, magn, nbr, size, i;
@@ -2245,7 +2245,7 @@ fore200e_alloc_rx_buf(struct fore200e* fore200e)
}
-static int __init
+static int __devinit
fore200e_init_bs_queue(struct fore200e* fore200e)
{
int scheme, magn, i;
@@ -2308,7 +2308,7 @@ fore200e_init_bs_queue(struct fore200e* fore200e)
}
-static int __init
+static int __devinit
fore200e_init_rx_queue(struct fore200e* fore200e)
{
struct host_rxq* rxq = &fore200e->host_rxq;
@@ -2368,7 +2368,7 @@ fore200e_init_rx_queue(struct fore200e* fore200e)
}
-static int __init
+static int __devinit
fore200e_init_tx_queue(struct fore200e* fore200e)
{
struct host_txq* txq = &fore200e->host_txq;
@@ -2431,7 +2431,7 @@ fore200e_init_tx_queue(struct fore200e* fore200e)
}
-static int __init
+static int __devinit
fore200e_init_cmd_queue(struct fore200e* fore200e)
{
struct host_cmdq* cmdq = &fore200e->host_cmdq;
@@ -2487,7 +2487,7 @@ fore200e_param_bs_queue(struct fore200e* fore200e,
}
-static int __init
+static int __devinit
fore200e_initialize(struct fore200e* fore200e)
{
struct cp_queues __iomem * cpq;
@@ -2539,7 +2539,7 @@ fore200e_initialize(struct fore200e* fore200e)
}
-static void __init
+static void __devinit
fore200e_monitor_putc(struct fore200e* fore200e, char c)
{
struct cp_monitor __iomem * monitor = fore200e->cp_monitor;
@@ -2551,7 +2551,7 @@ fore200e_monitor_putc(struct fore200e* fore200e, char c)
}
-static int __init
+static int __devinit
fore200e_monitor_getc(struct fore200e* fore200e)
{
struct cp_monitor __iomem * monitor = fore200e->cp_monitor;
@@ -2576,7 +2576,7 @@ fore200e_monitor_getc(struct fore200e* fore200e)
}
-static void __init
+static void __devinit
fore200e_monitor_puts(struct fore200e* fore200e, char* str)
{
while (*str) {
@@ -2591,7 +2591,7 @@ fore200e_monitor_puts(struct fore200e* fore200e, char* str)
}
-static int __init
+static int __devinit
fore200e_start_fw(struct fore200e* fore200e)
{
int ok;
@@ -2622,7 +2622,7 @@ fore200e_start_fw(struct fore200e* fore200e)
}
-static int __init
+static int __devinit
fore200e_load_fw(struct fore200e* fore200e)
{
u32* fw_data = (u32*) fore200e->bus->fw_data;
@@ -2648,7 +2648,7 @@ fore200e_load_fw(struct fore200e* fore200e)
}
-static int __init
+static int __devinit
fore200e_register(struct fore200e* fore200e)
{
struct atm_dev* atm_dev;
@@ -2675,7 +2675,7 @@ fore200e_register(struct fore200e* fore200e)
}
-static int __init
+static int __devinit
fore200e_init(struct fore200e* fore200e)
{
if (fore200e_register(fore200e) < 0)
@@ -2721,7 +2721,7 @@ fore200e_init(struct fore200e* fore200e)
return -EBUSY;
fore200e_supply(fore200e);
-
+
/* all done, board initialization is now complete */
fore200e->state = FORE200E_STATE_COMPLETE;
return 0;
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 6ede1f352c2..37b8cda3e8b 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -41,6 +41,7 @@
#include <linux/timer.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/random.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include "DAC960.h"
@@ -3463,7 +3464,7 @@ static inline boolean DAC960_ProcessCompletedRequest(DAC960_Command_T *Command,
Command->SegmentCount, Command->DmaDirection);
if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) {
-
+ add_disk_randomness(Request->rq_disk);
end_that_request_last(Request, UpToDate);
if (Command->Completion) {
diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c
index b3bc2e37e61..29dc87e5902 100644
--- a/drivers/char/hw_random.c
+++ b/drivers/char/hw_random.c
@@ -131,7 +131,9 @@ enum {
rng_hw_none,
rng_hw_intel,
rng_hw_amd,
+#ifdef __i386__
rng_hw_via,
+#endif
rng_hw_geode,
};
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c
index c92378121b4..1b05fa68899 100644
--- a/drivers/char/mmtimer.c
+++ b/drivers/char/mmtimer.c
@@ -675,7 +675,7 @@ static int __init mmtimer_init(void)
cnodeid_t node, maxn = -1;
if (!ia64_platform_is("sn2"))
- return -1;
+ return 0;
/*
* Sanity check the cycles/sec variable
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 649677b5dc3..5fdf1851543 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -13,11 +13,12 @@
*
* (C) 2000,2001,2002,2003,2004 Omnikey AG
*
- * (C) 2005 Harald Welte <laforge@gnumonks.org>
+ * (C) 2005-2006 Harald Welte <laforge@gnumonks.org>
* - Adhere to Kernel CodingStyle
* - Port to 2.6.13 "new" style PCMCIA
* - Check for copy_{from,to}_user return values
* - Use nonseekable_open()
+ * - add class interface for udev device creation
*
* All rights reserved. Licensed under dual BSD/GPL license.
*/
@@ -56,7 +57,7 @@ module_param(pc_debug, int, 0600);
#else
#define DEBUGP(n, rdr, x, args...)
#endif
-static char *version = "cm4000_cs.c v2.4.0gm5 - All bugs added by Harald Welte";
+static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte";
#define T_1SEC (HZ)
#define T_10MSEC msecs_to_jiffies(10)
@@ -156,6 +157,7 @@ struct cm4000_dev {
/*queue*/ 4*sizeof(wait_queue_head_t))
static dev_link_t *dev_table[CM4000_MAX_DEV];
+static struct class *cmm_class;
/* This table doesn't use spaces after the comma between fields and thus
* violates CodingStyle. However, I don't really think wrapping it around will
@@ -1937,6 +1939,9 @@ static int cm4000_attach(struct pcmcia_device *p_dev)
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
cm4000_config(link, i);
+ class_device_create(cmm_class, NULL, MKDEV(major, i), NULL,
+ "cmm%d", i);
+
return 0;
}
@@ -1962,6 +1967,8 @@ static void cm4000_detach(struct pcmcia_device *p_dev)
dev_table[devno] = NULL;
kfree(dev);
+ class_device_destroy(cmm_class, MKDEV(major, devno));
+
return;
}
@@ -1995,8 +2002,18 @@ static struct pcmcia_driver cm4000_driver = {
static int __init cmm_init(void)
{
+ int rc;
+
printk(KERN_INFO "%s\n", version);
- pcmcia_register_driver(&cm4000_driver);
+
+ cmm_class = class_create(THIS_MODULE, "cardman_4000");
+ if (!cmm_class)
+ return -1;
+
+ rc = pcmcia_register_driver(&cm4000_driver);
+ if (rc < 0)
+ return rc;
+
major = register_chrdev(0, DEVICE_NAME, &cm4000_fops);
if (major < 0) {
printk(KERN_WARNING MODULE_NAME
@@ -2012,6 +2029,7 @@ static void __exit cmm_exit(void)
printk(KERN_INFO MODULE_NAME ": unloading\n");
pcmcia_unregister_driver(&cm4000_driver);
unregister_chrdev(major, DEVICE_NAME);
+ class_destroy(cmm_class);
};
module_init(cmm_init);
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 46eb371bf17..466e33bab02 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -3,12 +3,13 @@
*
* (c) 2000-2004 Omnikey AG (http://www.omnikey.com/)
*
- * (C) 2005 Harald Welte <laforge@gnumonks.org>
+ * (C) 2005-2006 Harald Welte <laforge@gnumonks.org>
* - add support for poll()
* - driver cleanup
* - add waitqueues
* - adhere to linux kernel coding style and policies
* - support 2.6.13 "new style" pcmcia interface
+ * - add class interface for udev device creation
*
* The device basically is a USB CCID compliant device that has been
* attached to an I/O-Mapped FIFO.
@@ -53,7 +54,7 @@ module_param(pc_debug, int, 0600);
#endif
static char *version =
-"OMNIKEY CardMan 4040 v1.1.0gm4 - All bugs added by Harald Welte";
+"OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte";
#define CCID_DRIVER_BULK_DEFAULT_TIMEOUT (150*HZ)
#define CCID_DRIVER_ASYNC_POWERUP_TIMEOUT (35*HZ)
@@ -67,6 +68,7 @@ static char *version =
static void reader_release(dev_link_t *link);
static int major;
+static struct class *cmx_class;
#define BS_READABLE 0x01
#define BS_WRITABLE 0x02
@@ -696,6 +698,9 @@ static int reader_attach(struct pcmcia_device *p_dev)
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
reader_config(link, i);
+ class_device_create(cmx_class, NULL, MKDEV(major, i), NULL,
+ "cmx%d", i);
+
return 0;
}
@@ -721,6 +726,8 @@ static void reader_detach(struct pcmcia_device *p_dev)
dev_table[devno] = NULL;
kfree(dev);
+ class_device_destroy(cmx_class, MKDEV(major, devno));
+
return;
}
@@ -755,8 +762,17 @@ static struct pcmcia_driver reader_driver = {
static int __init cm4040_init(void)
{
+ int rc;
+
printk(KERN_INFO "%s\n", version);
- pcmcia_register_driver(&reader_driver);
+ cmx_class = class_create(THIS_MODULE, "cardman_4040");
+ if (!cmx_class)
+ return -1;
+
+ rc = pcmcia_register_driver(&reader_driver);
+ if (rc < 0)
+ return rc;
+
major = register_chrdev(0, DEVICE_NAME, &reader_fops);
if (major < 0) {
printk(KERN_WARNING MODULE_NAME
@@ -771,6 +787,7 @@ static void __exit cm4040_exit(void)
printk(KERN_INFO MODULE_NAME ": unloading\n");
pcmcia_unregister_driver(&reader_driver);
unregister_chrdev(major, DEVICE_NAME);
+ class_destroy(cmx_class);
}
module_init(cm4040_init);
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 18a45565112..52f3eb45d2b 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -6,17 +6,29 @@
# $Id: Kconfig,v 1.4.2.7 2005/07/08 22:05:38 dsp_llnl Exp $
#
-menu 'EDAC - error detection and reporting (RAS)'
+menu 'EDAC - error detection and reporting (RAS) (EXPERIMENTAL)'
config EDAC
- tristate "EDAC core system error reporting"
- depends on X86
+ tristate "EDAC core system error reporting (EXPERIMENTAL)"
+ depends on X86 && EXPERIMENTAL
help
EDAC is designed to report errors in the core system.
These are low-level errors that are reported in the CPU or
supporting chipset: memory errors, cache errors, PCI errors,
thermal throttling, etc.. If unsure, select 'Y'.
+ If this code is reporting problems on your system, please
+ see the EDAC project web pages for more information at:
+
+ <http://bluesmoke.sourceforge.net/>
+
+ and:
+
+ <http://buttersideup.com/edacwiki>
+
+ There is also a mailing list for the EDAC project, which can
+ be found via the sourceforge page.
+
comment "Reporting subsystems"
depends on EDAC
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index b10ee4698b1..262e44544dc 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -132,11 +132,13 @@ static struct kobject edac_pci_kobj;
* /sys/devices/system/edac/mc;
* data structures and methods
*/
+#if 0
static ssize_t memctrl_string_show(void *ptr, char *buffer)
{
char *value = (char*) ptr;
return sprintf(buffer, "%s\n", value);
}
+#endif
static ssize_t memctrl_int_show(void *ptr, char *buffer)
{
@@ -207,7 +209,9 @@ struct memctrl_dev_attribute attr_##_name = { \
};
/* cwrow<id> attribute f*/
+#if 0
MEMCTRL_STRING_ATTR(mc_version,EDAC_MC_VERSION,S_IRUGO,memctrl_string_show,NULL);
+#endif
/* csrow<id> control files */
MEMCTRL_ATTR(panic_on_ue,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
@@ -222,7 +226,6 @@ static struct memctrl_dev_attribute *memctrl_attr[] = {
&attr_log_ue,
&attr_log_ce,
&attr_poll_msec,
- &attr_mc_version,
NULL,
};
@@ -309,6 +312,8 @@ struct list_control {
int *count;
};
+
+#if 0
/* Output the list as: vendor_id:device:id<,vendor_id:device_id> */
static ssize_t edac_pci_list_string_show(void *ptr, char *buffer)
{
@@ -430,6 +435,7 @@ static ssize_t edac_pci_list_string_store(void *ptr, const char *buffer,
return count;
}
+#endif
static ssize_t edac_pci_int_show(void *ptr, char *buffer)
{
int *value = ptr;
@@ -498,6 +504,7 @@ struct edac_pci_dev_attribute edac_pci_attr_##_name = { \
.store = _store, \
};
+#if 0
static struct list_control pci_whitelist_control = {
.list = pci_whitelist,
.count = &pci_whitelist_count
@@ -520,6 +527,7 @@ EDAC_PCI_STRING_ATTR(pci_parity_blacklist,
S_IRUGO|S_IWUSR,
edac_pci_list_string_show,
edac_pci_list_string_store);
+#endif
/* PCI Parity control files */
EDAC_PCI_ATTR(check_pci_parity,S_IRUGO|S_IWUSR,edac_pci_int_show,edac_pci_int_store);
@@ -531,8 +539,6 @@ static struct edac_pci_dev_attribute *edac_pci_attr[] = {
&edac_pci_attr_check_pci_parity,
&edac_pci_attr_panic_on_pci_parity,
&edac_pci_attr_pci_parity_count,
- &edac_pci_attr_pci_parity_whitelist,
- &edac_pci_attr_pci_parity_blacklist,
NULL,
};
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 8ed6ddbb9c5..4652512f7d1 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -39,7 +39,7 @@
#include "dcdbas.h"
#define DRIVER_NAME "dcdbas"
-#define DRIVER_VERSION "5.6.0-1"
+#define DRIVER_VERSION "5.6.0-2"
#define DRIVER_DESCRIPTION "Dell Systems Management Base Driver"
static struct platform_device *dcdbas_pdev;
@@ -581,9 +581,13 @@ static int __init dcdbas_init(void)
*/
static void __exit dcdbas_exit(void)
{
- platform_device_unregister(dcdbas_pdev);
+ /*
+ * make sure functions that use dcdbas_pdev are called
+ * before platform_device_unregister
+ */
unregister_reboot_notifier(&dcdbas_reboot_nb);
smi_data_buf_free();
+ platform_device_unregister(dcdbas_pdev);
}
module_init(dcdbas_init);
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 4c2af902090..6213bd3caee 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -445,6 +445,7 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
+ PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443),
PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 2d2d4ac3525..960dae5c87d 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1155,6 +1155,12 @@ static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func)
spin_lock_irq(target->scsi_host->host_lock);
+ if (target->state == SRP_TARGET_DEAD ||
+ target->state == SRP_TARGET_REMOVED) {
+ scmnd->result = DID_BAD_TARGET << 16;
+ goto out;
+ }
+
if (scmnd->host_scribble == (void *) -1L)
goto out;
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 19b1b012172..ad621746767 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -58,7 +58,7 @@ static unsigned int psmouse_resetafter = 5;
module_param_named(resetafter, psmouse_resetafter, uint, 0644);
MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
-static unsigned int psmouse_resync_time = 5;
+static unsigned int psmouse_resync_time;
module_param_named(resync_time, psmouse_resync_time, uint, 0644);
MODULE_PARM_DESC(resync_time, "How long can mouse stay idle before forcing resync (in seconds, 0 = never).");
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index 8159bcecd0c..df9d6520181 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -1929,6 +1929,8 @@ static struct pci_device_id hisax_pci_tbl[] __initdata = {
{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, PCI_ANY_ID, PCI_ANY_ID},
{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, PCI_ANY_ID, PCI_ANY_ID},
{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, PCI_ANY_ID, PCI_ANY_ID},
+ {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B700, PCI_ANY_ID, PCI_ANY_ID},
+ {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B701, PCI_ANY_ID, PCI_ANY_ID},
{PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, PCI_ANY_ID, PCI_ANY_ID},
{PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, PCI_ANY_ID, PCI_ANY_ID},
{PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, PCI_ANY_ID, PCI_ANY_ID},
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 4866fc32d8d..91d25acb5ed 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -51,6 +51,8 @@ static const PCI_ENTRY id_list[] =
{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, "Billion", "B00B"},
{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, "Billion", "B00C"},
{PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, "Seyeon", "B100"},
+ {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B700, "Primux II S0", "B700"},
+ {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B701, "Primux II S0 NT", "B701"},
{PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, "Abocom/Magitek", "2BD1"},
{PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, "Asuscom/Askey", "675"},
{PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, "German telekom", "T-Concept"},
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index ca5b4a3b683..262c4412741 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -1,7 +1,7 @@
/*
* hfc_usb.c
*
- * $Id: hfc_usb.c,v 4.36 2005/04/08 09:55:13 martinb1 Exp $
+ * $Id: hfc_usb.c,v 2.3.2.13 2006/02/17 17:17:22 mbachem Exp $
*
* modular HiSax ISDN driver for Colognechip HFC-S USB chip
*
@@ -45,7 +45,7 @@
#include "hfc_usb.h"
static const char *hfcusb_revision =
- "$Revision: 4.36 $ $Date: 2005/04/08 09:55:13 $ ";
+ "$Revision: 2.3.2.13 $ $Date: 2006/02/17 17:17:22 $ ";
/* Hisax debug support
* use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG
@@ -219,7 +219,7 @@ symbolic(struct hfcusb_symbolic_list list[], const int num)
for (i = 0; list[i].name != NULL; i++)
if (list[i].num == num)
return (list[i].name);
- return "<unkown ERROR>";
+ return "<unknown ERROR>";
}
@@ -235,9 +235,9 @@ ctrl_start_transfer(hfcusb_data * hfc)
hfc->ctrl_urb->transfer_buffer = NULL;
hfc->ctrl_urb->transfer_buffer_length = 0;
hfc->ctrl_write.wIndex =
- hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg;
+ cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg);
hfc->ctrl_write.wValue =
- hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val;
+ cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val);
usb_submit_urb(hfc->ctrl_urb, GFP_ATOMIC); /* start transfer */
}
@@ -1282,7 +1282,7 @@ usb_init(hfcusb_data * hfc)
/* init the background machinery for control requests */
hfc->ctrl_read.bRequestType = 0xc0;
hfc->ctrl_read.bRequest = 1;
- hfc->ctrl_read.wLength = 1;
+ hfc->ctrl_read.wLength = cpu_to_le16(1);
hfc->ctrl_write.bRequestType = 0x40;
hfc->ctrl_write.bRequest = 0;
hfc->ctrl_write.wLength = 0;
@@ -1373,9 +1373,8 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
vend_idx = 0xffff;
for (i = 0; hfcusb_idtab[i].idVendor; i++) {
- if (dev->descriptor.idVendor == hfcusb_idtab[i].idVendor
- && dev->descriptor.idProduct ==
- hfcusb_idtab[i].idProduct) {
+ if ((le16_to_cpu(dev->descriptor.idVendor) == hfcusb_idtab[i].idVendor)
+ && (le16_to_cpu(dev->descriptor.idProduct) == hfcusb_idtab[i].idProduct)) {
vend_idx = i;
continue;
}
@@ -1516,8 +1515,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
usb_transfer_mode
= USB_INT;
packet_size =
- ep->desc.
- wMaxPacketSize;
+ le16_to_cpu(ep->desc.wMaxPacketSize);
break;
case USB_ENDPOINT_XFER_BULK:
if (ep_addr & 0x80)
@@ -1545,8 +1543,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
usb_transfer_mode
= USB_BULK;
packet_size =
- ep->desc.
- wMaxPacketSize;
+ le16_to_cpu(ep->desc.wMaxPacketSize);
break;
case USB_ENDPOINT_XFER_ISOC:
if (ep_addr & 0x80)
@@ -1574,8 +1571,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
usb_transfer_mode
= USB_ISOC;
iso_packet_size =
- ep->desc.
- wMaxPacketSize;
+ le16_to_cpu(ep->desc.wMaxPacketSize);
break;
default:
context->
@@ -1588,10 +1584,8 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
fifonum = cidx;
context->fifos[cidx].hfc =
context;
- context->fifos[cidx].
- usb_packet_maxlen =
- ep->desc.
- wMaxPacketSize;
+ context->fifos[cidx].usb_packet_maxlen =
+ le16_to_cpu(ep->desc.wMaxPacketSize);
context->fifos[cidx].
intervall =
ep->desc.bInterval;
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 393633681f4..aeaa1db74bd 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1682,6 +1682,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
#ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n");
#endif
+ module_put(info->owner);
return;
}
info->flags |= ISDN_ASYNC_CLOSING;
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index bb8d5efe19b..6c0ba04bc57 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -35,6 +35,8 @@
#include <linux/platform_device.h>
#include <linux/mutex.h>
+#include <asm/prom.h>
+
#include "windfarm.h"
#define VERSION "0.2"
@@ -465,6 +467,11 @@ static int __init windfarm_core_init(void)
{
DBG("wf: core loaded\n");
+ /* Don't register on old machines that use therm_pm72 for now */
+ if (machine_is_compatible("PowerMac7,2") ||
+ machine_is_compatible("PowerMac7,3") ||
+ machine_is_compatible("RackMac3,1"))
+ return -ENODEV;
platform_device_register(&wf_platform_device);
return 0;
}
diff --git a/drivers/macintosh/windfarm_cpufreq_clamp.c b/drivers/macintosh/windfarm_cpufreq_clamp.c
index 607dbaca69c..81337cd16e8 100644
--- a/drivers/macintosh/windfarm_cpufreq_clamp.c
+++ b/drivers/macintosh/windfarm_cpufreq_clamp.c
@@ -8,6 +8,8 @@
#include <linux/wait.h>
#include <linux/cpufreq.h>
+#include <asm/prom.h>
+
#include "windfarm.h"
#define VERSION "0.3"
@@ -74,6 +76,12 @@ static int __init wf_cpufreq_clamp_init(void)
{
struct wf_control *clamp;
+ /* Don't register on old machines that use therm_pm72 for now */
+ if (machine_is_compatible("PowerMac7,2") ||
+ machine_is_compatible("PowerMac7,3") ||
+ machine_is_compatible("RackMac3,1"))
+ return -ENODEV;
+
clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL);
if (clamp == NULL)
return -ENOMEM;
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index 906d3ecae6e..423bfa2432c 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -25,7 +25,7 @@
#include "windfarm.h"
-#define VERSION "0.1"
+#define VERSION "0.2"
#undef DEBUG
@@ -113,6 +113,7 @@ static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter,
const char *loc)
{
struct wf_lm75_sensor *lm;
+ int rc;
DBG("wf_lm75: creating %s device at address 0x%02x\n",
ds1775 ? "ds1775" : "lm75", addr);
@@ -139,9 +140,11 @@ static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter,
lm->i2c.driver = &wf_lm75_driver;
strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1);
- if (i2c_attach_client(&lm->i2c)) {
- printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n",
- ds1775 ? "ds1775" : "lm75", lm->i2c.name);
+ rc = i2c_attach_client(&lm->i2c);
+ if (rc) {
+ printk(KERN_ERR "windfarm: failed to attach %s %s to i2c,"
+ " err %d\n", ds1775 ? "ds1775" : "lm75",
+ lm->i2c.name, rc);
goto fail;
}
@@ -175,16 +178,22 @@ static int wf_lm75_attach(struct i2c_adapter *adapter)
(dev = of_get_next_child(busnode, dev)) != NULL;) {
const char *loc =
get_property(dev, "hwsensor-location", NULL);
- u32 *reg = (u32 *)get_property(dev, "reg", NULL);
- DBG(" dev: %s... (loc: %p, reg: %p)\n", dev->name, loc, reg);
- if (loc == NULL || reg == NULL)
+ u8 addr;
+
+ /* We must re-match the adapter in order to properly check
+ * the channel on multibus setups
+ */
+ if (!pmac_i2c_match_adapter(dev, adapter))
+ continue;
+ addr = pmac_i2c_get_dev_addr(dev);
+ if (loc == NULL || addr == 0)
continue;
/* real lm75 */
if (device_is_compatible(dev, "lm75"))
- wf_lm75_create(adapter, *reg, 0, loc);
+ wf_lm75_create(adapter, addr, 0, loc);
/* ds1775 (compatible, better resolution */
else if (device_is_compatible(dev, "ds1775"))
- wf_lm75_create(adapter, *reg, 1, loc);
+ wf_lm75_create(adapter, addr, 1, loc);
}
return 0;
}
@@ -206,6 +215,11 @@ static int wf_lm75_detach(struct i2c_client *client)
static int __init wf_lm75_sensor_init(void)
{
+ /* Don't register on old machines that use therm_pm72 for now */
+ if (machine_is_compatible("PowerMac7,2") ||
+ machine_is_compatible("PowerMac7,3") ||
+ machine_is_compatible("RackMac3,1"))
+ return -ENODEV;
return i2c_add_driver(&wf_lm75_driver);
}
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
index 5b9ad6ca7cb..8e99d408fdd 100644
--- a/drivers/macintosh/windfarm_max6690_sensor.c
+++ b/drivers/macintosh/windfarm_max6690_sensor.c
@@ -17,7 +17,7 @@
#include "windfarm.h"
-#define VERSION "0.1"
+#define VERSION "0.2"
/* This currently only exports the external temperature sensor,
since that's all the control loops need. */
@@ -81,7 +81,7 @@ static struct wf_sensor_ops wf_max6690_ops = {
static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr)
{
struct wf_6690_sensor *max;
- char *name = "u4-temp";
+ char *name = "backside-temp";
max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
if (max == NULL) {
@@ -118,7 +118,6 @@ static int wf_max6690_attach(struct i2c_adapter *adapter)
struct device_node *busnode, *dev = NULL;
struct pmac_i2c_bus *bus;
const char *loc;
- u32 *reg;
bus = pmac_i2c_adapter_to_bus(adapter);
if (bus == NULL)
@@ -126,16 +125,23 @@ static int wf_max6690_attach(struct i2c_adapter *adapter)
busnode = pmac_i2c_get_bus_node(bus);
while ((dev = of_get_next_child(busnode, dev)) != NULL) {
+ u8 addr;
+
+ /* We must re-match the adapter in order to properly check
+ * the channel on multibus setups
+ */
+ if (!pmac_i2c_match_adapter(dev, adapter))
+ continue;
if (!device_is_compatible(dev, "max6690"))
continue;
+ addr = pmac_i2c_get_dev_addr(dev);
loc = get_property(dev, "hwsensor-location", NULL);
- reg = (u32 *) get_property(dev, "reg", NULL);
- if (!loc || !reg)
+ if (loc == NULL || addr == 0)
continue;
- printk("found max6690, loc=%s reg=%x\n", loc, *reg);
+ printk("found max6690, loc=%s addr=0x%02x\n", loc, addr);
if (strcmp(loc, "BACKSIDE"))
continue;
- wf_max6690_create(adapter, *reg);
+ wf_max6690_create(adapter, addr);
}
return 0;
@@ -153,6 +159,11 @@ static int wf_max6690_detach(struct i2c_client *client)
static int __init wf_max6690_sensor_init(void)
{
+ /* Don't register on old machines that use therm_pm72 for now */
+ if (machine_is_compatible("PowerMac7,2") ||
+ machine_is_compatible("PowerMac7,3") ||
+ machine_is_compatible("RackMac3,1"))
+ return -ENODEV;
return i2c_add_driver(&wf_max6690_driver);
}
diff --git a/drivers/macintosh/windfarm_pid.c b/drivers/macintosh/windfarm_pid.c
index 0842432e27a..f10efb28cae 100644
--- a/drivers/macintosh/windfarm_pid.c
+++ b/drivers/macintosh/windfarm_pid.c
@@ -143,3 +143,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp)
return st->target;
}
EXPORT_SYMBOL_GPL(wf_cpu_pid_run);
+
+MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
+MODULE_DESCRIPTION("PID algorithm for PowerMacs thermal control");
+MODULE_LICENSE("GPL");
diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c
index c2a4e689c78..ef66bf2778e 100644
--- a/drivers/macintosh/windfarm_pm112.c
+++ b/drivers/macintosh/windfarm_pm112.c
@@ -358,6 +358,7 @@ static void backside_fan_tick(void)
return;
if (!backside_tick) {
/* first time; initialize things */
+ printk(KERN_INFO "windfarm: Backside control loop started.\n");
backside_param.min = backside_fan->ops->get_min(backside_fan);
backside_param.max = backside_fan->ops->get_max(backside_fan);
wf_pid_init(&backside_pid, &backside_param);
@@ -407,6 +408,7 @@ static void drive_bay_fan_tick(void)
return;
if (!drive_bay_tick) {
/* first time; initialize things */
+ printk(KERN_INFO "windfarm: Drive bay control loop started.\n");
drive_bay_prm.min = drive_bay_fan->ops->get_min(drive_bay_fan);
drive_bay_prm.max = drive_bay_fan->ops->get_max(drive_bay_fan);
wf_pid_init(&drive_bay_pid, &drive_bay_prm);
@@ -458,6 +460,7 @@ static void slots_fan_tick(void)
return;
if (!slots_started) {
/* first time; initialize things */
+ printk(KERN_INFO "windfarm: Slots control loop started.\n");
wf_pid_init(&slots_pid, &slots_param);
slots_started = 1;
}
@@ -504,6 +507,7 @@ static void pm112_tick(void)
if (!started) {
started = 1;
+ printk(KERN_INFO "windfarm: CPUs control loops started.\n");
for (i = 0; i < nr_cores; ++i) {
if (create_cpu_loop(i) < 0) {
failure_state = FAILURE_PERM;
@@ -594,8 +598,6 @@ static void pm112_new_sensor(struct wf_sensor *sr)
{
unsigned int i;
- if (have_all_sensors)
- return;
if (!strncmp(sr->name, "cpu-temp-", 9)) {
i = sr->name[9] - '0';
if (sr->name[10] == 0 && i < NR_CORES &&
@@ -613,7 +615,7 @@ static void pm112_new_sensor(struct wf_sensor *sr)
} else if (!strcmp(sr->name, "slots-power")) {
if (slots_power == NULL && wf_get_sensor(sr) == 0)
slots_power = sr;
- } else if (!strcmp(sr->name, "u4-temp")) {
+ } else if (!strcmp(sr->name, "backside-temp")) {
if (u4_temp == NULL && wf_get_sensor(sr) == 0)
u4_temp = sr;
} else
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index d39f584cd8b..5d88329e3c7 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -306,6 +306,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private);
int mirror, behind = test_bit(R1BIO_BehindIO, &r1_bio->state);
conf_t *conf = mddev_to_conf(r1_bio->mddev);
+ struct bio *to_put = NULL;
if (bio->bi_size)
return 1;
@@ -323,6 +324,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
* this branch is our 'one mirror IO has finished' event handler:
*/
r1_bio->bios[mirror] = NULL;
+ to_put = bio;
if (!uptodate) {
md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
/* an I/O failed, we can't clear the bitmap */
@@ -375,7 +377,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
/* Don't dec_pending yet, we want to hold
* the reference over the retry
*/
- return 0;
+ goto out;
}
if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
/* free extra copy of the data pages */
@@ -392,10 +394,11 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
raid_end_bio_io(r1_bio);
}
- if (r1_bio->bios[mirror]==NULL)
- bio_put(bio);
-
rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
+ out:
+ if (to_put)
+ bio_put(to_put);
+
return 0;
}
@@ -857,7 +860,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
atomic_set(&r1_bio->remaining, 0);
atomic_set(&r1_bio->behind_remaining, 0);
- do_barriers = bio->bi_rw & BIO_RW_BARRIER;
+ do_barriers = bio_barrier(bio);
if (do_barriers)
set_bit(R1BIO_Barrier, &r1_bio->state);
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 390cc3a99ce..9c7f122826e 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -526,7 +526,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
} else
/* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
- if ((fc->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
+ if ((fc->fe = vp310_mt312_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
ops = fc->fe->ops;
ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index 34c3189a1a3..356f447ee2a 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -382,7 +382,7 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *
EXPORT_SYMBOL(bt878_device_control);
-struct cards card_list[] __devinitdata = {
+static struct cards card_list[] __devinitdata = {
{ 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
{ 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 3a2ff1cc24b..0310e3dd07e 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -602,7 +602,7 @@ static int dst_type_print(u8 type)
*/
-struct dst_types dst_tlist[] = {
+static struct dst_types dst_tlist[] = {
{
.device_id = "200103A",
.offset = 0,
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index 9f025825b2d..0c1d87c5227 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -216,7 +216,7 @@ struct dmx_frontend {
/*--------------------------------------------------------------------------*/
/*
- * Flags OR'ed in the capabilites field of struct dmx_demux.
+ * Flags OR'ed in the capabilities field of struct dmx_demux.
*/
#define DMX_TS_FILTERING 1
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index f327fac1688..162f9795cd8 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -282,7 +282,7 @@ static struct cx22702_config cxusb_cx22702_config = {
.pll_set = dvb_usb_pll_set_i2c,
};
-static struct lgdt330x_config cxusb_lgdt330x_config = {
+static struct lgdt330x_config cxusb_lgdt3303_config = {
.demod_address = 0x0e,
.demod_chip = LGDT3303,
.pll_set = dvb_usb_pll_set_i2c,
@@ -357,14 +357,14 @@ static int cxusb_cx22702_frontend_attach(struct dvb_usb_device *d)
return -EIO;
}
-static int cxusb_lgdt330x_frontend_attach(struct dvb_usb_device *d)
+static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_device *d)
{
if (usb_set_interface(d->udev,0,7) < 0)
err("set interface failed");
cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
- if ((d->fe = lgdt330x_attach(&cxusb_lgdt330x_config, &d->i2c_adap)) != NULL)
+ if ((d->fe = lgdt330x_attach(&cxusb_lgdt3303_config, &d->i2c_adap)) != NULL)
return 0;
return -EIO;
@@ -506,7 +506,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = {
.streaming_ctrl = cxusb_streaming_ctrl,
.power_ctrl = cxusb_power_ctrl,
- .frontend_attach = cxusb_lgdt330x_frontend_attach,
+ .frontend_attach = cxusb_lgdt3303_frontend_attach,
.tuner_attach = cxusb_lgh064f_tuner_attach,
.i2c_algo = &cxusb_i2c_algo,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
index 716f8bf528c..ce34a55e5c2 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -47,7 +47,7 @@ static int dvb_usb_init(struct dvb_usb_device *d)
d->state = DVB_USB_STATE_INIT;
-/* check the capabilites and set appropriate variables */
+/* check the capabilities and set appropriate variables */
/* speed - when running at FULL speed we need a HW PID filter */
if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) {
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index 5e5d21ad93c..d4909e5c67e 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -87,7 +87,7 @@ struct dvb_usb_device;
/**
* struct dvb_usb_properties - properties of a dvb-usb-device
- * @caps: capabilites of the DVB USB device.
+ * @caps: capabilities of the DVB USB device.
* @pid_filter_count: number of PID filter position in the optional hardware
* PID-filter.
*
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 76b6a2aef32..c676b1e23ab 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -29,7 +29,7 @@ config DVB_TDA8083
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_MT312
- tristate "Zarlink MT312 based"
+ tristate "Zarlink VP310/MT312 based"
depends on DVB_CORE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index ec4e641acc6..d3aea83cf21 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -612,76 +612,6 @@ static void mt312_release(struct dvb_frontend* fe)
kfree(state);
}
-static struct dvb_frontend_ops vp310_mt312_ops;
-
-struct dvb_frontend* vp310_attach(const struct mt312_config* config,
- struct i2c_adapter* i2c)
-{
- struct mt312_state* state = NULL;
-
- /* allocate memory for the internal state */
- state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
- if (state == NULL)
- goto error;
-
- /* setup the state */
- state->config = config;
- state->i2c = i2c;
- memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops));
- strcpy(state->ops.info.name, "Zarlink VP310 DVB-S");
-
- /* check if the demod is there */
- if (mt312_readreg(state, ID, &state->id) < 0)
- goto error;
- if (state->id != ID_VP310) {
- goto error;
- }
-
- /* create dvb_frontend */
- state->frequency = 90;
- state->frontend.ops = &state->ops;
- state->frontend.demodulator_priv = state;
- return &state->frontend;
-
-error:
- kfree(state);
- return NULL;
-}
-
-struct dvb_frontend* mt312_attach(const struct mt312_config* config,
- struct i2c_adapter* i2c)
-{
- struct mt312_state* state = NULL;
-
- /* allocate memory for the internal state */
- state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
- if (state == NULL)
- goto error;
-
- /* setup the state */
- state->config = config;
- state->i2c = i2c;
- memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops));
- strcpy(state->ops.info.name, "Zarlink MT312 DVB-S");
-
- /* check if the demod is there */
- if (mt312_readreg(state, ID, &state->id) < 0)
- goto error;
- if (state->id != ID_MT312) {
- goto error;
- }
-
- /* create dvb_frontend */
- state->frequency = 60;
- state->frontend.ops = &state->ops;
- state->frontend.demodulator_priv = state;
- return &state->frontend;
-
-error:
- kfree(state);
- return NULL;
-}
-
static struct dvb_frontend_ops vp310_mt312_ops = {
.info = {
@@ -720,6 +650,49 @@ static struct dvb_frontend_ops vp310_mt312_ops = {
.set_voltage = mt312_set_voltage,
};
+struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
+ struct i2c_adapter* i2c)
+{
+ struct mt312_state* state = NULL;
+
+ /* allocate memory for the internal state */
+ state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+
+ /* setup the state */
+ state->config = config;
+ state->i2c = i2c;
+ memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops));
+
+ /* check if the demod is there */
+ if (mt312_readreg(state, ID, &state->id) < 0)
+ goto error;
+
+ switch (state->id) {
+ case ID_VP310:
+ strcpy(state->ops.info.name, "Zarlink VP310 DVB-S");
+ state->frequency = 90;
+ break;
+ case ID_MT312:
+ strcpy(state->ops.info.name, "Zarlink MT312 DVB-S");
+ state->frequency = 60;
+ break;
+ default:
+ printk (KERN_WARNING "Only Zarlink VP310/MT312 are supported chips.\n");
+ goto error;
+ }
+
+ /* create dvb_frontend */
+ state->frontend.ops = &state->ops;
+ state->frontend.demodulator_priv = state;
+ return &state->frontend;
+
+error:
+ kfree(state);
+ return NULL;
+}
+
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
@@ -727,5 +700,4 @@ MODULE_DESCRIPTION("Zarlink VP310/MT312 DVB-S Demodulator driver");
MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
MODULE_LICENSE("GPL");
-EXPORT_SYMBOL(mt312_attach);
-EXPORT_SYMBOL(vp310_attach);
+EXPORT_SYMBOL(vp310_mt312_attach);
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h
index b3a53a73a11..074d844f013 100644
--- a/drivers/media/dvb/frontends/mt312.h
+++ b/drivers/media/dvb/frontends/mt312.h
@@ -38,10 +38,8 @@ struct mt312_config
int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
};
-extern struct dvb_frontend* mt312_attach(const struct mt312_config* config,
- struct i2c_adapter* i2c);
+struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
+ struct i2c_adapter* i2c);
-extern struct dvb_frontend* vp310_attach(const struct mt312_config* config,
- struct i2c_adapter* i2c);
#endif // MT312_H
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
index 6122ba754bc..eb15676d374 100644
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -393,10 +393,6 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
break;
case QAM_128:
- delay = 150;
- sweeprate = 1000;
- break;
-
case QAM_256:
delay = 200;
sweeprate = 500;
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index d36369e9e88..7c6ccb96b15 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -1439,7 +1439,7 @@ static int check_firmware(struct av7110* av7110)
len = ntohl(*(u32*) ptr);
ptr += 4;
if (len >= 512) {
- printk("dvb-ttpci: dpram file is way to big.\n");
+ printk("dvb-ttpci: dpram file is way too big.\n");
return -EINVAL;
}
if (crc != crc32_le(0, ptr, len)) {
@@ -2477,7 +2477,8 @@ static int frontend_init(struct av7110 *av7110)
* The same behaviour of missing VSYNC can be duplicated on budget
* cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
*/
-static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext)
+static int __devinit av7110_attach(struct saa7146_dev* dev,
+ struct saa7146_pci_extension_data *pci_ext)
{
const int length = TS_WIDTH * TS_HEIGHT;
struct pci_dev *pdev = dev->pci;
@@ -2827,7 +2828,7 @@ err_kfree_0:
goto out;
}
-static int av7110_detach(struct saa7146_dev* saa)
+static int __devexit av7110_detach(struct saa7146_dev* saa)
{
struct av7110 *av7110 = saa->ext_priv;
dprintk(4, "%p\n", av7110);
@@ -2974,7 +2975,7 @@ static struct saa7146_extension av7110_extension = {
.module = THIS_MODULE,
.pci_tbl = &pci_tbl[0],
.attach = av7110_attach,
- .detach = av7110_detach,
+ .detach = __devexit_p(av7110_detach),
.irq_mask = MASK_19 | MASK_03 | MASK_10,
.irq_func = av7110_irq,
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index b2e63e9fc05..0bb6e74ae7f 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -245,6 +245,9 @@ int av7110_bootarm(struct av7110 *av7110)
/* test DEBI */
iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);
+ /* FIXME: Why does Nexus CA require 2x iwdebi for first init? */
+ iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);
+
if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) {
printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: "
"%08x != %08x (check your BIOS 'Plug&Play OS' settings)\n",
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index 617e4f6c0ed..d54bbcdde2c 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -208,7 +208,7 @@ static void ir_handler(struct av7110 *av7110, u32 ircom)
}
-int __init av7110_ir_init(struct av7110 *av7110)
+int __devinit av7110_ir_init(struct av7110 *av7110)
{
static struct proc_dir_entry *e;
@@ -248,7 +248,7 @@ int __init av7110_ir_init(struct av7110 *av7110)
}
-void __exit av7110_ir_exit(struct av7110 *av7110)
+void __devexit av7110_ir_exit(struct av7110 *av7110)
{
int i;
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 9f59541155d..85d964b5b33 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -3369,7 +3369,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
//DBG("cpia_ioctl: %u\n", ioctlnr);
switch (ioctlnr) {
- /* query capabilites */
+ /* query capabilities */
case VIDIOCGCAP:
{
struct video_capability *b = arg;
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 08ffd1f325f..5588b9a5c43 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -567,7 +567,7 @@ static struct v4l2_queryctrl cx25840_qctrl[] = {
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Contrast",
.minimum = 0,
- .maximum = 255,
+ .maximum = 127,
.step = 1,
.default_value = 64,
.flags = 0,
@@ -576,7 +576,7 @@ static struct v4l2_queryctrl cx25840_qctrl[] = {
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Saturation",
.minimum = 0,
- .maximum = 255,
+ .maximum = 127,
.step = 1,
.default_value = 64,
.flags = 0,
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 048d000941c..ffd87ce5555 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1027,7 +1027,7 @@ static struct v4l2_queryctrl saa7115_qctrl[] = {
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Contrast",
.minimum = 0,
- .maximum = 255,
+ .maximum = 127,
.step = 1,
.default_value = 64,
.flags = 0,
@@ -1036,7 +1036,7 @@ static struct v4l2_queryctrl saa7115_qctrl[] = {
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Saturation",
.minimum = 0,
- .maximum = 255,
+ .maximum = 127,
.step = 1,
.default_value = 64,
.flags = 0,
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index a7a6ab9298a..7df5e0826e1 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -54,10 +54,12 @@ MODULE_PARM_DESC(debug,"enable debug messages [alsa]");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
+static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
module_param_array(index, int, NULL, 0444);
+module_param_array(enable, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
+MODULE_PARM_DESC(enable, "Enable (or not) the SAA7134 capture interface(s).");
#define dprintk(fmt, arg...) if (debug) \
printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ##arg)
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 5a35d3b6550..6bc63a4086c 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -977,7 +977,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_ACTIVE,
+ .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_INACTIVE,
.inputs = {{
.name = name_tv,
.vmux = 3,
@@ -1666,7 +1666,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_ACTIVE,
+ .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_INACTIVE,
.mpeg = SAA7134_MPEG_DVB,
.inputs = {{
.name = name_tv,
@@ -2187,7 +2187,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = 0x61,
.radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
+ .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE,
.mpeg = SAA7134_MPEG_DVB,
.inputs = {{
.name = name_tv,
@@ -2211,7 +2211,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = 0x61,
.radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
+ .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE,
.mpeg = SAA7134_MPEG_DVB,
.inputs = {{
.name = name_tv,
@@ -2392,7 +2392,7 @@ struct saa7134_board saa7134_boards[] = {
}},
},
[SAA7134_BOARD_PINNACLE_PCTV_110i] = {
- .name = "Pinnacle PCTV 110i (saa7133)",
+ .name = "Pinnacle PCTV 40i/50i/110i (saa7133)",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_TDA8290,
.radio_type = UNSET,
@@ -2407,6 +2407,10 @@ struct saa7134_board saa7134_boards[] = {
},{
.name = name_comp1,
.vmux = 1,
+ .amux = LINE2,
+ },{
+ .name = name_comp2,
+ .vmux = 0,
.amux = LINE2,
},{
.name = name_svideo,
@@ -2745,7 +2749,7 @@ struct pci_device_id saa7134_pci_tbl[] = {
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
.subvendor = 0x1048,
- .subdevice = 0x226b,
+ .subdevice = 0x226a,
.driver_data = SAA7134_BOARD_ELSA_500TV,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
@@ -3201,6 +3205,11 @@ int saa7134_board_init1(struct saa7134_dev *dev)
/* power-up tuner chip */
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
+ case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
+ /* this turns the remote control chip off to work around a bug in it */
+ saa_writeb(SAA7134_GPIO_GPMODE1, 0x80);
+ saa_writeb(SAA7134_GPIO_GPSTATUS1, 0x80);
+ break;
case SAA7134_BOARD_MONSTERTV_MOBILE:
/* power-up tuner chip */
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 1a536e86527..9db8e13f21c 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -110,6 +110,7 @@ static int mt352_pinnacle_init(struct dvb_frontend* fe)
mt352_write(fe, fsm_ctl_cfg, sizeof(fsm_ctl_cfg));
mt352_write(fe, scan_ctl_cfg, sizeof(scan_ctl_cfg));
mt352_write(fe, irq_cfg, sizeof(irq_cfg));
+
return 0;
}
@@ -117,8 +118,10 @@ static int mt352_pinnacle_pll_set(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params,
u8* pllbuf)
{
- static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
- static int off = TDA9887_PRESENT | TDA9887_PORT2_ACTIVE;
+ u8 off[] = { 0x00, 0xf1};
+ u8 on[] = { 0x00, 0x71};
+ struct i2c_msg msg = {.addr=0x43, .flags=0, .buf=off, .len = sizeof(off)};
+
struct saa7134_dev *dev = fe->dvb->priv;
struct v4l2_frequency f;
@@ -126,9 +129,10 @@ static int mt352_pinnacle_pll_set(struct dvb_frontend* fe,
f.tuner = 0;
f.type = V4L2_TUNER_DIGITAL_TV;
f.frequency = params->frequency / 1000 * 16 / 1000;
- saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on);
+ i2c_transfer(&dev->i2c_adap, &msg, 1);
saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
- saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&off);
+ msg.buf = on;
+ i2c_transfer(&dev->i2c_adap, &msg, 1);
pinnacle_antenna_pwr(dev, antenna_pwr);
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index 7b4fb282ac8..a796a4e1917 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -580,9 +580,10 @@ int tda8290_init(struct i2c_client *c)
int tda8290_probe(struct i2c_client *c)
{
- unsigned char soft_reset[] = { 0x00, 0x00 };
- unsigned char easy_mode_b[] = { 0x01, 0x02 };
- unsigned char easy_mode_g[] = { 0x01, 0x04 };
+ unsigned char soft_reset[] = { 0x00, 0x00 };
+ unsigned char easy_mode_b[] = { 0x01, 0x02 };
+ unsigned char easy_mode_g[] = { 0x01, 0x04 };
+ unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 };
unsigned char addr_dto_lsb = 0x07;
unsigned char data;
@@ -599,6 +600,7 @@ int tda8290_probe(struct i2c_client *c)
return 0;
}
}
+ i2c_master_send(c, restore_9886, 3);
return -1;
}
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index e7ee619d62c..b6101bf446d 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -713,8 +713,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
struct v4l2_frequency *f = arg;
switch_v4l2();
- if (V4L2_TUNER_RADIO == f->type &&
- V4L2_TUNER_RADIO != t->mode) {
+ if ((V4L2_TUNER_RADIO == f->type && V4L2_TUNER_RADIO != t->mode)
+ || (V4L2_TUNER_DIGITAL_TV == f->type
+ && V4L2_TUNER_DIGITAL_TV != t->mode)) {
if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY")
== EINVAL)
return 0;
diff --git a/drivers/media/video/videocodec.h b/drivers/media/video/videocodec.h
index 156ae57096f..b1239ac7f37 100644
--- a/drivers/media/video/videocodec.h
+++ b/drivers/media/video/videocodec.h
@@ -56,7 +56,7 @@
the slave is bound to it). Otherwise it doesn't need this functions and
therfor they may not be initialized.
- The other fuctions are just for convenience, as they are for shure used by
+ The other fuctions are just for convenience, as they are for sure used by
most/all of the codecs. The last ones may be ommited, too.
See the structure declaration below for more information and which data has
diff --git a/drivers/media/video/zr36050.c b/drivers/media/video/zr36050.c
index bd0cd28543c..6699725be60 100644
--- a/drivers/media/video/zr36050.c
+++ b/drivers/media/video/zr36050.c
@@ -159,7 +159,7 @@ zr36050_wait_end (struct zr36050 *ptr)
while (!(zr36050_read_status1(ptr) & 0x4)) {
udelay(1);
- if (i++ > 200000) { // 200ms, there is for shure something wrong!!!
+ if (i++ > 200000) { // 200ms, there is for sure something wrong!!!
dprintk(1,
"%s: timout at wait_end (last status: 0x%02x)\n",
ptr->name, ptr->status1);
diff --git a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c
index 28fa31a5f15..d8dd003a7aa 100644
--- a/drivers/media/video/zr36060.c
+++ b/drivers/media/video/zr36060.c
@@ -161,7 +161,7 @@ zr36060_wait_end (struct zr36060 *ptr)
while (zr36060_read_status(ptr) & ZR060_CFSR_Busy) {
udelay(1);
- if (i++ > 200000) { // 200ms, there is for shure something wrong!!!
+ if (i++ > 200000) { // 200ms, there is for sure something wrong!!!
dprintk(1,
"%s: timout at wait_end (last status: 0x%02x)\n",
ptr->name, ptr->status);
diff --git a/drivers/media/video/zr36120_i2c.c b/drivers/media/video/zr36120_i2c.c
index 6bfe84d657f..21fde43a6ae 100644
--- a/drivers/media/video/zr36120_i2c.c
+++ b/drivers/media/video/zr36120_i2c.c
@@ -65,7 +65,7 @@ void attach_inform(struct i2c_bus *bus, int id)
case I2C_DRIVERID_VIDEODECODER:
DEBUG(printk(CARD_INFO "decoder attached\n",CARD));
- /* fetch the capabilites of the decoder */
+ /* fetch the capabilities of the decoder */
rv = i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_GET_CAPABILITIES, &dc);
if (rv) {
DEBUG(printk(CARD_DEBUG "decoder is not V4L aware!\n",CARD));
diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h
index 1cef2387fa6..6aba4195444 100644
--- a/drivers/misc/ibmasm/ibmasm.h
+++ b/drivers/misc/ibmasm/ibmasm.h
@@ -101,15 +101,16 @@ struct command {
static inline void command_put(struct command *cmd)
{
unsigned long flags;
+ spinlock_t *lock = cmd->lock;
- spin_lock_irqsave(cmd->lock, flags);
- kobject_put(&cmd->kobj);
- spin_unlock_irqrestore(cmd->lock, flags);
+ spin_lock_irqsave(lock, flags);
+ kobject_put(&cmd->kobj);
+ spin_unlock_irqrestore(lock, flags);
}
static inline void command_get(struct command *cmd)
{
- kobject_get(&cmd->kobj);
+ kobject_get(&cmd->kobj);
}
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c
index 227c39a7c1b..8d84b045bc8 100644
--- a/drivers/mmc/au1xmmc.c
+++ b/drivers/mmc/au1xmmc.c
@@ -37,7 +37,7 @@
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
@@ -194,7 +194,7 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);
- switch (mmc_rsp_type(cmd->flags)) {
+ switch (mmc_resp_type(cmd)) {
case MMC_RSP_R1:
mmccmd |= SD_CMD_RT_1;
break;
@@ -740,7 +740,6 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
static void au1xmmc_dma_callback(int irq, void *dev_id, struct pt_regs *regs)
{
struct au1xmmc_host *host = (struct au1xmmc_host *) dev_id;
- u32 status;
/* Avoid spurious interrupts */
@@ -887,7 +886,7 @@ struct mmc_host_ops au1xmmc_ops = {
.set_ios = au1xmmc_set_ios,
};
-static int au1xmmc_probe(struct device *dev)
+static int __devinit au1xmmc_probe(struct platform_device *pdev)
{
int i, ret = 0;
@@ -904,7 +903,7 @@ static int au1xmmc_probe(struct device *dev)
disable_irq(AU1100_SD_IRQ);
for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) {
- struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), dev);
+ struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev);
struct au1xmmc_host *host = 0;
if (!mmc) {
@@ -967,7 +966,7 @@ static int au1xmmc_probe(struct device *dev)
return 0;
}
-static int au1xmmc_remove(struct device *dev)
+static int __devexit au1xmmc_remove(struct platform_device *pdev)
{
int i;
@@ -997,23 +996,24 @@ static int au1xmmc_remove(struct device *dev)
return 0;
}
-static struct device_driver au1xmmc_driver = {
- .name = DRIVER_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver au1xmmc_driver = {
.probe = au1xmmc_probe,
.remove = au1xmmc_remove,
.suspend = NULL,
- .resume = NULL
+ .resume = NULL,
+ .driver = {
+ .name = DRIVER_NAME,
+ },
};
static int __init au1xmmc_init(void)
{
- return driver_register(&au1xmmc_driver);
+ return platform_driver_register(&au1xmmc_driver);
}
static void __exit au1xmmc_exit(void)
{
- driver_unregister(&au1xmmc_driver);
+ platform_driver_unregister(&au1xmmc_driver);
}
module_init(au1xmmc_init);
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c
index d01b6a9198e..8815c8dbef2 100644
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -1,5 +1,5 @@
/*
- * $Id: redboot.c,v 1.18 2005/11/07 11:14:21 gleixner Exp $
+ * $Id: redboot.c,v 1.19 2005/12/01 10:03:51 dwmw2 Exp $
*
* Parse RedBoot-style Flash Image System (FIS) tables and
* produce a Linux partition array to match.
@@ -92,10 +92,10 @@ static int parse_redboot_partitions(struct mtd_info *master,
if (!memcmp(buf[i].name, "FIS directory", 14)) {
/* This is apparently the FIS directory entry for the
* FIS directory itself. The FIS directory size is
- * one erase block, if the buf[i].size field is
+ * one erase block; if the buf[i].size field is
* swab32(erasesize) then we know we are looking at
* a byte swapped FIS directory - swap all the entries!
- * (NOTE: this is 'size' not 'data_length', size is
+ * (NOTE: this is 'size' not 'data_length'; size is
* the full size of the entry.)
*/
if (swab32(buf[i].size) == master->erasesize) {
@@ -104,15 +104,13 @@ static int parse_redboot_partitions(struct mtd_info *master,
/* The unsigned long fields were written with the
* wrong byte sex, name and pad have no byte sex.
*/
-# define do_swab32(x) (x) = swab32(x)
- do_swab32(buf[j].flash_base);
- do_swab32(buf[j].mem_base);
- do_swab32(buf[j].size);
- do_swab32(buf[j].entry_point);
- do_swab32(buf[j].data_length);
- do_swab32(buf[j].desc_cksum);
- do_swab32(buf[j].file_cksum);
-# undef do_swab32
+ swab32s(&buf[j].flash_base);
+ swab32s(&buf[j].mem_base);
+ swab32s(&buf[j].size);
+ swab32s(&buf[j].entry_point);
+ swab32s(&buf[j].data_length);
+ swab32s(&buf[j].desc_cksum);
+ swab32s(&buf[j].file_cksum);
}
}
break;
diff --git a/drivers/net/chelsio/espi.c b/drivers/net/chelsio/espi.c
index 230642571c9..e824acaf188 100644
--- a/drivers/net/chelsio/espi.c
+++ b/drivers/net/chelsio/espi.c
@@ -296,9 +296,7 @@ void t1_espi_destroy(struct peespi *espi)
struct peespi *t1_espi_create(adapter_t *adapter)
{
- struct peespi *espi = kmalloc(sizeof(*espi), GFP_KERNEL);
-
- memset(espi, 0, sizeof(*espi));
+ struct peespi *espi = kzalloc(sizeof(*espi), GFP_KERNEL);
if (espi)
espi->adapter = adapter;
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 27c77306193..99baf0e099f 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -225,9 +225,6 @@ struct e1000_rx_ring {
struct e1000_ps_page *ps_page;
struct e1000_ps_page_dma *ps_page_dma;
- struct sk_buff *rx_skb_top;
- struct sk_buff *rx_skb_prev;
-
/* cpu for rx queue */
int cpu;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 31e332935e5..5b7d0f425af 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -103,7 +103,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
#else
#define DRIVERNAPI "-NAPI"
#endif
-#define DRV_VERSION "6.3.9-k2"DRIVERNAPI
+#define DRV_VERSION "6.3.9-k4"DRIVERNAPI
char e1000_driver_version[] = DRV_VERSION;
static char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
@@ -1635,8 +1635,6 @@ setup_rx_desc_die:
rxdr->next_to_clean = 0;
rxdr->next_to_use = 0;
- rxdr->rx_skb_top = NULL;
- rxdr->rx_skb_prev = NULL;
return 0;
}
@@ -1713,8 +1711,23 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
rctl |= adapter->rx_buffer_len << 0x11;
} else {
rctl &= ~E1000_RCTL_SZ_4096;
- rctl &= ~E1000_RCTL_BSEX;
- rctl |= E1000_RCTL_SZ_2048;
+ rctl |= E1000_RCTL_BSEX;
+ switch (adapter->rx_buffer_len) {
+ case E1000_RXBUFFER_2048:
+ default:
+ rctl |= E1000_RCTL_SZ_2048;
+ rctl &= ~E1000_RCTL_BSEX;
+ break;
+ case E1000_RXBUFFER_4096:
+ rctl |= E1000_RCTL_SZ_4096;
+ break;
+ case E1000_RXBUFFER_8192:
+ rctl |= E1000_RCTL_SZ_8192;
+ break;
+ case E1000_RXBUFFER_16384:
+ rctl |= E1000_RCTL_SZ_16384;
+ break;
+ }
}
#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
@@ -2107,16 +2120,6 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter,
}
}
- /* there also may be some cached data in our adapter */
- if (rx_ring->rx_skb_top) {
- dev_kfree_skb(rx_ring->rx_skb_top);
-
- /* rx_skb_prev will be wiped out by rx_skb_top */
- rx_ring->rx_skb_top = NULL;
- rx_ring->rx_skb_prev = NULL;
- }
-
-
size = sizeof(struct e1000_buffer) * rx_ring->count;
memset(rx_ring->buffer_info, 0, size);
size = sizeof(struct e1000_ps_page) * rx_ring->count;
@@ -3106,24 +3109,27 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
break;
}
- /* since the driver code now supports splitting a packet across
- * multiple descriptors, most of the fifo related limitations on
- * jumbo frame traffic have gone away.
- * simply use 2k descriptors for everything.
- *
- * NOTE: dev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
- * means we reserve 2 more, this pushes us to allocate from the next
- * larger slab size
- * i.e. RXBUFFER_2048 --> size-4096 slab */
-
- /* recent hardware supports 1KB granularity */
+
if (adapter->hw.mac_type > e1000_82547_rev_2) {
- adapter->rx_buffer_len =
- ((max_frame < E1000_RXBUFFER_2048) ?
- max_frame : E1000_RXBUFFER_2048);
+ adapter->rx_buffer_len = max_frame;
E1000_ROUNDUP(adapter->rx_buffer_len, 1024);
- } else
- adapter->rx_buffer_len = E1000_RXBUFFER_2048;
+ } else {
+ if(unlikely((adapter->hw.mac_type < e1000_82543) &&
+ (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE))) {
+ DPRINTK(PROBE, ERR, "Jumbo Frames not supported "
+ "on 82542\n");
+ return -EINVAL;
+ } else {
+ if(max_frame <= E1000_RXBUFFER_2048)
+ adapter->rx_buffer_len = E1000_RXBUFFER_2048;
+ else if(max_frame <= E1000_RXBUFFER_4096)
+ adapter->rx_buffer_len = E1000_RXBUFFER_4096;
+ else if(max_frame <= E1000_RXBUFFER_8192)
+ adapter->rx_buffer_len = E1000_RXBUFFER_8192;
+ else if(max_frame <= E1000_RXBUFFER_16384)
+ adapter->rx_buffer_len = E1000_RXBUFFER_16384;
+ }
+ }
netdev->mtu = new_mtu;
@@ -3620,7 +3626,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
uint8_t last_byte;
unsigned int i;
int cleaned_count = 0;
- boolean_t cleaned = FALSE, multi_descriptor = FALSE;
+ boolean_t cleaned = FALSE;
i = rx_ring->next_to_clean;
rx_desc = E1000_RX_DESC(*rx_ring, i);
@@ -3652,43 +3658,12 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
length = le16_to_cpu(rx_desc->length);
- skb_put(skb, length);
-
- if (!(status & E1000_RXD_STAT_EOP)) {
- if (!rx_ring->rx_skb_top) {
- rx_ring->rx_skb_top = skb;
- rx_ring->rx_skb_top->len = length;
- rx_ring->rx_skb_prev = skb;
- } else {
- if (skb_shinfo(rx_ring->rx_skb_top)->frag_list) {
- rx_ring->rx_skb_prev->next = skb;
- skb->prev = rx_ring->rx_skb_prev;
- } else {
- skb_shinfo(rx_ring->rx_skb_top)->frag_list = skb;
- }
- rx_ring->rx_skb_prev = skb;
- rx_ring->rx_skb_top->data_len += length;
- }
+ if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
+ /* All receives must fit into a single buffer */
+ E1000_DBG("%s: Receive packet consumed multiple"
+ " buffers\n", netdev->name);
+ dev_kfree_skb_irq(skb);
goto next_desc;
- } else {
- if (rx_ring->rx_skb_top) {
- if (skb_shinfo(rx_ring->rx_skb_top)
- ->frag_list) {
- rx_ring->rx_skb_prev->next = skb;
- skb->prev = rx_ring->rx_skb_prev;
- } else
- skb_shinfo(rx_ring->rx_skb_top)
- ->frag_list = skb;
-
- rx_ring->rx_skb_top->data_len += length;
- rx_ring->rx_skb_top->len +=
- rx_ring->rx_skb_top->data_len;
-
- skb = rx_ring->rx_skb_top;
- multi_descriptor = TRUE;
- rx_ring->rx_skb_top = NULL;
- rx_ring->rx_skb_prev = NULL;
- }
}
if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
@@ -3712,10 +3687,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
* performance for small packets with large amounts
* of reassembly being done in the stack */
#define E1000_CB_LENGTH 256
- if ((length < E1000_CB_LENGTH) &&
- !rx_ring->rx_skb_top &&
- /* or maybe (status & E1000_RXD_STAT_EOP) && */
- !multi_descriptor) {
+ if (length < E1000_CB_LENGTH) {
struct sk_buff *new_skb =
dev_alloc_skb(length + NET_IP_ALIGN);
if (new_skb) {
@@ -3729,7 +3701,8 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
skb = new_skb;
skb_put(skb, length);
}
- }
+ } else
+ skb_put(skb, length);
/* end copybreak code */
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 01ddfc8cce3..aa558136939 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -806,6 +806,7 @@ static struct pcmcia_device_id axnet_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309),
PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1106),
PCMCIA_DEVICE_MANF_CARD(0x8a01, 0xc1ab),
+ PCMCIA_DEVICE_PROD_ID12("AmbiCom,Inc.", "Fast Ethernet PC Card(AMB8110)", 0x49b020a7, 0x119cc9fc),
PCMCIA_DEVICE_PROD_ID124("Fast Ethernet", "16-bit PC Card", "AX88190", 0xb4be14e3, 0x9a12eb6a, 0xab9be5ef),
PCMCIA_DEVICE_PROD_ID12("ASIX", "AX88190", 0x0959823b, 0xab9be5ef),
PCMCIA_DEVICE_PROD_ID12("Billionton", "LNA-100B", 0x552ab682, 0xbc3b87e1),
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 49b597cbc19..b7f00d6eb6a 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -4092,6 +4092,7 @@ static void s2io_set_multicast(struct net_device *dev)
i++, mclist = mclist->next) {
memcpy(sp->usr_addrs[i].addr, mclist->dmi_addr,
ETH_ALEN);
+ mac_addr = 0;
for (j = 0; j < ETH_ALEN; j++) {
mac_addr |= mclist->dmi_addr[j];
mac_addr <<= 8;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index e8e92c853e8..15545620ab0 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -3532,9 +3532,23 @@ static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len)
(base + len + 8 < base));
}
+/* Test for DMA addresses > 40-bit */
+static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
+ int len)
+{
+#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
+ if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
+ return (((u64) mapping + len) > DMA_40BIT_MASK);
+ return 0;
+#else
+ return 0;
+#endif
+}
+
static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32);
-static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
+/* Workaround 4GB and 40-bit hardware DMA bugs. */
+static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
u32 last_plus_one, u32 *start,
u32 base_flags, u32 mss)
{
@@ -3742,6 +3756,9 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (tg3_4g_overflow_test(mapping, len))
would_hit_hwbug = 1;
+ if (tg3_40bit_overflow_test(tp, mapping, len))
+ would_hit_hwbug = 1;
+
if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
tg3_set_txd(tp, entry, mapping, len,
base_flags, (i == last)|(mss << 1));
@@ -3763,7 +3780,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* If the workaround fails due to memory/mapping
* failure, silently drop this packet.
*/
- if (tigon3_4gb_hwbug_workaround(tp, skb, last_plus_one,
+ if (tigon3_dma_hwbug_workaround(tp, skb, last_plus_one,
&start, base_flags, mss))
goto out_unlock;
@@ -10608,8 +10625,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
unsigned long tg3reg_base, tg3reg_len;
struct net_device *dev;
struct tg3 *tp;
- int i, err, pci_using_dac, pm_cap;
+ int i, err, pm_cap;
char str[40];
+ u64 dma_mask, persist_dma_mask;
if (tg3_version_printed++ == 0)
printk(KERN_INFO "%s", version);
@@ -10646,26 +10664,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
goto err_out_free_res;
}
- /* Configure DMA attributes. */
- err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
- if (!err) {
- pci_using_dac = 1;
- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
- if (err < 0) {
- printk(KERN_ERR PFX "Unable to obtain 64 bit DMA "
- "for consistent allocations\n");
- goto err_out_free_res;
- }
- } else {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
- if (err) {
- printk(KERN_ERR PFX "No usable DMA configuration, "
- "aborting.\n");
- goto err_out_free_res;
- }
- pci_using_dac = 0;
- }
-
tg3reg_base = pci_resource_start(pdev, 0);
tg3reg_len = pci_resource_len(pdev, 0);
@@ -10679,8 +10677,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
- if (pci_using_dac)
- dev->features |= NETIF_F_HIGHDMA;
dev->features |= NETIF_F_LLTX;
#if TG3_VLAN_TAG_USED
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
@@ -10765,6 +10761,44 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
goto err_out_iounmap;
}
+ /* 5714, 5715 and 5780 cannot support DMA addresses > 40-bit.
+ * On 64-bit systems with IOMMU, use 40-bit dma_mask.
+ * On 64-bit systems without IOMMU, use 64-bit dma_mask and
+ * do DMA address check in tg3_start_xmit().
+ */
+ if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
+ persist_dma_mask = dma_mask = DMA_40BIT_MASK;
+#ifdef CONFIG_HIGHMEM
+ dma_mask = DMA_64BIT_MASK;
+#endif
+ } else if (tp->tg3_flags2 & TG3_FLG2_IS_5788)
+ persist_dma_mask = dma_mask = DMA_32BIT_MASK;
+ else
+ persist_dma_mask = dma_mask = DMA_64BIT_MASK;
+
+ /* Configure DMA attributes. */
+ if (dma_mask > DMA_32BIT_MASK) {
+ err = pci_set_dma_mask(pdev, dma_mask);
+ if (!err) {
+ dev->features |= NETIF_F_HIGHDMA;
+ err = pci_set_consistent_dma_mask(pdev,
+ persist_dma_mask);
+ if (err < 0) {
+ printk(KERN_ERR PFX "Unable to obtain 64 bit "
+ "DMA for consistent allocations\n");
+ goto err_out_iounmap;
+ }
+ }
+ }
+ if (err || dma_mask == DMA_32BIT_MASK) {
+ err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (err) {
+ printk(KERN_ERR PFX "No usable DMA configuration, "
+ "aborting.\n");
+ goto err_out_iounmap;
+ }
+ }
+
tg3_init_bufmgr_config(tp);
#if TG3_TSO_SUPPORT != 0
@@ -10833,9 +10867,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
} else
tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
- if (tp->tg3_flags2 & TG3_FLG2_IS_5788)
- dev->features &= ~NETIF_F_HIGHDMA;
-
/* flow control autonegotiation is default behavior */
tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 8bc0b528548..f8f4503475f 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -877,7 +877,6 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777),
PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000),
PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),
PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030b),
PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612),
@@ -891,6 +890,10 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002),
PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005),
PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010),
+ PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "INTERSIL",
+ 0x74c5e40d),
+ PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "Intersil",
+ 0x4b801a17),
PCMCIA_MFC_DEVICE_PROD_ID12(0, "SanDisk", "ConnectPlus",
0x7a954bd9, 0x74be00c6),
PCMCIA_DEVICE_PROD_ID1234(
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index 166de350778..10845253c9e 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -312,8 +312,7 @@ static int __devinit parport_register (struct pci_dev *dev,
{
struct parport_pc_pci *card;
struct parport_serial_private *priv = pci_get_drvdata (dev);
- int i = id->driver_data, n;
- int success = 0;
+ int n, success = 0;
priv->par = cards[id->driver_data];
card = &priv->par;
@@ -344,10 +343,8 @@ static int __devinit parport_register (struct pci_dev *dev,
"hi" as an offset (see SYBA
def.) */
/* TODO: test if sharing interrupts works */
- printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, "
- "I/O at %#lx(%#lx)\n",
- parport_serial_pci_tbl[i].vendor,
- parport_serial_pci_tbl[i].device, io_lo, io_hi);
+ dev_dbg(&dev->dev, "PCI parallel port detected: I/O at "
+ "%#lx(%#lx)\n", io_lo, io_hi);
port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
PARPORT_DMA_NONE, dev);
if (port) {
@@ -359,7 +356,7 @@ static int __devinit parport_register (struct pci_dev *dev,
if (card->postinit_hook)
card->postinit_hook (dev, card, !success);
- return success ? 0 : 1;
+ return 0;
}
static int __devinit parport_serial_pci_probe (struct pci_dev *dev,
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 0a424a4e818..bb96ce1db08 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -352,11 +352,20 @@ static void pcmcia_release_dev(struct device *dev)
kfree(p_dev);
}
+static void pcmcia_add_pseudo_device(struct pcmcia_socket *s)
+{
+ if (!s->pcmcia_state.device_add_pending) {
+ s->pcmcia_state.device_add_pending = 1;
+ schedule_work(&s->device_add);
+ }
+ return;
+}
static int pcmcia_device_probe(struct device * dev)
{
struct pcmcia_device *p_dev;
struct pcmcia_driver *p_drv;
+ struct pcmcia_device_id *did;
struct pcmcia_socket *s;
int ret = 0;
@@ -392,6 +401,19 @@ static int pcmcia_device_probe(struct device * dev)
}
ret = p_drv->probe(p_dev);
+ if (ret)
+ goto put_module;
+
+ /* handle pseudo multifunction devices:
+ * there are at most two pseudo multifunction devices.
+ * if we're matching against the first, schedule a
+ * call which will then check whether there are two
+ * pseudo devices, and if not, add the second one.
+ */
+ did = (struct pcmcia_device_id *) p_dev->dev.driver_data;
+ if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
+ (p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
+ pcmcia_add_pseudo_device(p_dev->socket);
put_module:
if (ret)
@@ -660,15 +682,6 @@ static void pcmcia_delayed_add_pseudo_device(void *data)
s->pcmcia_state.device_add_pending = 0;
}
-static inline void pcmcia_add_pseudo_device(struct pcmcia_socket *s)
-{
- if (!s->pcmcia_state.device_add_pending) {
- s->pcmcia_state.device_add_pending = 1;
- schedule_work(&s->device_add);
- }
- return;
-}
-
static int pcmcia_requery(struct device *dev, void * _data)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
@@ -755,15 +768,6 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
}
if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) {
- /* handle pseudo multifunction devices:
- * there are at most two pseudo multifunction devices.
- * if we're matching against the first, schedule a
- * call which will then check whether there are two
- * pseudo devices, and if not, add the second one.
- */
- if (dev->device_no == 0)
- pcmcia_add_pseudo_device(dev->socket);
-
if (dev->device_no != did->device_no)
return 0;
}
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index af1d5b404ce..33157c84d1d 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -215,9 +215,10 @@ dasd_state_basic_to_known(struct dasd_device * device)
* interrupt for this detection ccw uses the kernel event daemon to
* trigger the call to dasd_change_state. All this is done in the
* discipline code, see dasd_eckd.c.
- * After the analysis ccw is done (do_analysis returned 0 or error)
- * the block device is setup. Either a fake disk is added to allow
- * formatting or a proper device request queue is created.
+ * After the analysis ccw is done (do_analysis returned 0) the block
+ * device is setup.
+ * In case the analysis returns an error, the device setup is stopped
+ * (a fake disk was already added to allow formatting).
*/
static inline int
dasd_state_basic_to_ready(struct dasd_device * device)
@@ -227,13 +228,19 @@ dasd_state_basic_to_ready(struct dasd_device * device)
rc = 0;
if (device->discipline->do_analysis != NULL)
rc = device->discipline->do_analysis(device);
- if (rc)
+ if (rc) {
+ if (rc != -EAGAIN)
+ device->state = DASD_STATE_UNFMT;
return rc;
+ }
+ /* make disk known with correct capacity */
dasd_setup_queue(device);
+ set_capacity(device->gdp, device->blocks << device->s2b_shift);
device->state = DASD_STATE_READY;
- if (dasd_scan_partitions(device) != 0)
+ rc = dasd_scan_partitions(device);
+ if (rc)
device->state = DASD_STATE_BASIC;
- return 0;
+ return rc;
}
/*
@@ -254,6 +261,15 @@ dasd_state_ready_to_basic(struct dasd_device * device)
}
/*
+ * Back to basic.
+ */
+static inline void
+dasd_state_unfmt_to_basic(struct dasd_device * device)
+{
+ device->state = DASD_STATE_BASIC;
+}
+
+/*
* Make the device online and schedule the bottom half to start
* the requeueing of requests from the linux request queue to the
* ccw queue.
@@ -319,8 +335,12 @@ dasd_decrease_state(struct dasd_device *device)
if (device->state == DASD_STATE_READY &&
device->target <= DASD_STATE_BASIC)
dasd_state_ready_to_basic(device);
-
- if (device->state == DASD_STATE_BASIC &&
+
+ if (device->state == DASD_STATE_UNFMT &&
+ device->target <= DASD_STATE_BASIC)
+ dasd_state_unfmt_to_basic(device);
+
+ if (device->state == DASD_STATE_BASIC &&
device->target <= DASD_STATE_KNOWN)
dasd_state_basic_to_known(device);
@@ -1722,7 +1742,7 @@ dasd_open(struct inode *inp, struct file *filp)
goto out;
}
- if (device->state < DASD_STATE_BASIC) {
+ if (device->state <= DASD_STATE_BASIC) {
DBF_DEV_EVENT(DBF_ERR, device, " %s",
" Cannot open unrecognized device");
rc = -ENODEV;
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index 65dc844b975..fce2835e7d1 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -100,8 +100,6 @@ dasd_scan_partitions(struct dasd_device * device)
{
struct block_device *bdev;
- /* Make the disk known. */
- set_capacity(device->gdp, device->blocks << device->s2b_shift);
bdev = bdget_disk(device->gdp, 0);
if (!bdev || blkdev_get(bdev, FMODE_READ, 1) < 0)
return -ENODEV;
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 0592354cc60..7cb0b9e78a6 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -26,7 +26,7 @@
* new: the dasd_device structure is allocated.
* known: the discipline for the device is identified.
* basic: the device can do basic i/o.
- * accept: the device is analysed (format is known).
+ * unfmt: the device could not be analyzed (format is unknown).
* ready: partition detection is done and the device is can do block io.
* online: the device accepts requests from the block device queue.
*
@@ -47,8 +47,9 @@
#define DASD_STATE_NEW 0
#define DASD_STATE_KNOWN 1
#define DASD_STATE_BASIC 2
-#define DASD_STATE_READY 3
-#define DASD_STATE_ONLINE 4
+#define DASD_STATE_UNFMT 3
+#define DASD_STATE_READY 4
+#define DASD_STATE_ONLINE 5
#include <linux/module.h>
#include <linux/wait.h>
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 2d5da3c75ca..1aa3c261718 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -93,6 +93,9 @@ dasd_devices_show(struct seq_file *m, void *v)
case DASD_STATE_BASIC:
seq_printf(m, "basic");
break;
+ case DASD_STATE_UNFMT:
+ seq_printf(m, "unformatted");
+ break;
case DASD_STATE_READY:
case DASD_STATE_ONLINE:
seq_printf(m, "active ");
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 8cf9905d484..f4183d66025 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -1115,6 +1115,9 @@ chsc_enable_facility(int operation_code)
goto out;
}
switch (sda_area->response.code) {
+ case 0x0001: /* everything ok */
+ ret = 0;
+ break;
case 0x0003: /* invalid request block */
case 0x0007:
ret = -EINVAL;
@@ -1123,6 +1126,8 @@ chsc_enable_facility(int operation_code)
case 0x0101: /* facility not provided */
ret = -EOPNOTSUPP;
break;
+ default: /* something went wrong */
+ ret = -EIO;
}
out:
free_page((unsigned long)sda_area);
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index d6469baa7e1..72118ee6895 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -168,7 +168,7 @@ smsg_init(void)
driver_unregister(&smsg_driver);
return -EIO; /* better errno ? */
}
- rc = iucv_connect (&smsg_pathid, 1, 0, "*MSG ", 0, 0, 0, 0,
+ rc = iucv_connect (&smsg_pathid, 255, 0, "*MSG ", 0, 0, 0, 0,
smsg_handle, 0);
if (rc) {
printk(KERN_ERR "SMSGIUCV: failed to connect to *MSG");
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 1c2ab3dede7..00dfdefe296 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -778,23 +778,17 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *
struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->active_tag);
if (!ahci_host_intr(ap, qc))
- if (ata_ratelimit()) {
- struct pci_dev *pdev =
- to_pci_dev(ap->host_set->dev);
- dev_printk(KERN_WARNING, &pdev->dev,
+ if (ata_ratelimit())
+ dev_printk(KERN_WARNING, host_set->dev,
"unhandled interrupt on port %u\n",
i);
- }
VPRINTK("port %u\n", i);
} else {
VPRINTK("port %u (no irq)\n", i);
- if (ata_ratelimit()) {
- struct pci_dev *pdev =
- to_pci_dev(ap->host_set->dev);
- dev_printk(KERN_WARNING, &pdev->dev,
+ if (ata_ratelimit())
+ dev_printk(KERN_WARNING, host_set->dev,
"interrupt on disabled port %u\n", i);
- }
}
irq_ack |= (1 << i);
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index c662bf53151..9327b62f97d 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -101,6 +101,8 @@ enum {
ICH5_PCS = 0x92, /* port control and status */
PIIX_SCC = 0x0A, /* sub-class code register */
+ PIIX_FLAG_IGNORE_PCS = (1 << 25), /* ignore PCS present bits */
+ PIIX_FLAG_SCR = (1 << 26), /* SCR available */
PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */
PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */
PIIX_FLAG_COMBINED = (1 << 29), /* combined mode possible */
@@ -110,24 +112,38 @@ enum {
/* combined mode. if set, PATA is channel 0.
* if clear, PATA is channel 1.
*/
- PIIX_COMB_PATA_P0 = (1 << 1),
- PIIX_COMB = (1 << 2), /* combined mode enabled? */
-
PIIX_PORT_ENABLED = (1 << 0),
PIIX_PORT_PRESENT = (1 << 4),
PIIX_80C_PRI = (1 << 5) | (1 << 4),
PIIX_80C_SEC = (1 << 7) | (1 << 6),
- ich5_pata = 0,
- ich5_sata = 1,
- piix4_pata = 2,
- ich6_sata = 3,
- ich6_sata_ahci = 4,
+ /* controller IDs */
+ piix4_pata = 0,
+ ich5_pata = 1,
+ ich5_sata = 2,
+ esb_sata = 3,
+ ich6_sata = 4,
+ ich6_sata_ahci = 5,
+ ich6m_sata_ahci = 6,
+
+ /* constants for mapping table */
+ P0 = 0, /* port 0 */
+ P1 = 1, /* port 1 */
+ P2 = 2, /* port 2 */
+ P3 = 3, /* port 3 */
+ IDE = -1, /* IDE */
+ NA = -2, /* not avaliable */
+ RV = -3, /* reserved */
PIIX_AHCI_DEVICE = 6,
};
+struct piix_map_db {
+ const u32 mask;
+ const int map[][4];
+};
+
static int piix_init_one (struct pci_dev *pdev,
const struct pci_device_id *ent);
@@ -149,19 +165,32 @@ static const struct pci_device_id piix_pci_tbl[] = {
* list in drivers/pci/quirks.c.
*/
+ /* 82801EB (ICH5) */
{ 0x8086, 0x24d1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
+ /* 82801EB (ICH5) */
{ 0x8086, 0x24df, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
- { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
- { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
+ /* 6300ESB (ICH5 variant with broken PCS present bits) */
+ { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_sata },
+ /* 6300ESB pretending RAID */
+ { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_sata },
+ /* 82801FB/FW (ICH6/ICH6W) */
{ 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
+ /* 82801FR/FRW (ICH6R/ICH6RW) */
{ 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
- { 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+ /* 82801FBM ICH6M (ICH6R with only port 0 and 2 implemented) */
+ { 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
+ /* 82801GB/GR/GH (ICH7, identical to ICH6) */
{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
- { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+ /* 2801GBM/GHM (ICH7M, identical to ICH6M) */
+ { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
+ /* Enterprise Southbridge 2 (where's the datasheet?) */
{ 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+ /* SATA Controller 1 IDE (ICH8, no datasheet yet) */
{ 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+ /* SATA Controller 2 IDE (ICH8, ditto) */
{ 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
- { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+ /* Mobile SATA Controller IDE (ICH8M, ditto) */
+ { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
{ } /* terminate list */
};
@@ -254,7 +283,58 @@ static const struct ata_port_operations piix_sata_ops = {
.host_stop = ata_host_stop,
};
+static struct piix_map_db ich5_map_db = {
+ .mask = 0x7,
+ .map = {
+ /* PM PS SM SS MAP */
+ { P0, NA, P1, NA }, /* 000b */
+ { P1, NA, P0, NA }, /* 001b */
+ { RV, RV, RV, RV },
+ { RV, RV, RV, RV },
+ { P0, P1, IDE, IDE }, /* 100b */
+ { P1, P0, IDE, IDE }, /* 101b */
+ { IDE, IDE, P0, P1 }, /* 110b */
+ { IDE, IDE, P1, P0 }, /* 111b */
+ },
+};
+
+static struct piix_map_db ich6_map_db = {
+ .mask = 0x3,
+ .map = {
+ /* PM PS SM SS MAP */
+ { P0, P1, P2, P3 }, /* 00b */
+ { IDE, IDE, P1, P3 }, /* 01b */
+ { P0, P2, IDE, IDE }, /* 10b */
+ { RV, RV, RV, RV },
+ },
+};
+
+static struct piix_map_db ich6m_map_db = {
+ .mask = 0x3,
+ .map = {
+ /* PM PS SM SS MAP */
+ { P0, P1, P2, P3 }, /* 00b */
+ { RV, RV, RV, RV },
+ { P0, P2, IDE, IDE }, /* 10b */
+ { RV, RV, RV, RV },
+ },
+};
+
static struct ata_port_info piix_port_info[] = {
+ /* piix4_pata */
+ {
+ .sht = &piix_sht,
+ .host_flags = ATA_FLAG_SLAVE_POSS,
+ .pio_mask = 0x1f, /* pio0-4 */
+#if 0
+ .mwdma_mask = 0x06, /* mwdma1-2 */
+#else
+ .mwdma_mask = 0x00, /* mwdma broken */
+#endif
+ .udma_mask = ATA_UDMA_MASK_40C,
+ .port_ops = &piix_pata_ops,
+ },
+
/* ich5_pata */
{
.sht = &piix_sht,
@@ -278,43 +358,57 @@ static struct ata_port_info piix_port_info[] = {
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &piix_sata_ops,
+ .private_data = &ich5_map_db,
},
- /* piix4_pata */
+ /* i6300esb_sata */
{
.sht = &piix_sht,
- .host_flags = ATA_FLAG_SLAVE_POSS,
+ .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED |
+ PIIX_FLAG_CHECKINTR | PIIX_FLAG_IGNORE_PCS,
.pio_mask = 0x1f, /* pio0-4 */
-#if 0
- .mwdma_mask = 0x06, /* mwdma1-2 */
-#else
- .mwdma_mask = 0x00, /* mwdma broken */
-#endif
- .udma_mask = ATA_UDMA_MASK_40C,
- .port_ops = &piix_pata_ops,
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x7f, /* udma0-6 */
+ .port_ops = &piix_sata_ops,
+ .private_data = &ich5_map_db,
},
/* ich6_sata */
{
.sht = &piix_sht,
.host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
- PIIX_FLAG_CHECKINTR | ATA_FLAG_SLAVE_POSS,
+ PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &piix_sata_ops,
+ .private_data = &ich6_map_db,
},
/* ich6_sata_ahci */
{
.sht = &piix_sht,
.host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
- PIIX_FLAG_CHECKINTR | ATA_FLAG_SLAVE_POSS |
+ PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
PIIX_FLAG_AHCI,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &piix_sata_ops,
+ .private_data = &ich6_map_db,
+ },
+
+ /* ich6m_sata_ahci */
+ {
+ .sht = &piix_sht,
+ .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
+ PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
+ PIIX_FLAG_AHCI,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x7f, /* udma0-6 */
+ .port_ops = &piix_sata_ops,
+ .private_data = &ich6m_map_db,
},
};
@@ -405,44 +499,59 @@ static int piix_pata_probe_reset(struct ata_port *ap, unsigned int *classes)
* piix_sata_probe - Probe PCI device for present SATA devices
* @ap: Port associated with the PCI device we wish to probe
*
- * Reads SATA PCI device's PCI config register Port Configuration
- * and Status (PCS) to determine port and device availability.
+ * Reads and configures SATA PCI device's PCI config register
+ * Port Configuration and Status (PCS) to determine port and
+ * device availability.
*
* LOCKING:
* None (inherited from caller).
*
* RETURNS:
- * Non-zero if port is enabled, it may or may not have a device
- * attached in that case (PRESENT bit would only be set if BIOS probe
- * was done). Zero is returned if port is disabled.
+ * Mask of avaliable devices on the port.
*/
-static int piix_sata_probe (struct ata_port *ap)
+static unsigned int piix_sata_probe (struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
- int combined = (ap->flags & ATA_FLAG_SLAVE_POSS);
- int orig_mask, mask, i;
+ const unsigned int *map = ap->host_set->private_data;
+ int base = 2 * ap->hard_port_no;
+ unsigned int present_mask = 0;
+ int port, i;
u8 pcs;
pci_read_config_byte(pdev, ICH5_PCS, &pcs);
- orig_mask = (int) pcs & 0xff;
-
- /* TODO: this is vaguely wrong for ICH6 combined mode,
- * where only two of the four SATA ports are mapped
- * onto a single ATA channel. It is also vaguely inaccurate
- * for ICH5, which has only two ports. However, this is ok,
- * as further device presence detection code will handle
- * any false positives produced here.
- */
+ DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base);
- for (i = 0; i < 4; i++) {
- mask = (PIIX_PORT_ENABLED << i);
+ /* enable all ports on this ap and wait for them to settle */
+ for (i = 0; i < 2; i++) {
+ port = map[base + i];
+ if (port >= 0)
+ pcs |= 1 << port;
+ }
- if ((orig_mask & mask) == mask)
- if (combined || (i == ap->hard_port_no))
- return 1;
+ pci_write_config_byte(pdev, ICH5_PCS, pcs);
+ msleep(100);
+
+ /* let's see which devices are present */
+ pci_read_config_byte(pdev, ICH5_PCS, &pcs);
+
+ for (i = 0; i < 2; i++) {
+ port = map[base + i];
+ if (port < 0)
+ continue;
+ if (ap->flags & PIIX_FLAG_IGNORE_PCS || pcs & 1 << (4 + port))
+ present_mask |= 1 << i;
+ else
+ pcs &= ~(1 << port);
}
- return 0;
+ /* disable offline ports on non-AHCI controllers */
+ if (!(ap->flags & PIIX_FLAG_AHCI))
+ pci_write_config_byte(pdev, ICH5_PCS, pcs);
+
+ DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n",
+ ap->id, pcs, present_mask);
+
+ return present_mask;
}
/**
@@ -666,6 +775,54 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
return no_piix_dma;
}
+static void __devinit piix_init_sata_map(struct pci_dev *pdev,
+ struct ata_port_info *pinfo)
+{
+ struct piix_map_db *map_db = pinfo[0].private_data;
+ const unsigned int *map;
+ int i, invalid_map = 0;
+ u8 map_value;
+
+ pci_read_config_byte(pdev, ICH5_PMR, &map_value);
+
+ map = map_db->map[map_value & map_db->mask];
+
+ dev_printk(KERN_INFO, &pdev->dev, "MAP [");
+ for (i = 0; i < 4; i++) {
+ switch (map[i]) {
+ case RV:
+ invalid_map = 1;
+ printk(" XX");
+ break;
+
+ case NA:
+ printk(" --");
+ break;
+
+ case IDE:
+ WARN_ON((i & 1) || map[i + 1] != IDE);
+ pinfo[i / 2] = piix_port_info[ich5_pata];
+ i++;
+ printk(" IDE IDE");
+ break;
+
+ default:
+ printk(" P%d", map[i]);
+ if (i & 1)
+ pinfo[i / 2].host_flags |= ATA_FLAG_SLAVE_POSS;
+ break;
+ }
+ }
+ printk(" ]\n");
+
+ if (invalid_map)
+ dev_printk(KERN_ERR, &pdev->dev,
+ "invalid MAP value %u\n", map_value);
+
+ pinfo[0].private_data = (void *)map;
+ pinfo[1].private_data = (void *)map;
+}
+
/**
* piix_init_one - Register PIIX ATA PCI device with kernel services
* @pdev: PCI device to register
@@ -684,9 +841,8 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_port_info *port_info[2];
- unsigned int combined = 0;
- unsigned int pata_chan = 0, sata_chan = 0;
+ struct ata_port_info port_info[2];
+ struct ata_port_info *ppinfo[2] = { &port_info[0], &port_info[1] };
unsigned long host_flags;
if (!printed_version++)
@@ -697,10 +853,10 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (!in_module_init)
return -ENODEV;
- port_info[0] = &piix_port_info[ent->driver_data];
- port_info[1] = &piix_port_info[ent->driver_data];
+ port_info[0] = piix_port_info[ent->driver_data];
+ port_info[1] = piix_port_info[ent->driver_data];
- host_flags = port_info[0]->host_flags;
+ host_flags = port_info[0].host_flags;
if (host_flags & PIIX_FLAG_AHCI) {
u8 tmp;
@@ -712,37 +868,9 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
}
}
- if (host_flags & PIIX_FLAG_COMBINED) {
- u8 tmp;
- pci_read_config_byte(pdev, ICH5_PMR, &tmp);
-
- if (host_flags & PIIX_FLAG_COMBINED_ICH6) {
- switch (tmp & 0x3) {
- case 0:
- break;
- case 1:
- combined = 1;
- sata_chan = 1;
- break;
- case 2:
- combined = 1;
- pata_chan = 1;
- break;
- case 3:
- dev_printk(KERN_WARNING, &pdev->dev,
- "invalid MAP value %u\n", tmp);
- break;
- }
- } else {
- if (tmp & PIIX_COMB) {
- combined = 1;
- if (tmp & PIIX_COMB_PATA_P0)
- sata_chan = 1;
- else
- pata_chan = 1;
- }
- }
- }
+ /* Initialize SATA map */
+ if (host_flags & ATA_FLAG_SATA)
+ piix_init_sata_map(pdev, port_info);
/* On ICH5, some BIOSen disable the interrupt using the
* PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3.
@@ -753,25 +881,16 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (host_flags & PIIX_FLAG_CHECKINTR)
pci_intx(pdev, 1);
- if (combined) {
- port_info[sata_chan] = &piix_port_info[ent->driver_data];
- port_info[sata_chan]->host_flags |= ATA_FLAG_SLAVE_POSS;
- port_info[pata_chan] = &piix_port_info[ich5_pata];
-
- dev_printk(KERN_WARNING, &pdev->dev,
- "combined mode detected (p=%u, s=%u)\n",
- pata_chan, sata_chan);
- }
if (piix_check_450nx_errata(pdev)) {
/* This writes into the master table but it does not
really matter for this errata as we will apply it to
all the PIIX devices on the board */
- port_info[0]->mwdma_mask = 0;
- port_info[0]->udma_mask = 0;
- port_info[1]->mwdma_mask = 0;
- port_info[1]->udma_mask = 0;
+ port_info[0].mwdma_mask = 0;
+ port_info[0].udma_mask = 0;
+ port_info[1].mwdma_mask = 0;
+ port_info[1].udma_mask = 0;
}
- return ata_pci_init_one(pdev, port_info, 2);
+ return ata_pci_init_one(pdev, ppinfo, 2);
}
static int __init piix_init(void)
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 9132698d29b..5060a1a1ad2 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -65,12 +65,9 @@ static unsigned int ata_dev_init_params(struct ata_port *ap,
struct ata_device *dev);
static void ata_set_mode(struct ata_port *ap);
static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev);
-static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift);
-static int fgb(u32 bitmap);
-static int ata_choose_xfer_mode(const struct ata_port *ap,
- u8 *xfer_mode_out,
- unsigned int *xfer_shift_out);
static void ata_pio_error(struct ata_port *ap);
+static unsigned int ata_dev_xfermask(struct ata_port *ap,
+ struct ata_device *dev);
static unsigned int ata_unique_id = 1;
static struct workqueue_struct *ata_wq;
@@ -232,58 +229,148 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
return -1;
}
-static const char * const xfer_mode_str[] = {
- "UDMA/16",
- "UDMA/25",
- "UDMA/33",
- "UDMA/44",
- "UDMA/66",
- "UDMA/100",
- "UDMA/133",
- "UDMA7",
- "MWDMA0",
- "MWDMA1",
- "MWDMA2",
- "PIO0",
- "PIO1",
- "PIO2",
- "PIO3",
- "PIO4",
+/**
+ * ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask
+ * @pio_mask: pio_mask
+ * @mwdma_mask: mwdma_mask
+ * @udma_mask: udma_mask
+ *
+ * Pack @pio_mask, @mwdma_mask and @udma_mask into a single
+ * unsigned int xfer_mask.
+ *
+ * LOCKING:
+ * None.
+ *
+ * RETURNS:
+ * Packed xfer_mask.
+ */
+static unsigned int ata_pack_xfermask(unsigned int pio_mask,
+ unsigned int mwdma_mask,
+ unsigned int udma_mask)
+{
+ return ((pio_mask << ATA_SHIFT_PIO) & ATA_MASK_PIO) |
+ ((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) |
+ ((udma_mask << ATA_SHIFT_UDMA) & ATA_MASK_UDMA);
+}
+
+static const struct ata_xfer_ent {
+ unsigned int shift, bits;
+ u8 base;
+} ata_xfer_tbl[] = {
+ { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 },
+ { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 },
+ { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 },
+ { -1, },
};
/**
- * ata_udma_string - convert UDMA bit offset to string
- * @mask: mask of bits supported; only highest bit counts.
+ * ata_xfer_mask2mode - Find matching XFER_* for the given xfer_mask
+ * @xfer_mask: xfer_mask of interest
*
- * Determine string which represents the highest speed
- * (highest bit in @udma_mask).
+ * Return matching XFER_* value for @xfer_mask. Only the highest
+ * bit of @xfer_mask is considered.
*
* LOCKING:
* None.
*
* RETURNS:
- * Constant C string representing highest speed listed in
- * @udma_mask, or the constant C string "<n/a>".
+ * Matching XFER_* value, 0 if no match found.
*/
+static u8 ata_xfer_mask2mode(unsigned int xfer_mask)
+{
+ int highbit = fls(xfer_mask) - 1;
+ const struct ata_xfer_ent *ent;
-static const char *ata_mode_string(unsigned int mask)
+ for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
+ if (highbit >= ent->shift && highbit < ent->shift + ent->bits)
+ return ent->base + highbit - ent->shift;
+ return 0;
+}
+
+/**
+ * ata_xfer_mode2mask - Find matching xfer_mask for XFER_*
+ * @xfer_mode: XFER_* of interest
+ *
+ * Return matching xfer_mask for @xfer_mode.
+ *
+ * LOCKING:
+ * None.
+ *
+ * RETURNS:
+ * Matching xfer_mask, 0 if no match found.
+ */
+static unsigned int ata_xfer_mode2mask(u8 xfer_mode)
{
- int i;
+ const struct ata_xfer_ent *ent;
- for (i = 7; i >= 0; i--)
- if (mask & (1 << i))
- goto out;
- for (i = ATA_SHIFT_MWDMA + 2; i >= ATA_SHIFT_MWDMA; i--)
- if (mask & (1 << i))
- goto out;
- for (i = ATA_SHIFT_PIO + 4; i >= ATA_SHIFT_PIO; i--)
- if (mask & (1 << i))
- goto out;
+ for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
+ if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits)
+ return 1 << (ent->shift + xfer_mode - ent->base);
+ return 0;
+}
- return "<n/a>";
+/**
+ * ata_xfer_mode2shift - Find matching xfer_shift for XFER_*
+ * @xfer_mode: XFER_* of interest
+ *
+ * Return matching xfer_shift for @xfer_mode.
+ *
+ * LOCKING:
+ * None.
+ *
+ * RETURNS:
+ * Matching xfer_shift, -1 if no match found.
+ */
+static int ata_xfer_mode2shift(unsigned int xfer_mode)
+{
+ const struct ata_xfer_ent *ent;
-out:
- return xfer_mode_str[i];
+ for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
+ if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits)
+ return ent->shift;
+ return -1;
+}
+
+/**
+ * ata_mode_string - convert xfer_mask to string
+ * @xfer_mask: mask of bits supported; only highest bit counts.
+ *
+ * Determine string which represents the highest speed
+ * (highest bit in @modemask).
+ *
+ * LOCKING:
+ * None.
+ *
+ * RETURNS:
+ * Constant C string representing highest speed listed in
+ * @mode_mask, or the constant C string "<n/a>".
+ */
+static const char *ata_mode_string(unsigned int xfer_mask)
+{
+ static const char * const xfer_mode_str[] = {
+ "PIO0",
+ "PIO1",
+ "PIO2",
+ "PIO3",
+ "PIO4",
+ "MWDMA0",
+ "MWDMA1",
+ "MWDMA2",
+ "UDMA/16",
+ "UDMA/25",
+ "UDMA/33",
+ "UDMA/44",
+ "UDMA/66",
+ "UDMA/100",
+ "UDMA/133",
+ "UDMA7",
+ };
+ int highbit;
+
+ highbit = fls(xfer_mask) - 1;
+ if (highbit >= 0 && highbit < ARRAY_SIZE(xfer_mode_str))
+ return xfer_mode_str[highbit];
+ return "<n/a>";
}
/**
@@ -693,69 +780,104 @@ static inline void ata_dump_id(const u16 *id)
id[93]);
}
-/*
- * Compute the PIO modes available for this device. This is not as
- * trivial as it seems if we must consider early devices correctly.
+/**
+ * ata_id_xfermask - Compute xfermask from the given IDENTIFY data
+ * @id: IDENTIFY data to compute xfer mask from
*
- * FIXME: pre IDE drive timing (do we care ?).
+ * Compute the xfermask for this device. This is not as trivial
+ * as it seems if we must consider early devices correctly.
+ *
+ * FIXME: pre IDE drive timing (do we care ?).
+ *
+ * LOCKING:
+ * None.
+ *
+ * RETURNS:
+ * Computed xfermask
*/
-
-static unsigned int ata_pio_modes(const struct ata_device *adev)
+static unsigned int ata_id_xfermask(const u16 *id)
{
- u16 modes;
+ unsigned int pio_mask, mwdma_mask, udma_mask;
/* Usual case. Word 53 indicates word 64 is valid */
- if (adev->id[ATA_ID_FIELD_VALID] & (1 << 1)) {
- modes = adev->id[ATA_ID_PIO_MODES] & 0x03;
- modes <<= 3;
- modes |= 0x7;
- return modes;
+ if (id[ATA_ID_FIELD_VALID] & (1 << 1)) {
+ pio_mask = id[ATA_ID_PIO_MODES] & 0x03;
+ pio_mask <<= 3;
+ pio_mask |= 0x7;
+ } else {
+ /* If word 64 isn't valid then Word 51 high byte holds
+ * the PIO timing number for the maximum. Turn it into
+ * a mask.
+ */
+ pio_mask = (2 << (id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ;
+
+ /* But wait.. there's more. Design your standards by
+ * committee and you too can get a free iordy field to
+ * process. However its the speeds not the modes that
+ * are supported... Note drivers using the timing API
+ * will get this right anyway
+ */
}
- /* If word 64 isn't valid then Word 51 high byte holds the PIO timing
- number for the maximum. Turn it into a mask and return it */
- modes = (2 << ((adev->id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF)) - 1 ;
- return modes;
- /* But wait.. there's more. Design your standards by committee and
- you too can get a free iordy field to process. However its the
- speeds not the modes that are supported... Note drivers using the
- timing API will get this right anyway */
-}
+ mwdma_mask = id[ATA_ID_MWDMA_MODES] & 0x07;
+ udma_mask = id[ATA_ID_UDMA_MODES] & 0xff;
-static inline void
-ata_queue_pio_task(struct ata_port *ap)
-{
- if (!(ap->flags & ATA_FLAG_FLUSH_PIO_TASK))
- queue_work(ata_wq, &ap->pio_task);
+ return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask);
}
-static inline void
-ata_queue_delayed_pio_task(struct ata_port *ap, unsigned long delay)
+/**
+ * ata_port_queue_task - Queue port_task
+ * @ap: The ata_port to queue port_task for
+ *
+ * Schedule @fn(@data) for execution after @delay jiffies using
+ * port_task. There is one port_task per port and it's the
+ * user(low level driver)'s responsibility to make sure that only
+ * one task is active at any given time.
+ *
+ * libata core layer takes care of synchronization between
+ * port_task and EH. ata_port_queue_task() may be ignored for EH
+ * synchronization.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), void *data,
+ unsigned long delay)
{
- if (!(ap->flags & ATA_FLAG_FLUSH_PIO_TASK))
- queue_delayed_work(ata_wq, &ap->pio_task, delay);
+ int rc;
+
+ if (ap->flags & ATA_FLAG_FLUSH_PORT_TASK)
+ return;
+
+ PREPARE_WORK(&ap->port_task, fn, data);
+
+ if (!delay)
+ rc = queue_work(ata_wq, &ap->port_task);
+ else
+ rc = queue_delayed_work(ata_wq, &ap->port_task, delay);
+
+ /* rc == 0 means that another user is using port task */
+ WARN_ON(rc == 0);
}
/**
- * ata_flush_pio_tasks - Flush pio_task
- * @ap: the target ata_port
+ * ata_port_flush_task - Flush port_task
+ * @ap: The ata_port to flush port_task for
*
- * After this function completes, pio_task is
- * guranteed not to be running or scheduled.
+ * After this function completes, port_task is guranteed not to
+ * be running or scheduled.
*
* LOCKING:
* Kernel thread context (may sleep)
*/
-
-static void ata_flush_pio_tasks(struct ata_port *ap)
+void ata_port_flush_task(struct ata_port *ap)
{
- int tmp = 0;
unsigned long flags;
DPRINTK("ENTER\n");
spin_lock_irqsave(&ap->host_set->lock, flags);
- ap->flags |= ATA_FLAG_FLUSH_PIO_TASK;
+ ap->flags |= ATA_FLAG_FLUSH_PORT_TASK;
spin_unlock_irqrestore(&ap->host_set->lock, flags);
DPRINTK("flush #1\n");
@@ -766,14 +888,13 @@ static void ata_flush_pio_tasks(struct ata_port *ap)
* the FLUSH flag; thus, it will never queue pio tasks again.
* Cancel and flush.
*/
- tmp |= cancel_delayed_work(&ap->pio_task);
- if (!tmp) {
+ if (!cancel_delayed_work(&ap->port_task)) {
DPRINTK("flush #2\n");
flush_workqueue(ata_wq);
}
spin_lock_irqsave(&ap->host_set->lock, flags);
- ap->flags &= ~ATA_FLAG_FLUSH_PIO_TASK;
+ ap->flags &= ~ATA_FLAG_FLUSH_PORT_TASK;
spin_unlock_irqrestore(&ap->host_set->lock, flags);
DPRINTK("EXIT\n");
@@ -904,7 +1025,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
* @dev: target device
* @p_class: pointer to class of the target device (may be changed)
* @post_reset: is this read ID post-reset?
- * @id: buffer to fill IDENTIFY page into
+ * @p_id: read IDENTIFY page (newly allocated)
*
* Read ID data from the specified device. ATA_CMD_ID_ATA is
* performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI
@@ -919,12 +1040,13 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
* 0 on success, -errno otherwise.
*/
static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
- unsigned int *p_class, int post_reset, u16 *id)
+ unsigned int *p_class, int post_reset, u16 **p_id)
{
unsigned int class = *p_class;
unsigned int using_edd;
struct ata_taskfile tf;
unsigned int err_mask = 0;
+ u16 *id;
const char *reason;
int rc;
@@ -938,6 +1060,13 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
+ id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL);
+ if (id == NULL) {
+ rc = -ENOMEM;
+ reason = "out of memory";
+ goto err_out;
+ }
+
retry:
ata_tf_init(ap, &tf, dev->devno);
@@ -1028,53 +1157,59 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
}
*p_class = class;
+ *p_id = id;
return 0;
err_out:
printk(KERN_WARNING "ata%u: dev %u failed to IDENTIFY (%s)\n",
ap->id, dev->devno, reason);
+ kfree(id);
return rc;
}
+static inline u8 ata_dev_knobble(const struct ata_port *ap,
+ struct ata_device *dev)
+{
+ return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
+}
+
/**
- * ata_dev_identify - obtain IDENTIFY x DEVICE page
- * @ap: port on which device we wish to probe resides
- * @device: device bus address, starting at zero
- *
- * Following bus reset, we issue the IDENTIFY [PACKET] DEVICE
- * command, and read back the 512-byte device information page.
- * The device information page is fed to us via the standard
- * PIO-IN protocol, but we hand-code it here. (TODO: investigate
- * using standard PIO-IN paths)
- *
- * After reading the device information page, we use several
- * bits of information from it to initialize data structures
- * that will be used during the lifetime of the ata_device.
- * Other data from the info page is used to disqualify certain
- * older ATA devices we do not wish to support.
+ * ata_dev_configure - Configure the specified ATA/ATAPI device
+ * @ap: Port on which target device resides
+ * @dev: Target device to configure
+ * @print_info: Enable device info printout
+ *
+ * Configure @dev according to @dev->id. Generic and low-level
+ * driver specific fixups are also applied.
*
* LOCKING:
- * Inherited from caller. Some functions called by this function
- * obtain the host_set lock.
+ * Kernel thread context (may sleep)
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise
*/
-
-static void ata_dev_identify(struct ata_port *ap, unsigned int device)
+static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
+ int print_info)
{
- struct ata_device *dev = &ap->device[device];
- unsigned long xfer_modes;
+ unsigned int xfer_mask;
int i, rc;
if (!ata_dev_present(dev)) {
DPRINTK("ENTER/EXIT (host %u, dev %u) -- nodev\n",
- ap->id, device);
- return;
+ ap->id, dev->devno);
+ return 0;
}
- DPRINTK("ENTER, host %u, dev %u\n", ap->id, device);
+ DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno);
- rc = ata_dev_read_id(ap, dev, &dev->class, 1, dev->id);
- if (rc)
- goto err_out;
+ /* initialize to-be-configured parameters */
+ dev->flags = 0;
+ dev->max_sectors = 0;
+ dev->cdb_len = 0;
+ dev->n_sectors = 0;
+ dev->cylinders = 0;
+ dev->heads = 0;
+ dev->sectors = 0;
/*
* common ATA, ATAPI feature tests
@@ -1083,15 +1218,12 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
/* we require DMA support (bits 8 of word 49) */
if (!ata_id_has_dma(dev->id)) {
printk(KERN_DEBUG "ata%u: no dma\n", ap->id);
+ rc = -EINVAL;
goto err_out_nosup;
}
- /* quick-n-dirty find max transfer mode; for printk only */
- xfer_modes = dev->id[ATA_ID_UDMA_MODES];
- if (!xfer_modes)
- xfer_modes = (dev->id[ATA_ID_MWDMA_MODES]) << ATA_SHIFT_MWDMA;
- if (!xfer_modes)
- xfer_modes = ata_pio_modes(dev);
+ /* find max transfer mode; for printk only */
+ xfer_mask = ata_id_xfermask(dev->id);
ata_dump_id(dev->id);
@@ -1100,19 +1232,25 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
dev->n_sectors = ata_id_n_sectors(dev->id);
if (ata_id_has_lba(dev->id)) {
- dev->flags |= ATA_DFLAG_LBA;
+ const char *lba_desc;
- if (ata_id_has_lba48(dev->id))
+ lba_desc = "LBA";
+ dev->flags |= ATA_DFLAG_LBA;
+ if (ata_id_has_lba48(dev->id)) {
dev->flags |= ATA_DFLAG_LBA48;
+ lba_desc = "LBA48";
+ }
/* print device info to dmesg */
- printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n",
- ap->id, device,
- ata_id_major_version(dev->id),
- ata_mode_string(xfer_modes),
- (unsigned long long)dev->n_sectors,
- dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA");
- } else {
+ if (print_info)
+ printk(KERN_INFO "ata%u: dev %u ATA-%d, "
+ "max %s, %Lu sectors: %s\n",
+ ap->id, dev->devno,
+ ata_id_major_version(dev->id),
+ ata_mode_string(xfer_mask),
+ (unsigned long long)dev->n_sectors,
+ lba_desc);
+ } else {
/* CHS */
/* Default translation */
@@ -1128,13 +1266,14 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
}
/* print device info to dmesg */
- printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n",
- ap->id, device,
- ata_id_major_version(dev->id),
- ata_mode_string(xfer_modes),
- (unsigned long long)dev->n_sectors,
- (int)dev->cylinders, (int)dev->heads, (int)dev->sectors);
-
+ if (print_info)
+ printk(KERN_INFO "ata%u: dev %u ATA-%d, "
+ "max %s, %Lu sectors: CHS %u/%u/%u\n",
+ ap->id, dev->devno,
+ ata_id_major_version(dev->id),
+ ata_mode_string(xfer_mask),
+ (unsigned long long)dev->n_sectors,
+ dev->cylinders, dev->heads, dev->sectors);
}
if (dev->id[59] & 0x100) {
@@ -1150,6 +1289,7 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
rc = atapi_cdb_len(dev->id);
if ((rc < 12) || (rc > ATAPI_CDB_LEN)) {
printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id);
+ rc = -EINVAL;
goto err_out_nosup;
}
dev->cdb_len = (unsigned int) rc;
@@ -1158,9 +1298,9 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
dev->flags |= ATA_DFLAG_CDB_INTR;
/* print device info to dmesg */
- printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n",
- ap->id, device,
- ata_mode_string(xfer_modes));
+ if (print_info)
+ printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n",
+ ap->id, dev->devno, ata_mode_string(xfer_mask));
}
ap->host->max_cmd_len = 0;
@@ -1169,44 +1309,26 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
ap->host->max_cmd_len,
ap->device[i].cdb_len);
- DPRINTK("EXIT, drv_stat = 0x%x\n", ata_chk_status(ap));
- return;
-
-err_out_nosup:
- printk(KERN_WARNING "ata%u: dev %u not supported, ignoring\n",
- ap->id, device);
-err_out:
- dev->class++; /* converts ATA_DEV_xxx into ATA_DEV_xxx_UNSUP */
- DPRINTK("EXIT, err\n");
-}
-
-
-static inline u8 ata_dev_knobble(const struct ata_port *ap,
- struct ata_device *dev)
-{
- return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
-}
-
-/**
- * ata_dev_config - Run device specific handlers & check for SATA->PATA bridges
- * @ap: Bus
- * @i: Device
- *
- * LOCKING:
- */
-
-void ata_dev_config(struct ata_port *ap, unsigned int i)
-{
/* limit bridge transfers to udma5, 200 sectors */
- if (ata_dev_knobble(ap, &ap->device[i])) {
- printk(KERN_INFO "ata%u(%u): applying bridge limits\n",
- ap->id, i);
+ if (ata_dev_knobble(ap, dev)) {
+ if (print_info)
+ printk(KERN_INFO "ata%u(%u): applying bridge limits\n",
+ ap->id, dev->devno);
ap->udma_mask &= ATA_UDMA5;
- ap->device[i].max_sectors = ATA_MAX_SECTORS;
+ dev->max_sectors = ATA_MAX_SECTORS;
}
if (ap->ops->dev_config)
- ap->ops->dev_config(ap, &ap->device[i]);
+ ap->ops->dev_config(ap, dev);
+
+ DPRINTK("EXIT, drv_stat = 0x%x\n", ata_chk_status(ap));
+ return 0;
+
+err_out_nosup:
+ printk(KERN_WARNING "ata%u: dev %u not supported, ignoring\n",
+ ap->id, dev->devno);
+ DPRINTK("EXIT, err\n");
+ return rc;
}
/**
@@ -1226,41 +1348,61 @@ void ata_dev_config(struct ata_port *ap, unsigned int i)
static int ata_bus_probe(struct ata_port *ap)
{
- unsigned int i, found = 0;
+ unsigned int classes[ATA_MAX_DEVICES];
+ unsigned int i, rc, found = 0;
- if (ap->ops->probe_reset) {
- unsigned int classes[ATA_MAX_DEVICES];
- int rc;
+ ata_port_probe(ap);
- ata_port_probe(ap);
+ /* reset */
+ if (ap->ops->probe_reset) {
+ for (i = 0; i < ATA_MAX_DEVICES; i++)
+ classes[i] = ATA_DEV_UNKNOWN;
rc = ap->ops->probe_reset(ap, classes);
- if (rc == 0) {
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
- if (classes[i] == ATA_DEV_UNKNOWN)
- classes[i] = ATA_DEV_NONE;
- ap->device[i].class = classes[i];
- }
- } else {
- printk(KERN_ERR "ata%u: probe reset failed, "
- "disabling port\n", ap->id);
- ata_port_disable(ap);
+ if (rc) {
+ printk("ata%u: reset failed (errno=%d)\n", ap->id, rc);
+ return rc;
}
- } else
+
+ for (i = 0; i < ATA_MAX_DEVICES; i++)
+ if (classes[i] == ATA_DEV_UNKNOWN)
+ classes[i] = ATA_DEV_NONE;
+ } else {
ap->ops->phy_reset(ap);
- if (ap->flags & ATA_FLAG_PORT_DISABLED)
- goto err_out;
+ for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ if (!(ap->flags & ATA_FLAG_PORT_DISABLED))
+ classes[i] = ap->device[i].class;
+ else
+ ap->device[i].class = ATA_DEV_UNKNOWN;
+ }
+ ata_port_probe(ap);
+ }
+ /* read IDENTIFY page and configure devices */
for (i = 0; i < ATA_MAX_DEVICES; i++) {
- ata_dev_identify(ap, i);
- if (ata_dev_present(&ap->device[i])) {
- found = 1;
- ata_dev_config(ap,i);
+ struct ata_device *dev = &ap->device[i];
+
+ dev->class = classes[i];
+
+ if (!ata_dev_present(dev))
+ continue;
+
+ WARN_ON(dev->id != NULL);
+ if (ata_dev_read_id(ap, dev, &dev->class, 1, &dev->id)) {
+ dev->class = ATA_DEV_NONE;
+ continue;
+ }
+
+ if (ata_dev_configure(ap, dev, 1)) {
+ dev->class++; /* disable device */
+ continue;
}
+
+ found = 1;
}
- if ((!found) || (ap->flags & ATA_FLAG_PORT_DISABLED))
+ if (!found)
goto err_out_disable;
ata_set_mode(ap);
@@ -1271,7 +1413,6 @@ static int ata_bus_probe(struct ata_port *ap)
err_out_disable:
ap->ops->port_disable(ap);
-err_out:
return -1;
}
@@ -1567,31 +1708,8 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
return 0;
}
-static const struct {
- unsigned int shift;
- u8 base;
-} xfer_mode_classes[] = {
- { ATA_SHIFT_UDMA, XFER_UDMA_0 },
- { ATA_SHIFT_MWDMA, XFER_MW_DMA_0 },
- { ATA_SHIFT_PIO, XFER_PIO_0 },
-};
-
-static u8 base_from_shift(unsigned int shift)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++)
- if (xfer_mode_classes[i].shift == shift)
- return xfer_mode_classes[i].base;
-
- return 0xff;
-}
-
static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
{
- int ofs, idx;
- u8 base;
-
if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED))
return;
@@ -1600,65 +1718,58 @@ static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
ata_dev_set_xfermode(ap, dev);
- base = base_from_shift(dev->xfer_shift);
- ofs = dev->xfer_mode - base;
- idx = ofs + dev->xfer_shift;
- WARN_ON(idx >= ARRAY_SIZE(xfer_mode_str));
+ if (ata_dev_revalidate(ap, dev, 0)) {
+ printk(KERN_ERR "ata%u: failed to revalidate after set "
+ "xfermode, disabled\n", ap->id);
+ ata_port_disable(ap);
+ }
- DPRINTK("idx=%d xfer_shift=%u, xfer_mode=0x%x, base=0x%x, offset=%d\n",
- idx, dev->xfer_shift, (int)dev->xfer_mode, (int)base, ofs);
+ DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n",
+ dev->xfer_shift, (int)dev->xfer_mode);
printk(KERN_INFO "ata%u: dev %u configured for %s\n",
- ap->id, dev->devno, xfer_mode_str[idx]);
+ ap->id, dev->devno,
+ ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode)));
}
static int ata_host_set_pio(struct ata_port *ap)
{
- unsigned int mask;
- int x, i;
- u8 base, xfer_mode;
-
- mask = ata_get_mode_mask(ap, ATA_SHIFT_PIO);
- x = fgb(mask);
- if (x < 0) {
- printk(KERN_WARNING "ata%u: no PIO support\n", ap->id);
- return -1;
- }
-
- base = base_from_shift(ATA_SHIFT_PIO);
- xfer_mode = base + x;
-
- DPRINTK("base 0x%x xfer_mode 0x%x mask 0x%x x %d\n",
- (int)base, (int)xfer_mode, mask, x);
+ int i;
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
- if (ata_dev_present(dev)) {
- dev->pio_mode = xfer_mode;
- dev->xfer_mode = xfer_mode;
- dev->xfer_shift = ATA_SHIFT_PIO;
- if (ap->ops->set_piomode)
- ap->ops->set_piomode(ap, dev);
+
+ if (!ata_dev_present(dev))
+ continue;
+
+ if (!dev->pio_mode) {
+ printk(KERN_WARNING "ata%u: no PIO support\n", ap->id);
+ return -1;
}
+
+ dev->xfer_mode = dev->pio_mode;
+ dev->xfer_shift = ATA_SHIFT_PIO;
+ if (ap->ops->set_piomode)
+ ap->ops->set_piomode(ap, dev);
}
return 0;
}
-static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
- unsigned int xfer_shift)
+static void ata_host_set_dma(struct ata_port *ap)
{
int i;
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
- if (ata_dev_present(dev)) {
- dev->dma_mode = xfer_mode;
- dev->xfer_mode = xfer_mode;
- dev->xfer_shift = xfer_shift;
- if (ap->ops->set_dmamode)
- ap->ops->set_dmamode(ap, dev);
- }
+
+ if (!ata_dev_present(dev) || !dev->dma_mode)
+ continue;
+
+ dev->xfer_mode = dev->dma_mode;
+ dev->xfer_shift = ata_xfer_mode2shift(dev->dma_mode);
+ if (ap->ops->set_dmamode)
+ ap->ops->set_dmamode(ap, dev);
}
}
@@ -1673,28 +1784,34 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
*/
static void ata_set_mode(struct ata_port *ap)
{
- unsigned int xfer_shift;
- u8 xfer_mode;
- int rc;
+ int i, rc;
- /* step 1: always set host PIO timings */
- rc = ata_host_set_pio(ap);
- if (rc)
- goto err_out;
+ /* step 1: calculate xfer_mask */
+ for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ struct ata_device *dev = &ap->device[i];
+ unsigned int xfer_mask;
+
+ if (!ata_dev_present(dev))
+ continue;
+
+ xfer_mask = ata_dev_xfermask(ap, dev);
- /* step 2: choose the best data xfer mode */
- xfer_mode = xfer_shift = 0;
- rc = ata_choose_xfer_mode(ap, &xfer_mode, &xfer_shift);
+ dev->pio_mode = ata_xfer_mask2mode(xfer_mask & ATA_MASK_PIO);
+ dev->dma_mode = ata_xfer_mask2mode(xfer_mask & (ATA_MASK_MWDMA |
+ ATA_MASK_UDMA));
+ }
+
+ /* step 2: always set host PIO timings */
+ rc = ata_host_set_pio(ap);
if (rc)
goto err_out;
- /* step 3: if that xfer mode isn't PIO, set host DMA timings */
- if (xfer_shift != ATA_SHIFT_PIO)
- ata_host_set_dma(ap, xfer_mode, xfer_shift);
+ /* step 3: set host DMA timings */
+ ata_host_set_dma(ap);
/* step 4: update devices' xfer mode */
- ata_dev_set_mode(ap, &ap->device[0]);
- ata_dev_set_mode(ap, &ap->device[1]);
+ for (i = 0; i < ATA_MAX_DEVICES; i++)
+ ata_dev_set_mode(ap, &ap->device[i]);
if (ap->flags & ATA_FLAG_PORT_DISABLED)
return;
@@ -2325,11 +2442,118 @@ int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit,
return rc;
}
-static void ata_pr_blacklisted(const struct ata_port *ap,
- const struct ata_device *dev)
+/**
+ * ata_dev_same_device - Determine whether new ID matches configured device
+ * @ap: port on which the device to compare against resides
+ * @dev: device to compare against
+ * @new_class: class of the new device
+ * @new_id: IDENTIFY page of the new device
+ *
+ * Compare @new_class and @new_id against @dev and determine
+ * whether @dev is the device indicated by @new_class and
+ * @new_id.
+ *
+ * LOCKING:
+ * None.
+ *
+ * RETURNS:
+ * 1 if @dev matches @new_class and @new_id, 0 otherwise.
+ */
+static int ata_dev_same_device(struct ata_port *ap, struct ata_device *dev,
+ unsigned int new_class, const u16 *new_id)
+{
+ const u16 *old_id = dev->id;
+ unsigned char model[2][41], serial[2][21];
+ u64 new_n_sectors;
+
+ if (dev->class != new_class) {
+ printk(KERN_INFO
+ "ata%u: dev %u class mismatch %d != %d\n",
+ ap->id, dev->devno, dev->class, new_class);
+ return 0;
+ }
+
+ ata_id_c_string(old_id, model[0], ATA_ID_PROD_OFS, sizeof(model[0]));
+ ata_id_c_string(new_id, model[1], ATA_ID_PROD_OFS, sizeof(model[1]));
+ ata_id_c_string(old_id, serial[0], ATA_ID_SERNO_OFS, sizeof(serial[0]));
+ ata_id_c_string(new_id, serial[1], ATA_ID_SERNO_OFS, sizeof(serial[1]));
+ new_n_sectors = ata_id_n_sectors(new_id);
+
+ if (strcmp(model[0], model[1])) {
+ printk(KERN_INFO
+ "ata%u: dev %u model number mismatch '%s' != '%s'\n",
+ ap->id, dev->devno, model[0], model[1]);
+ return 0;
+ }
+
+ if (strcmp(serial[0], serial[1])) {
+ printk(KERN_INFO
+ "ata%u: dev %u serial number mismatch '%s' != '%s'\n",
+ ap->id, dev->devno, serial[0], serial[1]);
+ return 0;
+ }
+
+ if (dev->class == ATA_DEV_ATA && dev->n_sectors != new_n_sectors) {
+ printk(KERN_INFO
+ "ata%u: dev %u n_sectors mismatch %llu != %llu\n",
+ ap->id, dev->devno, (unsigned long long)dev->n_sectors,
+ (unsigned long long)new_n_sectors);
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
+ * ata_dev_revalidate - Revalidate ATA device
+ * @ap: port on which the device to revalidate resides
+ * @dev: device to revalidate
+ * @post_reset: is this revalidation after reset?
+ *
+ * Re-read IDENTIFY page and make sure @dev is still attached to
+ * the port.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ *
+ * RETURNS:
+ * 0 on success, negative errno otherwise
+ */
+int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev,
+ int post_reset)
{
- printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, disabling DMA\n",
- ap->id, dev->devno);
+ unsigned int class;
+ u16 *id;
+ int rc;
+
+ if (!ata_dev_present(dev))
+ return -ENODEV;
+
+ class = dev->class;
+ id = NULL;
+
+ /* allocate & read ID data */
+ rc = ata_dev_read_id(ap, dev, &class, post_reset, &id);
+ if (rc)
+ goto fail;
+
+ /* is the device still there? */
+ if (!ata_dev_same_device(ap, dev, class, id)) {
+ rc = -ENODEV;
+ goto fail;
+ }
+
+ kfree(dev->id);
+ dev->id = id;
+
+ /* configure device according to the new ID */
+ return ata_dev_configure(ap, dev, 0);
+
+ fail:
+ printk(KERN_ERR "ata%u: dev %u revalidation failed (errno=%d)\n",
+ ap->id, dev->devno, rc);
+ kfree(id);
+ return rc;
}
static const char * const ata_dma_blacklist [] = {
@@ -2378,128 +2602,45 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
return 0;
}
-static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift)
-{
- const struct ata_device *master, *slave;
- unsigned int mask;
-
- master = &ap->device[0];
- slave = &ap->device[1];
-
- WARN_ON(!ata_dev_present(master) && !ata_dev_present(slave));
-
- if (shift == ATA_SHIFT_UDMA) {
- mask = ap->udma_mask;
- if (ata_dev_present(master)) {
- mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff);
- if (ata_dma_blacklisted(master)) {
- mask = 0;
- ata_pr_blacklisted(ap, master);
- }
- }
- if (ata_dev_present(slave)) {
- mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff);
- if (ata_dma_blacklisted(slave)) {
- mask = 0;
- ata_pr_blacklisted(ap, slave);
- }
- }
- }
- else if (shift == ATA_SHIFT_MWDMA) {
- mask = ap->mwdma_mask;
- if (ata_dev_present(master)) {
- mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07);
- if (ata_dma_blacklisted(master)) {
- mask = 0;
- ata_pr_blacklisted(ap, master);
- }
- }
- if (ata_dev_present(slave)) {
- mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07);
- if (ata_dma_blacklisted(slave)) {
- mask = 0;
- ata_pr_blacklisted(ap, slave);
- }
- }
- }
- else if (shift == ATA_SHIFT_PIO) {
- mask = ap->pio_mask;
- if (ata_dev_present(master)) {
- /* spec doesn't return explicit support for
- * PIO0-2, so we fake it
- */
- u16 tmp_mode = master->id[ATA_ID_PIO_MODES] & 0x03;
- tmp_mode <<= 3;
- tmp_mode |= 0x7;
- mask &= tmp_mode;
- }
- if (ata_dev_present(slave)) {
- /* spec doesn't return explicit support for
- * PIO0-2, so we fake it
- */
- u16 tmp_mode = slave->id[ATA_ID_PIO_MODES] & 0x03;
- tmp_mode <<= 3;
- tmp_mode |= 0x7;
- mask &= tmp_mode;
- }
- }
- else {
- mask = 0xffffffff; /* shut up compiler warning */
- BUG();
- }
-
- return mask;
-}
-
-/* find greatest bit */
-static int fgb(u32 bitmap)
-{
- unsigned int i;
- int x = -1;
-
- for (i = 0; i < 32; i++)
- if (bitmap & (1 << i))
- x = i;
-
- return x;
-}
-
/**
- * ata_choose_xfer_mode - attempt to find best transfer mode
- * @ap: Port for which an xfer mode will be selected
- * @xfer_mode_out: (output) SET FEATURES - XFER MODE code
- * @xfer_shift_out: (output) bit shift that selects this mode
+ * ata_dev_xfermask - Compute supported xfermask of the given device
+ * @ap: Port on which the device to compute xfermask for resides
+ * @dev: Device to compute xfermask for
*
- * Based on host and device capabilities, determine the
- * maximum transfer mode that is amenable to all.
+ * Compute supported xfermask of @dev. This function is
+ * responsible for applying all known limits including host
+ * controller limits, device blacklist, etc...
*
* LOCKING:
- * PCI/etc. bus probe sem.
+ * None.
*
* RETURNS:
- * Zero on success, negative on error.
+ * Computed xfermask.
*/
-
-static int ata_choose_xfer_mode(const struct ata_port *ap,
- u8 *xfer_mode_out,
- unsigned int *xfer_shift_out)
+static unsigned int ata_dev_xfermask(struct ata_port *ap,
+ struct ata_device *dev)
{
- unsigned int mask, shift;
- int x, i;
+ unsigned long xfer_mask;
+ int i;
- for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) {
- shift = xfer_mode_classes[i].shift;
- mask = ata_get_mode_mask(ap, shift);
+ xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask,
+ ap->udma_mask);
- x = fgb(mask);
- if (x >= 0) {
- *xfer_mode_out = xfer_mode_classes[i].base + x;
- *xfer_shift_out = shift;
- return 0;
- }
+ /* use port-wide xfermask for now */
+ for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ struct ata_device *d = &ap->device[i];
+ if (!ata_dev_present(d))
+ continue;
+ xfer_mask &= ata_id_xfermask(d->id);
+ if (ata_dma_blacklisted(d))
+ xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
}
- return -1;
+ if (ata_dma_blacklisted(dev))
+ printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, "
+ "disabling DMA\n", ap->id, dev->devno);
+
+ return xfer_mask;
}
/**
@@ -3667,12 +3808,84 @@ fsm_start:
}
if (timeout)
- ata_queue_delayed_pio_task(ap, timeout);
- else if (has_next)
+ ata_port_queue_task(ap, ata_pio_task, ap, timeout);
+ else if (!qc_completed)
goto fsm_start;
}
/**
+ * atapi_packet_task - Write CDB bytes to hardware
+ * @_data: Port to which ATAPI device is attached.
+ *
+ * When device has indicated its readiness to accept
+ * a CDB, this function is called. Send the CDB.
+ * If DMA is to be performed, exit immediately.
+ * Otherwise, we are in polling mode, so poll
+ * status under operation succeeds or fails.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ */
+
+static void atapi_packet_task(void *_data)
+{
+ struct ata_port *ap = _data;
+ struct ata_queued_cmd *qc;
+ u8 status;
+
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+ WARN_ON(qc == NULL);
+ WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
+
+ /* sleep-wait for BSY to clear */
+ DPRINTK("busy wait\n");
+ if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) {
+ qc->err_mask |= AC_ERR_TIMEOUT;
+ goto err_out;
+ }
+
+ /* make sure DRQ is set */
+ status = ata_chk_status(ap);
+ if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) {
+ qc->err_mask |= AC_ERR_HSM;
+ goto err_out;
+ }
+
+ /* send SCSI cdb */
+ DPRINTK("send cdb\n");
+ WARN_ON(qc->dev->cdb_len < 12);
+
+ if (qc->tf.protocol == ATA_PROT_ATAPI_DMA ||
+ qc->tf.protocol == ATA_PROT_ATAPI_NODATA) {
+ unsigned long flags;
+
+ /* Once we're done issuing command and kicking bmdma,
+ * irq handler takes over. To not lose irq, we need
+ * to clear NOINTR flag before sending cdb, but
+ * interrupt handler shouldn't be invoked before we're
+ * finished. Hence, the following locking.
+ */
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ ap->flags &= ~ATA_FLAG_NOINTR;
+ ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
+ if (qc->tf.protocol == ATA_PROT_ATAPI_DMA)
+ ap->ops->bmdma_start(qc); /* initiate bmdma */
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+ } else {
+ ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
+
+ /* PIO commands are handled by polling */
+ ap->hsm_task_state = HSM_ST;
+ ata_port_queue_task(ap, ata_pio_task, ap, 0);
+ }
+
+ return;
+
+err_out:
+ ata_poll_qc_complete(qc);
+}
+
+/**
* ata_qc_timeout - Handle timeout of queued command
* @qc: Command that timed out
*
@@ -3700,7 +3913,6 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
DPRINTK("ENTER\n");
- ata_flush_pio_tasks(ap);
ap->hsm_task_state = HSM_ST_IDLE;
spin_lock_irqsave(&host_set->lock, flags);
@@ -4010,7 +4222,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
if (qc->tf.flags & ATA_TFLAG_WRITE) {
/* PIO data out protocol */
ap->hsm_task_state = HSM_ST_FIRST;
- ata_queue_pio_task(ap);
+ ata_port_queue_task(ap, ata_pio_task, ap, 0);
/* always send first data block using
* the ata_pio_task() codepath.
@@ -4020,7 +4232,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
ap->hsm_task_state = HSM_ST;
if (qc->tf.flags & ATA_TFLAG_POLLING)
- ata_queue_pio_task(ap);
+ ata_port_queue_task(ap, ata_pio_task, ap, 0);
/* if polling, ata_pio_task() handles the rest.
* otherwise, interrupt handler takes over from here.
@@ -4041,7 +4253,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
/* send cdb by polling if no cdb interrupt */
if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) ||
(qc->tf.flags & ATA_TFLAG_POLLING))
- ata_queue_pio_task(ap);
+ ata_port_queue_task(ap, atapi_packet_task, ap, 0);
break;
case ATA_PROT_ATAPI_DMA:
@@ -4053,7 +4265,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
/* send cdb by polling if no cdb interrupt */
if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
- ata_queue_pio_task(ap);
+ ata_port_queue_task(ap, atapi_packet_task, ap, 0);
break;
default:
@@ -4533,6 +4745,7 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
return IRQ_RETVAL(handled);
}
+
/*
* Execute a 'simple' command, that only consists of the opcode 'cmd' itself,
* without filling any other registers
@@ -4752,7 +4965,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
ap->active_tag = ATA_TAG_POISON;
ap->last_ctl = 0xFF;
- INIT_WORK(&ap->pio_task, ata_pio_task, ap);
+ INIT_WORK(&ap->port_task, NULL, NULL);
INIT_LIST_HEAD(&ap->eh_done_q);
for (i = 0; i < ATA_MAX_DEVICES; i++)
@@ -5007,11 +5220,14 @@ void ata_host_set_remove(struct ata_host_set *host_set)
int ata_scsi_release(struct Scsi_Host *host)
{
struct ata_port *ap = (struct ata_port *) &host->hostdata[0];
+ int i;
DPRINTK("ENTER\n");
ap->ops->port_disable(ap);
ata_host_remove(ap, 0);
+ for (i = 0; i < ATA_MAX_DEVICES; i++)
+ kfree(ap->device[i].id);
DPRINTK("EXIT\n");
return 1;
@@ -5215,9 +5431,11 @@ EXPORT_SYMBOL_GPL(sata_std_hardreset);
EXPORT_SYMBOL_GPL(ata_std_postreset);
EXPORT_SYMBOL_GPL(ata_std_probe_reset);
EXPORT_SYMBOL_GPL(ata_drive_probe_reset);
+EXPORT_SYMBOL_GPL(ata_dev_revalidate);
EXPORT_SYMBOL_GPL(ata_port_disable);
EXPORT_SYMBOL_GPL(ata_ratelimit);
EXPORT_SYMBOL_GPL(ata_busy_sleep);
+EXPORT_SYMBOL_GPL(ata_port_queue_task);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_timed_out);
@@ -5228,7 +5446,6 @@ EXPORT_SYMBOL_GPL(ata_host_intr);
EXPORT_SYMBOL_GPL(ata_dev_classify);
EXPORT_SYMBOL_GPL(ata_id_string);
EXPORT_SYMBOL_GPL(ata_id_c_string);
-EXPORT_SYMBOL_GPL(ata_dev_config);
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index d0bd94abb41..ccedb453697 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -785,6 +785,8 @@ int ata_scsi_error(struct Scsi_Host *host)
WARN_ON(ata_qc_from_tag(ap, ap->active_tag) == NULL);
spin_unlock_irqrestore(&ap->host_set->lock, flags);
+ ata_port_flush_task(ap);
+
ap->ops->eng_timeout(ap);
WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q));
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index d822eba05f3..f4c48c91b63 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -45,6 +45,7 @@ extern int libata_fua;
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
struct ata_device *dev);
extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc);
+extern void ata_port_flush_task(struct ata_port *ap);
extern void ata_qc_free(struct ata_queued_cmd *qc);
extern unsigned int ata_qc_issue(struct ata_queued_cmd *qc);
extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 7fa807d7d9e..e5862ad5e6c 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -256,6 +256,8 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = {
board_20319 },
{ PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_20319 },
+ { PCI_VENDOR_ID_PROMISE, 0x3515, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ board_20319 },
{ PCI_VENDOR_ID_PROMISE, 0x3519, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_20319 },
{ PCI_VENDOR_ID_PROMISE, 0x3d17, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index cdf800e3ec1..4f2a67ed39d 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -49,24 +49,30 @@
#define DRV_VERSION "0.9"
enum {
+ /*
+ * host flags
+ */
SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29),
SIL_FLAG_MOD15WRITE = (1 << 30),
+ SIL_DFL_HOST_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO,
+ /*
+ * Controller IDs
+ */
sil_3112 = 0,
- sil_3112_m15w = 1,
- sil_3512 = 2,
- sil_3114 = 3,
-
- SIL_FIFO_R0 = 0x40,
- SIL_FIFO_W0 = 0x41,
- SIL_FIFO_R1 = 0x44,
- SIL_FIFO_W1 = 0x45,
- SIL_FIFO_R2 = 0x240,
- SIL_FIFO_W2 = 0x241,
- SIL_FIFO_R3 = 0x244,
- SIL_FIFO_W3 = 0x245,
+ sil_3512 = 1,
+ sil_3114 = 2,
+ /*
+ * Register offsets
+ */
SIL_SYSCFG = 0x48,
+
+ /*
+ * Register bits
+ */
+ /* SYSCFG */
SIL_MASK_IDE0_INT = (1 << 22),
SIL_MASK_IDE1_INT = (1 << 23),
SIL_MASK_IDE2_INT = (1 << 24),
@@ -75,9 +81,12 @@ enum {
SIL_MASK_4PORT = SIL_MASK_2PORT |
SIL_MASK_IDE2_INT | SIL_MASK_IDE3_INT,
- SIL_IDE2_BMDMA = 0x200,
-
+ /* BMDMA/BMDMA2 */
SIL_INTR_STEERING = (1 << 1),
+
+ /*
+ * Others
+ */
SIL_QUIRK_MOD15WRITE = (1 << 0),
SIL_QUIRK_UDMA5MAX = (1 << 1),
};
@@ -90,13 +99,13 @@ static void sil_post_set_mode (struct ata_port *ap);
static const struct pci_device_id sil_pci_tbl[] = {
- { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
- { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
+ { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
+ { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
{ 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 },
{ 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 },
- { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
- { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
- { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
+ { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
+ { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
+ { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
{ } /* terminate list */
};
@@ -181,18 +190,7 @@ static const struct ata_port_info sil_port_info[] = {
/* sil_3112 */
{
.sht = &sil_sht,
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x3f, /* udma0-5 */
- .port_ops = &sil_ops,
- },
- /* sil_3112_15w - keep it sync'd w/ sil_3112 */
- {
- .sht = &sil_sht,
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO | SIL_FLAG_MOD15WRITE,
+ .host_flags = SIL_DFL_HOST_FLAGS | SIL_FLAG_MOD15WRITE,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x3f, /* udma0-5 */
@@ -201,9 +199,7 @@ static const struct ata_port_info sil_port_info[] = {
/* sil_3512 */
{
.sht = &sil_sht,
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO |
- SIL_FLAG_RERR_ON_DMA_ACT,
+ .host_flags = SIL_DFL_HOST_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x3f, /* udma0-5 */
@@ -212,9 +208,7 @@ static const struct ata_port_info sil_port_info[] = {
/* sil_3114 */
{
.sht = &sil_sht,
- .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO |
- SIL_FLAG_RERR_ON_DMA_ACT,
+ .host_flags = SIL_DFL_HOST_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x3f, /* udma0-5 */
@@ -228,16 +222,17 @@ static const struct {
unsigned long tf; /* ATA taskfile register block */
unsigned long ctl; /* ATA control/altstatus register block */
unsigned long bmdma; /* DMA register block */
+ unsigned long fifo_cfg; /* FIFO Valid Byte Count and Control */
unsigned long scr; /* SATA control register block */
unsigned long sien; /* SATA Interrupt Enable register */
unsigned long xfer_mode;/* data transfer mode register */
unsigned long sfis_cfg; /* SATA FIS reception config register */
} sil_port[] = {
/* port 0 ... */
- { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4, 0x14c },
- { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4, 0x1cc },
- { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4, 0x34c },
- { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4, 0x3cc },
+ { 0x80, 0x8A, 0x00, 0x40, 0x100, 0x148, 0xb4, 0x14c },
+ { 0xC0, 0xCA, 0x08, 0x44, 0x180, 0x1c8, 0xf4, 0x1cc },
+ { 0x280, 0x28A, 0x200, 0x240, 0x300, 0x348, 0x2b4, 0x34c },
+ { 0x2C0, 0x2CA, 0x208, 0x244, 0x380, 0x3c8, 0x2f4, 0x3cc },
/* ... port 3 */
};
@@ -418,13 +413,12 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
goto err_out_regions;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+ probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
if (probe_ent == NULL) {
rc = -ENOMEM;
goto err_out_regions;
}
- memset(probe_ent, 0, sizeof(*probe_ent));
INIT_LIST_HEAD(&probe_ent->node);
probe_ent->dev = pci_dev_to_dev(pdev);
probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops;
@@ -461,19 +455,12 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (cls) {
cls >>= 3;
cls++; /* cls = (line_size/8)+1 */
- writeb(cls, mmio_base + SIL_FIFO_R0);
- writeb(cls, mmio_base + SIL_FIFO_W0);
- writeb(cls, mmio_base + SIL_FIFO_R1);
- writeb(cls, mmio_base + SIL_FIFO_W1);
- if (ent->driver_data == sil_3114) {
- writeb(cls, mmio_base + SIL_FIFO_R2);
- writeb(cls, mmio_base + SIL_FIFO_W2);
- writeb(cls, mmio_base + SIL_FIFO_R3);
- writeb(cls, mmio_base + SIL_FIFO_W3);
- }
+ for (i = 0; i < probe_ent->n_ports; i++)
+ writew(cls << 8 | cls,
+ mmio_base + sil_port[i].fifo_cfg);
} else
dev_printk(KERN_WARNING, &pdev->dev,
- "cache line size not set. Driver may not function\n");
+ "cache line size not set. Driver may not function\n");
/* Apply R_ERR on DMA activate FIS errata workaround */
if (probe_ent->host_flags & SIL_FLAG_RERR_ON_DMA_ACT) {
@@ -496,10 +483,10 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
irq_mask = SIL_MASK_4PORT;
/* flip the magic "make 4 ports work" bit */
- tmp = readl(mmio_base + SIL_IDE2_BMDMA);
+ tmp = readl(mmio_base + sil_port[2].bmdma);
if ((tmp & SIL_INTR_STEERING) == 0)
writel(tmp | SIL_INTR_STEERING,
- mmio_base + SIL_IDE2_BMDMA);
+ mmio_base + sil_port[2].bmdma);
} else {
irq_mask = SIL_MASK_2PORT;
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 5c5822e33a4..8fb62427be8 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -892,6 +892,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->sht = pinfo->sht;
probe_ent->host_flags = pinfo->host_flags;
probe_ent->pio_mask = pinfo->pio_mask;
+ probe_ent->mwdma_mask = pinfo->mwdma_mask;
probe_ent->udma_mask = pinfo->udma_mask;
probe_ent->port_ops = pinfo->port_ops;
probe_ent->n_ports = SIL24_FLAG2NPORTS(pinfo->host_flags);
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index 5d02ff4db6c..b65462f7648 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -192,7 +192,7 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
SDev = cd->device;
if (!sense) {
- sense = kmalloc(sizeof(*sense), GFP_KERNEL);
+ sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
if (!sense) {
err = -ENOMEM;
goto out;
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index f3763d2ccb8..a37579ce6d7 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -2301,7 +2301,6 @@ static void receive_chars(struct uart_port *the_port)
int read_count, request_count = IOC4_MAX_CHARS;
struct uart_icount *icount;
struct uart_info *info = the_port->info;
- int flip = 0;
unsigned long pflags;
/* Make sure all the pointers are "good" ones */
@@ -2313,7 +2312,7 @@ static void receive_chars(struct uart_port *the_port)
spin_lock_irqsave(&the_port->lock, pflags);
tty = info->tty;
- request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS - 2);
+ request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS);
if (request_count > 0) {
icount = &the_port->icount;
@@ -2326,8 +2325,7 @@ static void receive_chars(struct uart_port *the_port)
spin_unlock_irqrestore(&the_port->lock, pflags);
- if (flip)
- tty_flip_buffer_push(tty);
+ tty_flip_buffer_push(tty);
}
/**
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
index 419dd3cd786..193722d680c 100644
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -420,10 +420,8 @@ static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up,
if (up->port.info == NULL)
goto ack_tx_int;
xmit = &up->port.info->xmit;
- if (uart_circ_empty(xmit)) {
- uart_write_wakeup(&up->port);
+ if (uart_circ_empty(xmit))
goto ack_tx_int;
- }
if (uart_tx_stopped(&up->port))
goto ack_tx_int;
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 95fb4939c67..cc1faa31d12 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -71,6 +71,11 @@ static void uart_change_pm(struct uart_state *state, int pm_state);
void uart_write_wakeup(struct uart_port *port)
{
struct uart_info *info = port->info;
+ /*
+ * This means you called this function _after_ the port was
+ * closed. No cookie for you.
+ */
+ BUG_ON(!info);
tasklet_schedule(&info->tlet);
}
@@ -471,14 +476,26 @@ static void uart_flush_chars(struct tty_struct *tty)
}
static int
-uart_write(struct tty_struct *tty, const unsigned char * buf, int count)
+uart_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
struct uart_state *state = tty->driver_data;
- struct uart_port *port = state->port;
- struct circ_buf *circ = &state->info->xmit;
+ struct uart_port *port;
+ struct circ_buf *circ;
unsigned long flags;
int c, ret = 0;
+ /*
+ * This means you called this function _after_ the port was
+ * closed. No cookie for you.
+ */
+ if (!state || !state->info) {
+ WARN_ON(1);
+ return -EL3HLT;
+ }
+
+ port = state->port;
+ circ = &state->info->xmit;
+
if (!circ->buf)
return 0;
@@ -521,6 +538,15 @@ static void uart_flush_buffer(struct tty_struct *tty)
struct uart_port *port = state->port;
unsigned long flags;
+ /*
+ * This means you called this function _after_ the port was
+ * closed. No cookie for you.
+ */
+ if (!state || !state->info) {
+ WARN_ON(1);
+ return;
+ }
+
DPRINTK("uart_flush_buffer(%d) called\n", tty->index);
spin_lock_irqsave(&port->lock, flags);
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index 43e67d6c29d..60ea4a3f071 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -820,7 +820,7 @@ static int __init sn_sal_module_init(void)
int retval;
if (!ia64_platform_is("sn2"))
- return -ENODEV;
+ return 0;
printk(KERN_INFO "sn_console: Console driver init\n");
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 4dd6865d32b..b5c96e74a90 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -242,8 +242,10 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
down(&port->sem);
- if (port->open_count == 0)
- goto out;
+ if (port->open_count == 0) {
+ up(&port->sem);
+ return;
+ }
--port->open_count;
if (port->open_count == 0) {
@@ -260,10 +262,8 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
module_put(port->serial->type->driver.owner);
}
- kref_put(&port->serial->kref, destroy_serial);
-
-out:
up(&port->sem);
+ kref_put(&port->serial->kref, destroy_serial);
}
static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index df8e5667b34..466042808da 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -253,7 +253,7 @@ static void arcfb_lcd_update_page(struct arcfb_par *par, unsigned int upper,
{
unsigned char *src;
unsigned int xindex, yindex, chipindex, linesize;
- int i, count;
+ int i;
unsigned char val;
unsigned char bitmask, rightshift;
@@ -282,7 +282,6 @@ static void arcfb_lcd_update_page(struct arcfb_par *par, unsigned int upper,
}
ks108_writeb_data(par, chipindex, val);
left++;
- count++;
if (bitmask == 0x80) {
bitmask = 1;
src++;
@@ -460,11 +459,11 @@ static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t cou
inode = file->f_dentry->d_inode;
fbidx = iminor(inode);
info = registered_fb[fbidx];
- par = info->par;
if (!info || !info->screen_base)
return -ENODEV;
+ par = info->par;
xres = info->var.xres;
fbmemlength = (xres * info->var.yres)/8;
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index bfc8a93b2c7..620c9a934e0 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1326,7 +1326,7 @@ static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
unsigned char post_dividers[] = {1,2,4,8,3,6,12};
u32 output_freq;
u32 vclk; /* in .01 MHz */
- int i;
+ int i = 0;
u32 n, d;
vclk = 100000000 / period_in_ps; /* convert units to 10 kHz */
@@ -1340,15 +1340,16 @@ static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
/* now, find an acceptable divider */
for (i = 0; i < sizeof(post_dividers); i++) {
output_freq = post_dividers[i] * vclk;
- if (output_freq >= c.ppll_min && output_freq <= c.ppll_max)
+ if (output_freq >= c.ppll_min && output_freq <= c.ppll_max) {
+ pll->post_divider = post_dividers[i];
break;
+ }
}
/* calculate feedback divider */
n = c.ref_divider * output_freq;
d = c.ref_clk;
- pll->post_divider = post_dividers[i];
pll->feedback_divider = round_div(n, d);
pll->vclk = vclk;
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c
index 7f9838dceab..98c05bc0de4 100644
--- a/drivers/video/aty/radeon_monitor.c
+++ b/drivers/video/aty/radeon_monitor.c
@@ -396,6 +396,10 @@ static int __devinit radeon_parse_monitor_layout(struct radeonfb_info *rinfo,
s1[i] = *s;
i++;
}
+
+ if (i > 4)
+ i = 4;
+
} while (*s++);
if (second)
s2[i] = 0;
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index bd39bbd88d4..151fda8dded 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -172,7 +172,7 @@ struct backlight_device *backlight_device_register(const char *name, void *devda
new_bd = kmalloc(sizeof(struct backlight_device), GFP_KERNEL);
if (unlikely(!new_bd))
- return ERR_PTR(ENOMEM);
+ return ERR_PTR(-ENOMEM);
init_MUTEX(&new_bd->sem);
new_bd->props = bp;
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 9e32485ee7b..86908a60c63 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -171,7 +171,7 @@ struct lcd_device *lcd_device_register(const char *name, void *devdata,
new_ld = kmalloc(sizeof(struct lcd_device), GFP_KERNEL);
if (unlikely(!new_ld))
- return ERR_PTR(ENOMEM);
+ return ERR_PTR(-ENOMEM);
init_MUTEX(&new_ld->sem);
new_ld->props = lp;
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index ad416ae4759..7db42542eb1 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -1510,6 +1510,8 @@ imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
default:
printk(KERN_INFO "imsttfb: Device 0x%x unknown, "
"contact maintainer.\n", pdev->device);
+ release_mem_region(addr, size);
+ framebuffer_release(info);
return -ENODEV;
}
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 6b8bd3cdf9c..995b47c165a 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -1333,33 +1333,35 @@ intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
if (regno > 255)
return 1;
- switch (dinfo->depth) {
- case 8:
- {
- red >>= 8;
- green >>= 8;
- blue >>= 8;
+ if (dinfo->depth == 8) {
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+
+ intelfbhw_setcolreg(dinfo, regno, red, green, blue,
+ transp);
+ }
- intelfbhw_setcolreg(dinfo, regno, red, green, blue,
- transp);
+ if (regno < 16) {
+ switch (dinfo->depth) {
+ case 15:
+ dinfo->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
+ ((green & 0xf800) >> 6) |
+ ((blue & 0xf800) >> 11);
+ break;
+ case 16:
+ dinfo->pseudo_palette[regno] = (red & 0xf800) |
+ ((green & 0xfc00) >> 5) |
+ ((blue & 0xf800) >> 11);
+ break;
+ case 24:
+ dinfo->pseudo_palette[regno] = ((red & 0xff00) << 8) |
+ (green & 0xff00) |
+ ((blue & 0xff00) >> 8);
+ break;
}
- break;
- case 15:
- dinfo->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
- ((green & 0xf800) >> 6) |
- ((blue & 0xf800) >> 11);
- break;
- case 16:
- dinfo->pseudo_palette[regno] = (red & 0xf800) |
- ((green & 0xfc00) >> 5) |
- ((blue & 0xf800) >> 11);
- break;
- case 24:
- dinfo->pseudo_palette[regno] = ((red & 0xff00) << 8) |
- (green & 0xff00) |
- ((blue & 0xff00) >> 8);
- break;
}
+
return 0;
}
diff --git a/drivers/video/kyro/STG4000VTG.c b/drivers/video/kyro/STG4000VTG.c
index 3690b04190a..bd389709d23 100644
--- a/drivers/video/kyro/STG4000VTG.c
+++ b/drivers/video/kyro/STG4000VTG.c
@@ -17,7 +17,7 @@
void DisableVGA(volatile STG4000REG __iomem *pSTGReg)
{
u32 tmp;
- volatile u32 count, i;
+ volatile u32 count = 0, i;
/* Reset the VGA registers */
tmp = STG_READ_REG(SoftwareReset);
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index a2e201dc40f..b961d5601bd 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -486,10 +486,8 @@ static void vgaHWRestore(const struct fb_info *info,
static inline int neo2200_sync(struct fb_info *info)
{
struct neofb_par *par = info->par;
- int waitcycles;
- while (readl(&par->neo2200->bltStat) & 1)
- waitcycles++;
+ while (readl(&par->neo2200->bltStat) & 1);
return 0;
}
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index e5d0f92eeae..feec47bdd47 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -588,6 +588,7 @@ s1d13xxxfb_probe(struct platform_device *pdev)
goto bail;
}
+ platform_set_drvdata(pdev, info);
default_par = info->par;
default_par->regs = ioremap_nocache(pdev->resource[1].start,
pdev->resource[1].end - pdev->resource[1].start +1);
@@ -638,8 +639,6 @@ s1d13xxxfb_probe(struct platform_device *pdev)
goto bail;
}
- platform_set_drvdata(pdev, info);
-
printk(KERN_INFO "fb%d: %s frame buffer device\n",
info->node, info->fix.id);
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index ab727eaa7f4..10e6b3aab9e 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -2021,8 +2021,8 @@ static int __devinit savagefb_probe (struct pci_dev* dev,
#if defined(CONFIG_FB_SAVAGE_I2C)
savagefb_create_i2c_busses(info);
savagefb_probe_i2c_connector(info, &par->edid);
- kfree(par->edid);
fb_edid_to_monspecs(par->edid, &info->monspecs);
+ kfree(par->edid);
fb_videomode_to_modelist(info->monspecs.modedb,
info->monspecs.modedb_len,
&info->modelist);
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 3e7baf4c9fa..5e5328d682d 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -786,28 +786,32 @@ static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
if (regno >= info->cmap.len || regno > 255) return 1;
switch (info->fix.visual) {
- case FB_VISUAL_PSEUDOCOLOR:
- rgbcol =(((u32)red & 0xff00) << 8) |
- (((u32)green & 0xff00) << 0) |
- (((u32)blue & 0xff00) >> 8);
- do_setpalentry(par, regno, rgbcol);
- break;
- /* Truecolor has no hardware color palettes. */
- case FB_VISUAL_TRUECOLOR:
+ case FB_VISUAL_PSEUDOCOLOR:
+ rgbcol =(((u32)red & 0xff00) << 8) |
+ (((u32)green & 0xff00) << 0) |
+ (((u32)blue & 0xff00) >> 8);
+ do_setpalentry(par, regno, rgbcol);
+ break;
+ /* Truecolor has no hardware color palettes. */
+ case FB_VISUAL_TRUECOLOR:
+ if (regno < 16) {
rgbcol = (CNVT_TOHW( red, info->var.red.length) <<
info->var.red.offset) |
- (CNVT_TOHW( green, info->var.green.length) <<
- info->var.green.offset) |
- (CNVT_TOHW( blue, info->var.blue.length) <<
- info->var.blue.offset) |
- (CNVT_TOHW( transp, info->var.transp.length) <<
- info->var.transp.offset);
- par->palette[regno] = rgbcol;
- break;
- default:
- DPRINTK("bad depth %u\n", info->var.bits_per_pixel);
- break;
+ (CNVT_TOHW( green, info->var.green.length) <<
+ info->var.green.offset) |
+ (CNVT_TOHW( blue, info->var.blue.length) <<
+ info->var.blue.offset) |
+ (CNVT_TOHW( transp, info->var.transp.length) <<
+ info->var.transp.offset);
+ par->palette[regno] = rgbcol;
+ }
+
+ break;
+ default:
+ DPRINTK("bad depth %u\n", info->var.bits_per_pixel);
+ break;
}
+
return 0;
}