aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-12-24 09:31:05 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-12-24 09:31:05 -0500
commitaaadff81195056c7c14e0d834b3318c624c0fd78 (patch)
tree34d66d8dcb25fa9ffb568f8acfdb317ddf203b44 /drivers
parentMerge branch 'master' (diff)
parentLinux v2.6.15-rc6 (diff)
downloadlinux-dev-aaadff81195056c7c14e0d834b3318c624c0fd78.tar.xz
linux-dev-aaadff81195056c7c14e0d834b3318c624c0fd78.zip
Merge branch 'master'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/atm/adummy.c2
-rw-r--r--drivers/base/memory.c1
-rw-r--r--drivers/char/drm/radeon_cp.c11
-rw-r--r--drivers/char/drm/radeon_drv.h1
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c6
-rw-r--r--drivers/char/mwave/mwavepub.h2
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c13
-rw-r--r--drivers/char/watchdog/booke_wdt.c15
-rw-r--r--drivers/char/watchdog/wdrtas.c2
-rw-r--r--drivers/firmware/dell_rbu.c6
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c11
-rw-r--r--drivers/ide/Kconfig10
-rw-r--r--drivers/ide/ide-cd.c7
-rw-r--r--drivers/ide/ide-cd.h1
-rw-r--r--drivers/ide/ide-disk.c4
-rw-r--r--drivers/ide/ide-dma.c15
-rw-r--r--drivers/ide/mips/Makefile3
-rw-r--r--drivers/ide/mips/au1xxx-ide.c1498
-rw-r--r--drivers/ide/pci/sgiioc4.c8
-rw-r--r--drivers/ide/pci/via82cxxx.c1
-rw-r--r--drivers/ieee1394/hosts.h1
-rw-r--r--drivers/ieee1394/nodemgr.c67
-rw-r--r--drivers/input/misc/wistron_btns.c2
-rw-r--r--drivers/input/mouse/alps.c2
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c6
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c2
-rw-r--r--drivers/message/i2o/pci.c6
-rw-r--r--drivers/mmc/mmc.c10
-rw-r--r--drivers/mtd/onenand/generic.c4
-rw-r--r--drivers/mtd/onenand/onenand_base.c53
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c4
-rw-r--r--drivers/net/s2io.c10
-rw-r--r--drivers/net/tg3.c66
-rw-r--r--drivers/net/tg3.h7
-rw-r--r--drivers/pci/Makefile7
-rw-r--r--drivers/sbus/char/jsflash.c19
-rw-r--r--drivers/sbus/char/uctrl.c10
-rw-r--r--drivers/sbus/char/vfc.h2
-rw-r--r--drivers/sbus/char/vfc_dev.c6
-rw-r--r--drivers/scsi/dpt_i2o.c25
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.h2
-rw-r--r--drivers/scsi/ibmvscsi/iseries_vscsi.c3
-rw-r--r--drivers/scsi/ibmvscsi/rpa_vscsi.c8
-rw-r--r--drivers/scsi/iscsi_tcp.c2
-rw-r--r--drivers/scsi/megaraid.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h10
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c6
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c15
-rw-r--r--drivers/scsi/scsi_error.c7
-rw-r--r--drivers/scsi/scsi_lib.c33
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c2
-rw-r--r--drivers/scsi/sd.c16
-rw-r--r--drivers/scsi/sr.c20
-rw-r--r--drivers/scsi/st.c19
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.c4
-rw-r--r--drivers/usb/host/uhci-hcd.c2
-rw-r--r--drivers/usb/input/hid-core.c4
-rw-r--r--drivers/usb/input/hid-input.c1
-rw-r--r--drivers/usb/misc/auerswald.c2
-rw-r--r--drivers/video/arcfb.c2
-rw-r--r--drivers/video/cyber2000fb.c4
-rw-r--r--drivers/video/pxafb.c3
62 files changed, 903 insertions, 1190 deletions
diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c
index d15c194be44a..d1387cfe2d30 100644
--- a/drivers/atm/adummy.c
+++ b/drivers/atm/adummy.c
@@ -123,7 +123,7 @@ static int __init adummy_init(void)
}
memset(adummy_dev, 0, sizeof(struct adummy_dev));
- atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, 0);
+ atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL);
if (!atm_dev) {
printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
err = -ENODEV;
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index b7ddd651d664..bc3ca6a656b2 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -28,7 +28,6 @@
static struct sysdev_class memory_sysdev_class = {
set_kset_name(MEMORY_CLASS_NAME),
};
-EXPORT_SYMBOL(memory_sysdev_class);
static char *memory_hotplug_name(struct kset *kset, struct kobject *kobj)
{
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 9f2b4efd0c7a..501e557cbc86 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -1311,7 +1311,9 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
{
- drm_radeon_private_t *dev_priv = dev->dev_private;;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ unsigned int mem_size;
+
DRM_DEBUG("\n");
dev_priv->is_pci = init->is_pci;
@@ -1521,8 +1523,11 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
+ dev_priv->fb_location) >> 10));
dev_priv->gart_size = init->gart_size;
- dev_priv->gart_vm_start = dev_priv->fb_location
- + RADEON_READ(RADEON_CONFIG_APER_SIZE) * 2;
+
+ mem_size = RADEON_READ(RADEON_CONFIG_MEMSIZE);
+ if (mem_size == 0)
+ mem_size = 0x800000;
+ dev_priv->gart_vm_start = dev_priv->fb_location + mem_size;
#if __OS_HAS_AGP
if (!dev_priv->is_pci)
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index 7bda7e33d2bd..d92ccee3e54c 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -379,6 +379,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
# define RADEON_PLL_WR_EN (1 << 7)
#define RADEON_CLOCK_CNTL_INDEX 0x0008
#define RADEON_CONFIG_APER_SIZE 0x0108
+#define RADEON_CONFIG_MEMSIZE 0x00f8
#define RADEON_CRTC_OFFSET 0x0224
#define RADEON_CRTC_OFFSET_CNTL 0x0228
# define RADEON_CRTC_TILE_EN (1 << 15)
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 01a1f6badb53..beea450ee4b2 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -2399,7 +2399,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
new_smi->handlers->cleanup(new_smi->si_sm);
kfree(new_smi->si_sm);
}
- new_smi->io_cleanup(new_smi);
+ if (new_smi->io_cleanup)
+ new_smi->io_cleanup(new_smi);
return rv;
}
@@ -2518,7 +2519,8 @@ static void __exit cleanup_one_si(struct smi_info *to_clean)
kfree(to_clean->si_sm);
- to_clean->io_cleanup(to_clean);
+ if (to_clean->io_cleanup)
+ to_clean->io_cleanup(to_clean);
}
static __exit void cleanup_ipmi_si(void)
diff --git a/drivers/char/mwave/mwavepub.h b/drivers/char/mwave/mwavepub.h
index f1f9da7a65c1..60c961ae23b4 100644
--- a/drivers/char/mwave/mwavepub.h
+++ b/drivers/char/mwave/mwavepub.h
@@ -69,7 +69,7 @@ typedef struct _MW_ABILITIES {
typedef struct _MW_READWRITE {
unsigned short usDspAddress; /* The dsp address */
unsigned long ulDataLength; /* The size in bytes of the data or user buffer */
- void *pBuf; /* Input:variable sized buffer */
+ void __user *pBuf; /* Input:variable sized buffer */
} MW_READWRITE, *pMW_READWRITE;
#define IOCTL_MW_RESET _IO(MWAVE_MINOR,1)
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index ef011ef5dc46..61681c9f3f72 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1444,6 +1444,7 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
dev_link_t *link;
int size;
int rc;
+ void __user *argp = (void __user *)arg;
#ifdef PCMCIA_DEBUG
char *ioctl_names[CM_IOC_MAXNR + 1] = {
[_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS",
@@ -1481,11 +1482,11 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
_IOC_DIR(cmd), _IOC_READ, _IOC_WRITE, size, cmd);
if (_IOC_DIR(cmd) & _IOC_READ) {
- if (!access_ok(VERIFY_WRITE, (void *)arg, size))
+ if (!access_ok(VERIFY_WRITE, argp, size))
return -EFAULT;
}
if (_IOC_DIR(cmd) & _IOC_WRITE) {
- if (!access_ok(VERIFY_READ, (void *)arg, size))
+ if (!access_ok(VERIFY_READ, argp, size))
return -EFAULT;
}
@@ -1506,14 +1507,14 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
status |= CM_NO_READER;
if (test_bit(IS_BAD_CARD, &dev->flags))
status |= CM_BAD_CARD;
- if (copy_to_user((int *)arg, &status, sizeof(int)))
+ if (copy_to_user(argp, &status, sizeof(int)))
return -EFAULT;
}
return 0;
case CM_IOCGATR:
DEBUGP(4, dev, "... in CM_IOCGATR\n");
{
- struct atreq *atreq = (struct atreq *) arg;
+ struct atreq __user *atreq = argp;
int tmp;
/* allow nonblocking io and being interrupted */
if (wait_event_interruptible
@@ -1597,7 +1598,7 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
{
struct ptsreq krnptsreq;
- if (copy_from_user(&krnptsreq, (struct ptsreq *) arg,
+ if (copy_from_user(&krnptsreq, argp,
sizeof(struct ptsreq)))
return -EFAULT;
@@ -1641,7 +1642,7 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
int old_pc_debug = 0;
old_pc_debug = pc_debug;
- if (copy_from_user(&pc_debug, (int *)arg, sizeof(int)))
+ if (copy_from_user(&pc_debug, argp, sizeof(int)))
return -EFAULT;
if (old_pc_debug != pc_debug)
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c
index 65830ec71042..b6640606b44d 100644
--- a/drivers/char/watchdog/booke_wdt.c
+++ b/drivers/char/watchdog/booke_wdt.c
@@ -72,7 +72,7 @@ static __inline__ void booke_wdt_ping(void)
/*
* booke_wdt_write:
*/
-static ssize_t booke_wdt_write (struct file *file, const char *buf,
+static ssize_t booke_wdt_write (struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
booke_wdt_ping();
@@ -92,14 +92,15 @@ static int booke_wdt_ioctl (struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
u32 tmp = 0;
+ u32 __user *p = (u32 __user *)arg;
switch (cmd) {
case WDIOC_GETSUPPORT:
- if (copy_to_user ((struct watchdog_info *) arg, &ident,
+ if (copy_to_user ((struct watchdog_info __user *) arg, &ident,
sizeof(struct watchdog_info)))
return -EFAULT;
case WDIOC_GETSTATUS:
- return put_user(ident.options, (u32 *) arg);
+ return put_user(ident.options, p);
case WDIOC_GETBOOTSTATUS:
/* XXX: something is clearing TSR */
tmp = mfspr(SPRN_TSR) & TSR_WRS(3);
@@ -109,14 +110,14 @@ static int booke_wdt_ioctl (struct inode *inode, struct file *file,
booke_wdt_ping();
return 0;
case WDIOC_SETTIMEOUT:
- if (get_user(booke_wdt_period, (u32 *) arg))
+ if (get_user(booke_wdt_period, p))
return -EFAULT;
mtspr(SPRN_TCR, (mfspr(SPRN_TCR)&~WDTP(0))|WDTP(booke_wdt_period));
return 0;
case WDIOC_GETTIMEOUT:
- return put_user(booke_wdt_period, (u32 *) arg);
+ return put_user(booke_wdt_period, p);
case WDIOC_SETOPTIONS:
- if (get_user(tmp, (u32 *) arg))
+ if (get_user(tmp, p))
return -EINVAL;
if (tmp == WDIOS_ENABLECARD) {
booke_wdt_ping();
@@ -172,7 +173,7 @@ static int __init booke_wdt_init(void)
int ret = 0;
printk (KERN_INFO "PowerPC Book-E Watchdog Timer Loaded\n");
- ident.firmware_version = cpu_specs[0].pvr_value;
+ ident.firmware_version = cur_cpu_spec->pvr_value;
ret = misc_register(&booke_wdt_miscdev);
if (ret) {
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/char/watchdog/wdrtas.c
index 619e2ffca33f..dacfe31caccf 100644
--- a/drivers/char/watchdog/wdrtas.c
+++ b/drivers/char/watchdog/wdrtas.c
@@ -320,7 +320,7 @@ static int
wdrtas_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- int __user *argp = (void *)arg;
+ int __user *argp = (void __user *)arg;
int i;
static struct watchdog_info wdinfo = {
.options = WDRTAS_SUPPORTED_MASK,
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index 6d83299e7c9b..dfedb777d8c9 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -105,8 +105,8 @@ static int create_packet(void *data, size_t length)
int ordernum = 0;
int retval = 0;
unsigned int packet_array_size = 0;
- void **invalid_addr_packet_array = 0;
- void *packet_data_temp_buf = 0;
+ void **invalid_addr_packet_array = NULL;
+ void *packet_data_temp_buf = NULL;
unsigned int idx = 0;
pr_debug("create_packet: entry \n");
@@ -178,7 +178,7 @@ static int create_packet(void *data, size_t length)
packet_data_temp_buf),
allocation_floor);
invalid_addr_packet_array[idx++] = packet_data_temp_buf;
- packet_data_temp_buf = 0;
+ packet_data_temp_buf = NULL;
}
}
spin_lock(&rbu_data.lock);
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index afd7634e5cc9..81031eb51056 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -529,14 +529,15 @@ mv64xxx_i2c_probe(struct platform_device *pd)
i2c_set_adapdata(&drv_data->adapter, drv_data);
if (request_irq(drv_data->irq, mv64xxx_i2c_intr, 0,
- MV64XXX_I2C_CTLR_NAME, drv_data)) {
-
- dev_err(dev, "mv64xxx: Can't register intr handler "
- "irq: %d\n", drv_data->irq);
+ MV64XXX_I2C_CTLR_NAME, drv_data)) {
+ dev_err(&drv_data->adapter.dev,
+ "mv64xxx: Can't register intr handler irq: %d\n",
+ drv_data->irq);
rc = -EINVAL;
goto exit_unmap_regs;
} else if ((rc = i2c_add_adapter(&drv_data->adapter)) != 0) {
- dev_err(dev, "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
+ dev_err(&drv_data->adapter.dev,
+ "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
goto exit_free_irq;
}
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 31e649a9ff71..1c81174595b3 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -807,14 +807,6 @@ config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX
endchoice
-config BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
- bool "Enable burstable Mode on DbDMA"
- default false
- depends BLK_DEV_IDE_AU1XXX
- help
- This option enable the burstable Flag on DbDMA controller
- (cf. "AMD Alchemy 'Au1200' Processor Data Book - PRELIMINARY").
-
config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
int "Maximum transfer size (KB) per request (up to 128)"
default "128"
@@ -940,7 +932,7 @@ config BLK_DEV_Q40IDE
config BLK_DEV_MPC8xx_IDE
bool "MPC8xx IDE support"
- depends on 8xx
+ depends on 8xx && IDE=y && BLK_DEV_IDE=y
help
This option provides support for IDE on Motorola MPC8xx Systems.
Please see 'Type of MPC8xx IDE interface' for details.
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 9455e42abb23..b4d7a3efb90f 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -1292,7 +1292,6 @@ static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block)
struct cdrom_info *info = drive->driver_data;
info->dma = 0;
- info->cmd = 0;
info->start_seek = jiffies;
return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation);
}
@@ -1344,8 +1343,6 @@ static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
(rq->nr_sectors & (sectors_per_frame - 1)))
info->dma = 0;
- info->cmd = READ;
-
/* Start sending the read request to the drive. */
return cdrom_start_packet_command(drive, 32768, cdrom_start_read_continuation);
}
@@ -1484,7 +1481,6 @@ static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive)
struct cdrom_info *info = drive->driver_data;
info->dma = 0;
- info->cmd = 0;
rq->flags &= ~REQ_FAILED;
len = rq->data_len;
@@ -1891,7 +1887,6 @@ static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq)
/* use dma, if possible. we don't need to check more, since we
* know that the transfer is always (at least!) frame aligned */
info->dma = drive->using_dma ? 1 : 0;
- info->cmd = WRITE;
info->devinfo.media_written = 1;
@@ -1916,7 +1911,6 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
rq->flags |= REQ_QUIET;
info->dma = 0;
- info->cmd = 0;
/*
* sg request
@@ -1925,7 +1919,6 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
int mask = drive->queue->dma_alignment;
unsigned long addr = (unsigned long) page_address(bio_page(rq->bio));
- info->cmd = rq_data_dir(rq);
info->dma = drive->using_dma;
/*
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index 7ca3e5afc665..ad1f2ed14a37 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -480,7 +480,6 @@ struct cdrom_info {
struct request request_sense_request;
int dma;
- int cmd;
unsigned long last_block;
unsigned long start_seek;
/* Buffer to hold mechanism status and changer slot table. */
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index f4e3d3527b0e..449522f0540c 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1034,12 +1034,12 @@ static int ide_disk_remove(struct device *dev)
struct ide_disk_obj *idkp = drive->driver_data;
struct gendisk *g = idkp->disk;
- ide_cacheflush_p(drive);
-
ide_unregister_subdriver(drive, idkp->driver);
del_gendisk(g);
+ ide_cacheflush_p(drive);
+
ide_disk_put(idkp);
return 0;
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 1e1531334c25..0523da77425a 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -90,11 +90,6 @@
#include <asm/io.h>
#include <asm/irq.h>
-struct drive_list_entry {
- const char *id_model;
- const char *id_firmware;
-};
-
static const struct drive_list_entry drive_whitelist [] = {
{ "Micropolis 2112A" , "ALL" },
@@ -139,7 +134,7 @@ static const struct drive_list_entry drive_blacklist [] = {
};
/**
- * in_drive_list - look for drive in black/white list
+ * ide_in_drive_list - look for drive in black/white list
* @id: drive identifier
* @drive_table: list to inspect
*
@@ -147,7 +142,7 @@ static const struct drive_list_entry drive_blacklist [] = {
* Returns 1 if the drive is found in the table.
*/
-static int in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
+int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
{
for ( ; drive_table->id_model ; drive_table++)
if ((!strcmp(drive_table->id_model, id->model)) &&
@@ -157,6 +152,8 @@ static int in_drive_list(struct hd_driveid *id, const struct drive_list_entry *d
return 0;
}
+EXPORT_SYMBOL_GPL(ide_in_drive_list);
+
/**
* ide_dma_intr - IDE DMA interrupt handler
* @drive: the drive the interrupt is for
@@ -663,7 +660,7 @@ int __ide_dma_bad_drive (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
- int blacklist = in_drive_list(id, drive_blacklist);
+ int blacklist = ide_in_drive_list(id, drive_blacklist);
if (blacklist) {
printk(KERN_WARNING "%s: Disabling (U)DMA for %s (blacklisted)\n",
drive->name, id->model);
@@ -677,7 +674,7 @@ EXPORT_SYMBOL(__ide_dma_bad_drive);
int __ide_dma_good_drive (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
- return in_drive_list(id, drive_whitelist);
+ return ide_in_drive_list(id, drive_whitelist);
}
EXPORT_SYMBOL(__ide_dma_good_drive);
diff --git a/drivers/ide/mips/Makefile b/drivers/ide/mips/Makefile
index 578e52a59588..677c7b2bac92 100644
--- a/drivers/ide/mips/Makefile
+++ b/drivers/ide/mips/Makefile
@@ -1 +1,4 @@
obj-$(CONFIG_BLK_DEV_IDE_SWARM) += swarm.o
+obj-$(CONFIG_BLK_DEV_IDE_AU1XXX) += au1xxx-ide.o
+
+EXTRA_CFLAGS := -Idrivers/ide
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index 2b6327c576b9..32431dcf5d8e 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -31,865 +31,638 @@
*/
#undef REALLY_SLOW_IO /* most systems can safely undef this */
-#include <linux/config.h> /* for CONFIG_BLK_DEV_IDEPCI */
#include <linux/types.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/hdreg.h>
+#include <linux/platform_device.h>
+
#include <linux/init.h>
#include <linux/ide.h>
#include <linux/sysdev.h>
#include <linux/dma-mapping.h>
+#include "ide-timing.h"
+
#include <asm/io.h>
#include <asm/mach-au1x00/au1xxx.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
-#if CONFIG_PM
-#include <asm/mach-au1x00/au1xxx_pm.h>
-#endif
-
#include <asm/mach-au1x00/au1xxx_ide.h>
#define DRV_NAME "au1200-ide"
#define DRV_VERSION "1.0"
-#define DRV_AUTHOR "AMD PCS / Pete Popov <ppopov@embeddedalley.com>"
-#define DRV_DESC "Au1200 IDE"
-
-static _auide_hwif auide_hwif;
-static spinlock_t ide_tune_drive_spin_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t ide_tune_chipset_spin_lock = SPIN_LOCK_UNLOCKED;
-static int dbdma_init_done = 0;
-
-/*
- * local I/O functions
- */
-u8 auide_inb(unsigned long port)
-{
- return (au_readb(port));
-}
+#define DRV_AUTHOR "Enrico Walther <enrico.walther@amd.com> / Pete Popov <ppopov@embeddedalley.com>"
-u16 auide_inw(unsigned long port)
-{
- return (au_readw(port));
-}
+/* enable the burstmode in the dbdma */
+#define IDE_AU1XXX_BURSTMODE 1
-u32 auide_inl(unsigned long port)
-{
- return (au_readl(port));
-}
+static _auide_hwif auide_hwif;
+static int dbdma_init_done;
-void auide_insw(unsigned long port, void *addr, u32 count)
-{
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
- _auide_hwif *ahwif = &auide_hwif;
- chan_tab_t *ctp;
- au1x_ddma_desc_t *dp;
-
- if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1,
- DDMA_FLAGS_NOIE)) {
- printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
- return;
- }
- ctp = *((chan_tab_t **)ahwif->rx_chan);
- dp = ctp->cur_ptr;
- while (dp->dscr_cmd0 & DSCR_CMD0_V)
- ;
- ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
-#else
- while (count--)
- {
- *(u16 *)addr = au_readw(port);
- addr +=2 ;
- }
-#endif
-}
-
-void auide_insl(unsigned long port, void *addr, u32 count)
-{
- while (count--)
- {
- *(u32 *)addr = au_readl(port);
- /* NOTE: For IDE interfaces over PCMCIA,
- * 32-bit access does not work
- */
- addr += 4;
- }
-}
-
-void auide_outb(u8 addr, unsigned long port)
+void auide_insw(unsigned long port, void *addr, u32 count)
{
- return (au_writeb(addr, port));
-}
+ _auide_hwif *ahwif = &auide_hwif;
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
-void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port)
-{
- return (au_writeb(addr, port));
+ if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1,
+ DDMA_FLAGS_NOIE)) {
+ printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
+ return;
+ }
+ ctp = *((chan_tab_t **)ahwif->rx_chan);
+ dp = ctp->cur_ptr;
+ while (dp->dscr_cmd0 & DSCR_CMD0_V)
+ ;
+ ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
}
-void auide_outw(u16 addr, unsigned long port)
+void auide_outsw(unsigned long port, void *addr, u32 count)
{
- return (au_writew(addr, port));
-}
+ _auide_hwif *ahwif = &auide_hwif;
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
-void auide_outl(u32 addr, unsigned long port)
-{
- return (au_writel(addr, port));
+ if(!put_source_flags(ahwif->tx_chan, (void*)addr,
+ count << 1, DDMA_FLAGS_NOIE)) {
+ printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
+ return;
+ }
+ ctp = *((chan_tab_t **)ahwif->tx_chan);
+ dp = ctp->cur_ptr;
+ while (dp->dscr_cmd0 & DSCR_CMD0_V)
+ ;
+ ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
}
-void auide_outsw(unsigned long port, void *addr, u32 count)
-{
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
- _auide_hwif *ahwif = &auide_hwif;
- chan_tab_t *ctp;
- au1x_ddma_desc_t *dp;
-
- if(!put_source_flags(ahwif->tx_chan, (void*)addr,
- count << 1, DDMA_FLAGS_NOIE)) {
- printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
- return;
- }
- ctp = *((chan_tab_t **)ahwif->tx_chan);
- dp = ctp->cur_ptr;
- while (dp->dscr_cmd0 & DSCR_CMD0_V)
- ;
- ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
-#else
- while (count--)
- {
- au_writew(*(u16 *)addr, port);
- addr += 2;
- }
#endif
-}
-
-void auide_outsl(unsigned long port, void *addr, u32 count)
-{
- while (count--)
- {
- au_writel(*(u32 *)addr, port);
- /* NOTE: For IDE interfaces over PCMCIA,
- * 32-bit access does not work
- */
- addr += 4;
- }
-}
static void auide_tune_drive(ide_drive_t *drive, byte pio)
{
- int mem_sttime;
- int mem_stcfg;
- unsigned long flags;
- u8 speed;
-
- /* get the best pio mode for the drive */
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
-
- printk("%s: setting Au1XXX IDE to PIO mode%d\n",
- drive->name, pio);
-
- spin_lock_irqsave(&ide_tune_drive_spin_lock, flags);
-
- mem_sttime = 0;
- mem_stcfg = au_readl(MEM_STCFG2);
-
- /* set pio mode! */
- switch(pio) {
- case 0:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO0_TWCS
- | SBC_IDE_PIO0_TCSH
- | SBC_IDE_PIO0_TCSOFF
- | SBC_IDE_PIO0_TWP
- | SBC_IDE_PIO0_TCSW
- | SBC_IDE_PIO0_TPM
- | SBC_IDE_PIO0_TA;
- /* set configuration for RCS2# */
- mem_stcfg |= TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS;
-
- au_writel(mem_sttime,MEM_STTIME2);
- au_writel(mem_stcfg,MEM_STCFG2);
- break;
-
- case 1:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO1_TWCS
- | SBC_IDE_PIO1_TCSH
- | SBC_IDE_PIO1_TCSOFF
- | SBC_IDE_PIO1_TWP
- | SBC_IDE_PIO1_TCSW
- | SBC_IDE_PIO1_TPM
- | SBC_IDE_PIO1_TA;
- /* set configuration for RCS2# */
- mem_stcfg |= TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS;
- break;
-
- case 2:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO2_TWCS
- | SBC_IDE_PIO2_TCSH
- | SBC_IDE_PIO2_TCSOFF
- | SBC_IDE_PIO2_TWP
- | SBC_IDE_PIO2_TCSW
- | SBC_IDE_PIO2_TPM
- | SBC_IDE_PIO2_TA;
- /* set configuration for RCS2# */
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS;
- break;
-
- case 3:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO3_TWCS
- | SBC_IDE_PIO3_TCSH
- | SBC_IDE_PIO3_TCSOFF
- | SBC_IDE_PIO3_TWP
- | SBC_IDE_PIO3_TCSW
- | SBC_IDE_PIO3_TPM
- | SBC_IDE_PIO3_TA;
- /* set configuration for RCS2# */
- mem_stcfg |= TS_MASK;
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS;
-
- break;
-
- case 4:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO4_TWCS
- | SBC_IDE_PIO4_TCSH
- | SBC_IDE_PIO4_TCSOFF
- | SBC_IDE_PIO4_TWP
- | SBC_IDE_PIO4_TCSW
- | SBC_IDE_PIO4_TPM
- | SBC_IDE_PIO4_TA;
- /* set configuration for RCS2# */
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS;
- break;
- }
-
- au_writel(mem_sttime,MEM_STTIME2);
- au_writel(mem_stcfg,MEM_STCFG2);
-
- spin_unlock_irqrestore(&ide_tune_drive_spin_lock, flags);
-
- speed = pio + XFER_PIO_0;
- ide_config_drive_speed(drive, speed);
+ int mem_sttime;
+ int mem_stcfg;
+ u8 speed;
+
+ /* get the best pio mode for the drive */
+ pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+
+ printk(KERN_INFO "%s: setting Au1XXX IDE to PIO mode%d\n",
+ drive->name, pio);
+
+ mem_sttime = 0;
+ mem_stcfg = au_readl(MEM_STCFG2);
+
+ /* set pio mode! */
+ switch(pio) {
+ case 0:
+ mem_sttime = SBC_IDE_TIMING(PIO0);
+
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS;
+ break;
+
+ case 1:
+ mem_sttime = SBC_IDE_TIMING(PIO1);
+
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS;
+ break;
+
+ case 2:
+ mem_sttime = SBC_IDE_TIMING(PIO2);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS;
+ break;
+
+ case 3:
+ mem_sttime = SBC_IDE_TIMING(PIO3);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS;
+
+ break;
+
+ case 4:
+ mem_sttime = SBC_IDE_TIMING(PIO4);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS;
+ break;
+ }
+
+ au_writel(mem_sttime,MEM_STTIME2);
+ au_writel(mem_stcfg,MEM_STCFG2);
+
+ speed = pio + XFER_PIO_0;
+ ide_config_drive_speed(drive, speed);
}
static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
{
- u8 mode = 0;
- int mem_sttime;
- int mem_stcfg;
- unsigned long flags;
+ int mem_sttime;
+ int mem_stcfg;
+ unsigned long mode;
+
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
- struct hd_driveid *id = drive->id;
-
- /*
- * Now see what the current drive is capable of,
- * selecting UDMA only if the mate said it was ok.
- */
- if (id && (id->capability & 1) && drive->autodma &&
- !__ide_dma_bad_drive(drive)) {
- if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) {
- if (id->dma_mword & 4)
- mode = XFER_MW_DMA_2;
- else if (id->dma_mword & 2)
- mode = XFER_MW_DMA_1;
- else if (id->dma_mword & 1)
- mode = XFER_MW_DMA_0;
- }
- }
+ if (ide_use_dma(drive))
+ mode = ide_dma_speed(drive, 0);
#endif
- spin_lock_irqsave(&ide_tune_chipset_spin_lock, flags);
+ mem_sttime = 0;
+ mem_stcfg = au_readl(MEM_STCFG2);
- mem_sttime = 0;
- mem_stcfg = au_readl(MEM_STCFG2);
-
- switch(speed) {
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- auide_tune_drive(drive, (speed - XFER_PIO_0));
- break;
+ if (speed >= XFER_PIO_0 && speed <= XFER_PIO_4) {
+ auide_tune_drive(drive, speed - XFER_PIO_0);
+ return 0;
+ }
+
+ switch(speed) {
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
- case XFER_MW_DMA_2:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_MDMA2_TWCS
- | SBC_IDE_MDMA2_TCSH
- | SBC_IDE_MDMA2_TCSOFF
- | SBC_IDE_MDMA2_TWP
- | SBC_IDE_MDMA2_TCSW
- | SBC_IDE_MDMA2_TPM
- | SBC_IDE_MDMA2_TA;
- /* set configuration for RCS2# */
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
-
- mode = XFER_MW_DMA_2;
- break;
- case XFER_MW_DMA_1:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_MDMA1_TWCS
- | SBC_IDE_MDMA1_TCSH
- | SBC_IDE_MDMA1_TCSOFF
- | SBC_IDE_MDMA1_TWP
- | SBC_IDE_MDMA1_TCSW
- | SBC_IDE_MDMA1_TPM
- | SBC_IDE_MDMA1_TA;
- /* set configuration for RCS2# */
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
-
- mode = XFER_MW_DMA_1;
- break;
- case XFER_MW_DMA_0:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_MDMA0_TWCS
- | SBC_IDE_MDMA0_TCSH
- | SBC_IDE_MDMA0_TCSOFF
- | SBC_IDE_MDMA0_TWP
- | SBC_IDE_MDMA0_TCSW
- | SBC_IDE_MDMA0_TPM
- | SBC_IDE_MDMA0_TA;
- /* set configuration for RCS2# */
- mem_stcfg |= TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
-
- mode = XFER_MW_DMA_0;
- break;
+ case XFER_MW_DMA_2:
+ mem_sttime = SBC_IDE_TIMING(MDMA2);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
+
+ mode = XFER_MW_DMA_2;
+ break;
+ case XFER_MW_DMA_1:
+ mem_sttime = SBC_IDE_TIMING(MDMA1);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
+
+ mode = XFER_MW_DMA_1;
+ break;
+ case XFER_MW_DMA_0:
+ mem_sttime = SBC_IDE_TIMING(MDMA0);
+
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
+
+ mode = XFER_MW_DMA_0;
+ break;
#endif
- default:
- return 1;
- }
-
- /*
- * Tell the drive to switch to the new mode; abort on failure.
- */
- if (!mode || ide_config_drive_speed(drive, mode))
- {
- return 1; /* failure */
- }
-
-
- au_writel(mem_sttime,MEM_STTIME2);
- au_writel(mem_stcfg,MEM_STCFG2);
+ default:
+ return 1;
+ }
+
+ if (ide_config_drive_speed(drive, mode))
+ return 1;
- spin_unlock_irqrestore(&ide_tune_chipset_spin_lock, flags);
+ au_writel(mem_sttime,MEM_STTIME2);
+ au_writel(mem_stcfg,MEM_STCFG2);
- return 0;
+ return 0;
}
/*
* Multi-Word DMA + DbDMA functions
*/
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-static int in_drive_list(struct hd_driveid *id,
- const struct drive_list_entry *drive_table)
-{
- for ( ; drive_table->id_model ; drive_table++){
- if ((!strcmp(drive_table->id_model, id->model)) &&
- ((strstr(drive_table->id_firmware, id->fw_rev)) ||
- (!strcmp(drive_table->id_firmware, "ALL")))
- )
- return 1;
- }
- return 0;
-}
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
static int auide_build_sglist(ide_drive_t *drive, struct request *rq)
{
- ide_hwif_t *hwif = drive->hwif;
- _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
- struct scatterlist *sg = hwif->sg_table;
+ ide_hwif_t *hwif = drive->hwif;
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+ struct scatterlist *sg = hwif->sg_table;
- ide_map_sg(drive, rq);
+ ide_map_sg(drive, rq);
- if (rq_data_dir(rq) == READ)
- hwif->sg_dma_direction = DMA_FROM_DEVICE;
- else
- hwif->sg_dma_direction = DMA_TO_DEVICE;
+ if (rq_data_dir(rq) == READ)
+ hwif->sg_dma_direction = DMA_FROM_DEVICE;
+ else
+ hwif->sg_dma_direction = DMA_TO_DEVICE;
- return dma_map_sg(ahwif->dev, sg, hwif->sg_nents,
- hwif->sg_dma_direction);
+ return dma_map_sg(ahwif->dev, sg, hwif->sg_nents,
+ hwif->sg_dma_direction);
}
static int auide_build_dmatable(ide_drive_t *drive)
{
- int i, iswrite, count = 0;
- ide_hwif_t *hwif = HWIF(drive);
-
- struct request *rq = HWGROUP(drive)->rq;
-
- _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
- struct scatterlist *sg;
-
- iswrite = (rq_data_dir(rq) == WRITE);
- /* Save for interrupt context */
- ahwif->drive = drive;
-
- /* Build sglist */
- hwif->sg_nents = i = auide_build_sglist(drive, rq);
-
- if (!i)
- return 0;
-
- /* fill the descriptors */
- sg = hwif->sg_table;
- while (i && sg_dma_len(sg)) {
- u32 cur_addr;
- u32 cur_len;
-
- cur_addr = sg_dma_address(sg);
- cur_len = sg_dma_len(sg);
-
- while (cur_len) {
- u32 flags = DDMA_FLAGS_NOIE;
- unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
-
- if (++count >= PRD_ENTRIES) {
- printk(KERN_WARNING "%s: DMA table too small\n",
- drive->name);
- goto use_pio_instead;
- }
-
- /* Lets enable intr for the last descriptor only */
- if (1==i)
- flags = DDMA_FLAGS_IE;
- else
- flags = DDMA_FLAGS_NOIE;
-
- if (iswrite) {
- if(!put_source_flags(ahwif->tx_chan,
- (void*)(page_address(sg->page)
- + sg->offset),
- tc, flags)) {
- printk(KERN_ERR "%s failed %d\n",
- __FUNCTION__, __LINE__);
+ int i, iswrite, count = 0;
+ ide_hwif_t *hwif = HWIF(drive);
+
+ struct request *rq = HWGROUP(drive)->rq;
+
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+ struct scatterlist *sg;
+
+ iswrite = (rq_data_dir(rq) == WRITE);
+ /* Save for interrupt context */
+ ahwif->drive = drive;
+
+ /* Build sglist */
+ hwif->sg_nents = i = auide_build_sglist(drive, rq);
+
+ if (!i)
+ return 0;
+
+ /* fill the descriptors */
+ sg = hwif->sg_table;
+ while (i && sg_dma_len(sg)) {
+ u32 cur_addr;
+ u32 cur_len;
+
+ cur_addr = sg_dma_address(sg);
+ cur_len = sg_dma_len(sg);
+
+ while (cur_len) {
+ u32 flags = DDMA_FLAGS_NOIE;
+ unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
+
+ if (++count >= PRD_ENTRIES) {
+ printk(KERN_WARNING "%s: DMA table too small\n",
+ drive->name);
+ goto use_pio_instead;
+ }
+
+ /* Lets enable intr for the last descriptor only */
+ if (1==i)
+ flags = DDMA_FLAGS_IE;
+ else
+ flags = DDMA_FLAGS_NOIE;
+
+ if (iswrite) {
+ if(!put_source_flags(ahwif->tx_chan,
+ (void*)(page_address(sg->page)
+ + sg->offset),
+ tc, flags)) {
+ printk(KERN_ERR "%s failed %d\n",
+ __FUNCTION__, __LINE__);
}
- } else
+ } else
{
- if(!put_dest_flags(ahwif->rx_chan,
- (void*)(page_address(sg->page)
- + sg->offset),
- tc, flags)) {
- printk(KERN_ERR "%s failed %d\n",
- __FUNCTION__, __LINE__);
+ if(!put_dest_flags(ahwif->rx_chan,
+ (void*)(page_address(sg->page)
+ + sg->offset),
+ tc, flags)) {
+ printk(KERN_ERR "%s failed %d\n",
+ __FUNCTION__, __LINE__);
}
- }
+ }
- cur_addr += tc;
- cur_len -= tc;
- }
- sg++;
- i--;
- }
+ cur_addr += tc;
+ cur_len -= tc;
+ }
+ sg++;
+ i--;
+ }
- if (count)
- return 1;
+ if (count)
+ return 1;
-use_pio_instead:
- dma_unmap_sg(ahwif->dev,
- hwif->sg_table,
- hwif->sg_nents,
- hwif->sg_dma_direction);
+ use_pio_instead:
+ dma_unmap_sg(ahwif->dev,
+ hwif->sg_table,
+ hwif->sg_nents,
+ hwif->sg_dma_direction);
- return 0; /* revert to PIO for this request */
+ return 0; /* revert to PIO for this request */
}
static int auide_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
- _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+ ide_hwif_t *hwif = HWIF(drive);
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
- if (hwif->sg_nents) {
- dma_unmap_sg(ahwif->dev, hwif->sg_table, hwif->sg_nents,
- hwif->sg_dma_direction);
- hwif->sg_nents = 0;
- }
+ if (hwif->sg_nents) {
+ dma_unmap_sg(ahwif->dev, hwif->sg_table, hwif->sg_nents,
+ hwif->sg_dma_direction);
+ hwif->sg_nents = 0;
+ }
- return 0;
+ return 0;
}
static void auide_dma_start(ide_drive_t *drive )
{
-// printk("%s\n", __FUNCTION__);
}
-ide_startstop_t auide_dma_intr(ide_drive_t *drive)
-{
- //printk("%s\n", __FUNCTION__);
-
- u8 stat = 0, dma_stat = 0;
-
- dma_stat = HWIF(drive)->ide_dma_end(drive);
- stat = HWIF(drive)->INB(IDE_STATUS_REG); /* get drive status */
- if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
- if (!dma_stat) {
- struct request *rq = HWGROUP(drive)->rq;
-
- ide_end_request(drive, 1, rq->nr_sectors);
- return ide_stopped;
- }
- printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
- drive->name, dma_stat);
- }
- return ide_error(drive, "dma_intr", stat);
-}
static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
{
- //printk("%s\n", __FUNCTION__);
-
- /* issue cmd to drive */
- ide_execute_command(drive, command, &auide_dma_intr,
- (2*WAIT_CMD), NULL);
+ /* issue cmd to drive */
+ ide_execute_command(drive, command, &ide_dma_intr,
+ (2*WAIT_CMD), NULL);
}
static int auide_dma_setup(ide_drive_t *drive)
-{
-// printk("%s\n", __FUNCTION__);
-
- if (drive->media != ide_disk)
- return 1;
-
- if (!auide_build_dmatable(drive))
- /* try PIO instead of DMA */
- return 1;
+{
+ struct request *rq = HWGROUP(drive)->rq;
- drive->waiting_for_dma = 1;
+ if (!auide_build_dmatable(drive)) {
+ ide_map_sg(drive, rq);
+ return 1;
+ }
- return 0;
+ drive->waiting_for_dma = 1;
+ return 0;
}
static int auide_dma_check(ide_drive_t *drive)
{
-// printk("%s\n", __FUNCTION__);
+ u8 speed;
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
- if( !dbdma_init_done ){
- auide_hwif.white_list = in_drive_list(drive->id,
- dma_white_list);
- auide_hwif.black_list = in_drive_list(drive->id,
- dma_black_list);
- auide_hwif.drive = drive;
- auide_ddma_init(&auide_hwif);
- dbdma_init_done = 1;
- }
+
+ if( dbdma_init_done == 0 ){
+ auide_hwif.white_list = ide_in_drive_list(drive->id,
+ dma_white_list);
+ auide_hwif.black_list = ide_in_drive_list(drive->id,
+ dma_black_list);
+ auide_hwif.drive = drive;
+ auide_ddma_init(&auide_hwif);
+ dbdma_init_done = 1;
+ }
#endif
- /* Is the drive in our DMA black list? */
- if ( auide_hwif.black_list ) {
- drive->using_dma = 0;
- printk("%s found in dma_blacklist[]! Disabling DMA.\n",
- drive->id->model);
- }
- else
- drive->using_dma = 1;
+ /* Is the drive in our DMA black list? */
+
+ if ( auide_hwif.black_list ) {
+ drive->using_dma = 0;
+
+ /* Borrowed the warning message from ide-dma.c */
- return HWIF(drive)->ide_dma_host_on(drive);
+ printk(KERN_WARNING "%s: Disabling DMA for %s (blacklisted)\n",
+ drive->name, drive->id->model);
+ }
+ else
+ drive->using_dma = 1;
+
+ speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA);
+
+ if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
+ return HWIF(drive)->ide_dma_on(drive);
+
+ return HWIF(drive)->ide_dma_off_quietly(drive);
}
static int auide_dma_test_irq(ide_drive_t *drive)
-{
-// printk("%s\n", __FUNCTION__);
-
- if (!drive->waiting_for_dma)
- printk(KERN_WARNING "%s: ide_dma_test_irq \
+{
+ if (drive->waiting_for_dma == 0)
+ printk(KERN_WARNING "%s: ide_dma_test_irq \
called while not waiting\n", drive->name);
- /* If dbdma didn't execute the STOP command yet, the
- * active bit is still set
+ /* If dbdma didn't execute the STOP command yet, the
+ * active bit is still set
*/
- drive->waiting_for_dma++;
- if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
- printk(KERN_WARNING "%s: timeout waiting for ddma to \
+ drive->waiting_for_dma++;
+ if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
+ printk(KERN_WARNING "%s: timeout waiting for ddma to \
complete\n", drive->name);
- return 1;
- }
- udelay(10);
- return 0;
+ return 1;
+ }
+ udelay(10);
+ return 0;
}
static int auide_dma_host_on(ide_drive_t *drive)
{
-// printk("%s\n", __FUNCTION__);
- return 0;
+ return 0;
}
static int auide_dma_on(ide_drive_t *drive)
{
-// printk("%s\n", __FUNCTION__);
- drive->using_dma = 1;
- return auide_dma_host_on(drive);
+ drive->using_dma = 1;
+ return auide_dma_host_on(drive);
}
static int auide_dma_host_off(ide_drive_t *drive)
{
-// printk("%s\n", __FUNCTION__);
- return 0;
+ return 0;
}
static int auide_dma_off_quietly(ide_drive_t *drive)
{
-// printk("%s\n", __FUNCTION__);
- drive->using_dma = 0;
- return auide_dma_host_off(drive);
+ drive->using_dma = 0;
+ return auide_dma_host_off(drive);
}
static int auide_dma_lostirq(ide_drive_t *drive)
{
-// printk("%s\n", __FUNCTION__);
-
- printk(KERN_ERR "%s: IRQ lost\n", drive->name);
- return 0;
+ printk(KERN_ERR "%s: IRQ lost\n", drive->name);
+ return 0;
}
static void auide_ddma_tx_callback(int irq, void *param, struct pt_regs *regs)
{
-// printk("%s\n", __FUNCTION__);
-
- _auide_hwif *ahwif = (_auide_hwif*)param;
- ahwif->drive->waiting_for_dma = 0;
- return;
+ _auide_hwif *ahwif = (_auide_hwif*)param;
+ ahwif->drive->waiting_for_dma = 0;
}
static void auide_ddma_rx_callback(int irq, void *param, struct pt_regs *regs)
{
-// printk("%s\n", __FUNCTION__);
+ _auide_hwif *ahwif = (_auide_hwif*)param;
+ ahwif->drive->waiting_for_dma = 0;
+}
+
+#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
- _auide_hwif *ahwif = (_auide_hwif*)param;
- ahwif->drive->waiting_for_dma = 0;
- return;
+static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags)
+{
+ dev->dev_id = dev_id;
+ dev->dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
+ dev->dev_intlevel = 0;
+ dev->dev_intpolarity = 0;
+ dev->dev_tsize = tsize;
+ dev->dev_devwidth = devwidth;
+ dev->dev_flags = flags;
}
+
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
static int auide_dma_timeout(ide_drive_t *drive)
{
// printk("%s\n", __FUNCTION__);
- printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
+ printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
- if (HWIF(drive)->ide_dma_test_irq(drive))
- return 0;
+ if (HWIF(drive)->ide_dma_test_irq(drive))
+ return 0;
- return HWIF(drive)->ide_dma_end(drive);
+ return HWIF(drive)->ide_dma_end(drive);
}
-#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
+
+static int auide_ddma_init(_auide_hwif *auide) {
+
+ dbdev_tab_t source_dev_tab, target_dev_tab;
+ u32 dev_id, tsize, devwidth, flags;
+ ide_hwif_t *hwif = auide->hwif;
-static int auide_ddma_init( _auide_hwif *auide )
-{
-// printk("%s\n", __FUNCTION__);
+ dev_id = AU1XXX_ATA_DDMA_REQ;
- dbdev_tab_t source_dev_tab;
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
- dbdev_tab_t target_dev_tab;
- ide_hwif_t *hwif = auide->hwif;
- char warning_output [2][80];
- int i;
-#endif
+ if (auide->white_list || auide->black_list) {
+ tsize = 8;
+ devwidth = 32;
+ }
+ else {
+ tsize = 1;
+ devwidth = 16;
+
+ printk(KERN_ERR "au1xxx-ide: %s is not on ide driver whitelist.\n",auide_hwif.drive->id->model);
+ printk(KERN_ERR " please read 'Documentation/mips/AU1xxx_IDE.README'");
+ }
- /* Add our custom device to DDMA device table */
- /* Create our new device entries in the table */
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
- source_dev_tab.dev_id = AU1XXX_ATA_DDMA_REQ;
-
- if( auide->white_list || auide->black_list ){
- source_dev_tab.dev_tsize = 8;
- source_dev_tab.dev_devwidth = 32;
- source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
- source_dev_tab.dev_intlevel = 0;
- source_dev_tab.dev_intpolarity = 0;
-
- /* init device table for target - static bus controller - */
- target_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
- target_dev_tab.dev_tsize = 8;
- target_dev_tab.dev_devwidth = 32;
- target_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
- target_dev_tab.dev_intlevel = 0;
- target_dev_tab.dev_intpolarity = 0;
- target_dev_tab.dev_flags = DEV_FLAGS_ANYUSE;
- }
- else{
- source_dev_tab.dev_tsize = 1;
- source_dev_tab.dev_devwidth = 16;
- source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
- source_dev_tab.dev_intlevel = 0;
- source_dev_tab.dev_intpolarity = 0;
-
- /* init device table for target - static bus controller - */
- target_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
- target_dev_tab.dev_tsize = 1;
- target_dev_tab.dev_devwidth = 16;
- target_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
- target_dev_tab.dev_intlevel = 0;
- target_dev_tab.dev_intpolarity = 0;
- target_dev_tab.dev_flags = DEV_FLAGS_ANYUSE;
-
- sprintf(&warning_output[0][0],
- "%s is not on ide driver white list.",
- auide_hwif.drive->id->model);
- for ( i=strlen(&warning_output[0][0]) ; i<76; i++ ){
- sprintf(&warning_output[0][i]," ");
- }
-
- sprintf(&warning_output[1][0],
- "To add %s please read 'Documentation/mips/AU1xxx_IDE.README'.",
- auide_hwif.drive->id->model);
- for ( i=strlen(&warning_output[1][0]) ; i<76; i++ ){
- sprintf(&warning_output[1][i]," ");
- }
-
- printk("\n****************************************");
- printk("****************************************\n");
- printk("* %s *\n",&warning_output[0][0]);
- printk("* Switch to safe MWDMA Mode! ");
- printk(" *\n");
- printk("* %s *\n",&warning_output[1][0]);
- printk("****************************************");
- printk("****************************************\n\n");
- }
+#ifdef IDE_AU1XXX_BURSTMODE
+ flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;
#else
- source_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
- source_dev_tab.dev_tsize = 8;
- source_dev_tab.dev_devwidth = 32;
- source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
- source_dev_tab.dev_intlevel = 0;
- source_dev_tab.dev_intpolarity = 0;
+ flags = DEV_FLAGS_SYNC;
#endif
-#if CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
- /* set flags for tx channel */
- source_dev_tab.dev_flags = DEV_FLAGS_OUT
- | DEV_FLAGS_SYNC
- | DEV_FLAGS_BURSTABLE;
- auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
- /* set flags for rx channel */
- source_dev_tab.dev_flags = DEV_FLAGS_IN
- | DEV_FLAGS_SYNC
- | DEV_FLAGS_BURSTABLE;
- auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+ /* setup dev_tab for tx channel */
+ auide_init_dbdma_dev( &source_dev_tab,
+ dev_id,
+ tsize, devwidth, DEV_FLAGS_OUT | flags);
+ auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+
+ auide_init_dbdma_dev( &source_dev_tab,
+ dev_id,
+ tsize, devwidth, DEV_FLAGS_IN | flags);
+ auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+
+ /* We also need to add a target device for the DMA */
+ auide_init_dbdma_dev( &target_dev_tab,
+ (u32)DSCR_CMD0_ALWAYS,
+ tsize, devwidth, DEV_FLAGS_ANYUSE);
+ auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab);
+
+ /* Get a channel for TX */
+ auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id,
+ auide->tx_dev_id,
+ auide_ddma_tx_callback,
+ (void*)auide);
+
+ /* Get a channel for RX */
+ auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
+ auide->target_dev_id,
+ auide_ddma_rx_callback,
+ (void*)auide);
+
+ auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
+ NUM_DESCRIPTORS);
+ auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
+ NUM_DESCRIPTORS);
+
+ hwif->dmatable_cpu = dma_alloc_coherent(auide->dev,
+ PRD_ENTRIES * PRD_BYTES, /* 1 Page */
+ &hwif->dmatable_dma, GFP_KERNEL);
+
+ au1xxx_dbdma_start( auide->tx_chan );
+ au1xxx_dbdma_start( auide->rx_chan );
+
+ return 0;
+}
#else
- /* set flags for tx channel */
- source_dev_tab.dev_flags = DEV_FLAGS_OUT | DEV_FLAGS_SYNC;
- auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
- /* set flags for rx channel */
- source_dev_tab.dev_flags = DEV_FLAGS_IN | DEV_FLAGS_SYNC;
- auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
-#endif
+
+static int auide_ddma_init( _auide_hwif *auide )
+{
+ dbdev_tab_t source_dev_tab;
+ int flags;
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
-
- auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab);
-
- /* Get a channel for TX */
- auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id,
- auide->tx_dev_id,
- auide_ddma_tx_callback,
- (void*)auide);
- /* Get a channel for RX */
- auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
- auide->target_dev_id,
- auide_ddma_rx_callback,
- (void*)auide);
-#else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */
- /*
- * Note: if call back is not enabled, update ctp->cur_ptr manually
- */
- auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS,
- auide->tx_dev_id,
- NULL,
- (void*)auide);
- auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
- DSCR_CMD0_ALWAYS,
- NULL,
- (void*)auide);
+#ifdef IDE_AU1XXX_BURSTMODE
+ flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;
+#else
+ flags = DEV_FLAGS_SYNC;
#endif
- auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
- NUM_DESCRIPTORS);
- auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
- NUM_DESCRIPTORS);
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
- hwif->dmatable_cpu = dma_alloc_coherent(auide->dev,
- PRD_ENTRIES * PRD_BYTES, /* 1 Page */
- &hwif->dmatable_dma, GFP_KERNEL);
-
- auide->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
- GFP_KERNEL|GFP_DMA);
- if (auide->sg_table == NULL) {
- return -ENOMEM;
- }
-#endif
- au1xxx_dbdma_start( auide->tx_chan );
- au1xxx_dbdma_start( auide->rx_chan );
- return 0;
+ /* setup dev_tab for tx channel */
+ auide_init_dbdma_dev( &source_dev_tab,
+ (u32)DSCR_CMD0_ALWAYS,
+ 8, 32, DEV_FLAGS_OUT | flags);
+ auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+
+ auide_init_dbdma_dev( &source_dev_tab,
+ (u32)DSCR_CMD0_ALWAYS,
+ 8, 32, DEV_FLAGS_IN | flags);
+ auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+
+ /* Get a channel for TX */
+ auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS,
+ auide->tx_dev_id,
+ NULL,
+ (void*)auide);
+
+ /* Get a channel for RX */
+ auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
+ DSCR_CMD0_ALWAYS,
+ NULL,
+ (void*)auide);
+
+ auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
+ NUM_DESCRIPTORS);
+ auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
+ NUM_DESCRIPTORS);
+
+ au1xxx_dbdma_start( auide->tx_chan );
+ au1xxx_dbdma_start( auide->rx_chan );
+
+ return 0;
}
+#endif
static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif)
{
- int i;
-#define ide_ioreg_t unsigned long
- ide_ioreg_t *ata_regs = hw->io_ports;
-
- /* fixme */
- for (i = 0; i < IDE_CONTROL_OFFSET; i++) {
- *ata_regs++ = (ide_ioreg_t) ahwif->regbase
- + (ide_ioreg_t)(i << AU1XXX_ATA_REG_OFFSET);
- }
-
- /* set the Alternative Status register */
- *ata_regs = (ide_ioreg_t) ahwif->regbase
- + (ide_ioreg_t)(14 << AU1XXX_ATA_REG_OFFSET);
+ int i;
+ unsigned long *ata_regs = hw->io_ports;
+
+ /* FIXME? */
+ for (i = 0; i < IDE_CONTROL_OFFSET; i++) {
+ *ata_regs++ = ahwif->regbase + (i << AU1XXX_ATA_REG_OFFSET);
+ }
+
+ /* set the Alternative Status register */
+ *ata_regs = ahwif->regbase + (14 << AU1XXX_ATA_REG_OFFSET);
}
static int au_ide_probe(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
- _auide_hwif *ahwif = &auide_hwif;
- ide_hwif_t *hwif;
+ _auide_hwif *ahwif = &auide_hwif;
+ ide_hwif_t *hwif;
struct resource *res;
int ret = 0;
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
- char *mode = "MWDMA2";
+ char *mode = "MWDMA2";
#elif defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
- char *mode = "PIO+DDMA(offload)";
+ char *mode = "PIO+DDMA(offload)";
#endif
- memset(&auide_hwif, 0, sizeof(_auide_hwif));
- auide_hwif.dev = 0;
+ memset(&auide_hwif, 0, sizeof(_auide_hwif));
+ auide_hwif.dev = 0;
ahwif->dev = dev;
ahwif->irq = platform_get_irq(pdev, 0);
@@ -902,11 +675,11 @@ static int au_ide_probe(struct device *dev)
goto out;
}
- if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {
+ if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {
pr_debug("%s: request_mem_region failed\n", DRV_NAME);
- ret = -EBUSY;
+ ret = -EBUSY;
goto out;
- }
+ }
ahwif->regbase = (u32)ioremap(res->start, res->end-res->start);
if (ahwif->regbase == 0) {
@@ -914,130 +687,92 @@ static int au_ide_probe(struct device *dev)
goto out;
}
- hwif = &ide_hwifs[pdev->id];
+ /* FIXME: This might possibly break PCMCIA IDE devices */
+
+ hwif = &ide_hwifs[pdev->id];
hw_regs_t *hw = &hwif->hw;
- hwif->irq = hw->irq = ahwif->irq;
- hwif->chipset = ide_au1xxx;
+ hwif->irq = hw->irq = ahwif->irq;
+ hwif->chipset = ide_au1xxx;
- auide_setup_ports(hw, ahwif);
+ auide_setup_ports(hw, ahwif);
memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
- hwif->rqsize = CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ;
- hwif->rqsize = ((hwif->rqsize > AU1XXX_ATA_RQSIZE)
- || (hwif->rqsize < 32)) ? AU1XXX_ATA_RQSIZE : hwif->rqsize;
-#else /* if kernel config is not set */
- hwif->rqsize = AU1XXX_ATA_RQSIZE;
-#endif
-
- hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
+ hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
- hwif->mwdma_mask = 0x07; /* Multimode-2 DMA */
- hwif->swdma_mask = 0x07;
+ hwif->mwdma_mask = 0x07; /* Multimode-2 DMA */
+ hwif->swdma_mask = 0x00;
#else
- hwif->mwdma_mask = 0x0;
- hwif->swdma_mask = 0x0;
+ hwif->mwdma_mask = 0x0;
+ hwif->swdma_mask = 0x0;
+#endif
+
+ hwif->noprobe = 0;
+ hwif->drives[0].unmask = 1;
+ hwif->drives[1].unmask = 1;
+
+ /* hold should be on in all cases */
+ hwif->hold = 1;
+ hwif->mmio = 2;
+
+ /* If the user has selected DDMA assisted copies,
+ then set up a few local I/O function entry points
+ */
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
+ hwif->INSW = auide_insw;
+ hwif->OUTSW = auide_outsw;
#endif
- //hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
- hwif->noprobe = 0;
- hwif->drives[0].unmask = 1;
- hwif->drives[1].unmask = 1;
-
- /* hold should be on in all cases */
- hwif->hold = 1;
- hwif->mmio = 2;
-
- /* set up local I/O function entry points */
- hwif->INB = auide_inb;
- hwif->INW = auide_inw;
- hwif->INL = auide_inl;
- hwif->INSW = auide_insw;
- hwif->INSL = auide_insl;
- hwif->OUTB = auide_outb;
- hwif->OUTBSYNC = auide_outbsync;
- hwif->OUTW = auide_outw;
- hwif->OUTL = auide_outl;
- hwif->OUTSW = auide_outsw;
- hwif->OUTSL = auide_outsl;
-
- hwif->tuneproc = &auide_tune_drive;
- hwif->speedproc = &auide_tune_chipset;
+
+ hwif->tuneproc = &auide_tune_drive;
+ hwif->speedproc = &auide_tune_chipset;
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
- hwif->ide_dma_off_quietly = &auide_dma_off_quietly;
- hwif->ide_dma_timeout = &auide_dma_timeout;
-
- hwif->ide_dma_check = &auide_dma_check;
- hwif->dma_exec_cmd = &auide_dma_exec_cmd;
- hwif->dma_start = &auide_dma_start;
- hwif->ide_dma_end = &auide_dma_end;
- hwif->dma_setup = &auide_dma_setup;
- hwif->ide_dma_test_irq = &auide_dma_test_irq;
- hwif->ide_dma_host_off = &auide_dma_host_off;
- hwif->ide_dma_host_on = &auide_dma_host_on;
- hwif->ide_dma_lostirq = &auide_dma_lostirq;
- hwif->ide_dma_on = &auide_dma_on;
-
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
- hwif->atapi_dma = 1;
- hwif->drives[0].using_dma = 1;
- hwif->drives[1].using_dma = 1;
+ hwif->ide_dma_off_quietly = &auide_dma_off_quietly;
+ hwif->ide_dma_timeout = &auide_dma_timeout;
+
+ hwif->ide_dma_check = &auide_dma_check;
+ hwif->dma_exec_cmd = &auide_dma_exec_cmd;
+ hwif->dma_start = &auide_dma_start;
+ hwif->ide_dma_end = &auide_dma_end;
+ hwif->dma_setup = &auide_dma_setup;
+ hwif->ide_dma_test_irq = &auide_dma_test_irq;
+ hwif->ide_dma_host_off = &auide_dma_host_off;
+ hwif->ide_dma_host_on = &auide_dma_host_on;
+ hwif->ide_dma_lostirq = &auide_dma_lostirq;
+ hwif->ide_dma_on = &auide_dma_on;
+
+ hwif->autodma = 1;
+ hwif->drives[0].autodma = hwif->autodma;
+ hwif->drives[1].autodma = hwif->autodma;
+ hwif->atapi_dma = 1;
+
#else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
- hwif->autodma = 0;
- hwif->channel = 0;
- hwif->hold = 1;
- hwif->select_data = 0; /* no chipset-specific code */
- hwif->config_data = 0; /* no chipset-specific code */
-
- hwif->drives[0].autodma = 0;
- hwif->drives[0].drive_data = 0; /* no drive data */
- hwif->drives[0].using_dma = 0;
- hwif->drives[0].waiting_for_dma = 0;
- hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */
- /* secondary hdd not supported */
- hwif->drives[1].autodma = 0;
-
- hwif->drives[1].drive_data = 0;
- hwif->drives[1].using_dma = 0;
- hwif->drives[1].waiting_for_dma = 0;
- hwif->drives[1].autotune = 2; /* 1=autotune, 2=noautotune, 0=default */
-#endif
- hwif->drives[0].io_32bit = 0; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
- hwif->drives[1].io_32bit = 0; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
-
- /*Register Driver with PM Framework*/
-#ifdef CONFIG_PM
- auide_hwif.pm.lock = SPIN_LOCK_UNLOCKED;
- auide_hwif.pm.stopped = 0;
-
- auide_hwif.pm.dev = new_au1xxx_power_device( "ide",
- &au1200ide_pm_callback,
- NULL);
- if ( auide_hwif.pm.dev == NULL )
- printk(KERN_INFO "Unable to create a power management \
- device entry for the au1200-IDE.\n");
- else
- printk(KERN_INFO "Power management device entry for the \
- au1200-IDE loaded.\n");
+ hwif->autodma = 0;
+ hwif->channel = 0;
+ hwif->hold = 1;
+ hwif->select_data = 0; /* no chipset-specific code */
+ hwif->config_data = 0; /* no chipset-specific code */
+
+ hwif->drives[0].autodma = 0;
+ hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */
#endif
+ hwif->drives[0].no_io_32bit = 1;
- auide_hwif.hwif = hwif;
- hwif->hwif_data = &auide_hwif;
+ auide_hwif.hwif = hwif;
+ hwif->hwif_data = &auide_hwif;
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
- auide_ddma_init(&auide_hwif);
- dbdma_init_done = 1;
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
+ auide_ddma_init(&auide_hwif);
+ dbdma_init_done = 1;
#endif
probe_hwif_init(hwif);
dev_set_drvdata(dev, hwif);
- printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
+ printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
-out:
- return ret;
+ out:
+ return ret;
}
static int au_ide_remove(struct device *dev)
@@ -1045,7 +780,7 @@ static int au_ide_remove(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct resource *res;
ide_hwif_t *hwif = dev_get_drvdata(dev);
- _auide_hwif *ahwif = &auide_hwif;
+ _auide_hwif *ahwif = &auide_hwif;
ide_unregister(hwif - ide_hwifs);
@@ -1069,180 +804,11 @@ static int __init au_ide_init(void)
return driver_register(&au1200_ide_driver);
}
-static void __init au_ide_exit(void)
+static void __exit au_ide_exit(void)
{
driver_unregister(&au1200_ide_driver);
}
-#ifdef CONFIG_PM
-int au1200ide_pm_callback( au1xxx_power_dev_t *dev,\
- au1xxx_request_t request, void *data) {
-
- unsigned int d, err = 0;
- unsigned long flags;
-
- spin_lock_irqsave(auide_hwif.pm.lock, flags);
-
- switch (request){
- case AU1XXX_PM_SLEEP:
- err = au1xxxide_pm_sleep(dev);
- break;
- case AU1XXX_PM_WAKEUP:
- d = *((unsigned int*)data);
- if ( d > 0 && d <= 99) {
- err = au1xxxide_pm_standby(dev);
- }
- else {
- err = au1xxxide_pm_resume(dev);
- }
- break;
- case AU1XXX_PM_GETSTATUS:
- err = au1xxxide_pm_getstatus(dev);
- break;
- case AU1XXX_PM_ACCESS:
- err = au1xxxide_pm_access(dev);
- break;
- case AU1XXX_PM_IDLE:
- err = au1xxxide_pm_idle(dev);
- break;
- case AU1XXX_PM_CLEANUP:
- err = au1xxxide_pm_cleanup(dev);
- break;
- default:
- err = -1;
- break;
- }
-
- spin_unlock_irqrestore(auide_hwif.pm.lock, flags);
-
- return err;
-}
-
-static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev ) {
- return 0;
-}
-
-static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev ) {
-
- int retval;
- ide_hwif_t *hwif = auide_hwif.hwif;
- struct request rq;
- struct request_pm_state rqpm;
- ide_task_t args;
-
- if(auide_hwif.pm.stopped)
- return -1;
-
- /*
- * wait until hard disc is ready
- */
- if ( wait_for_ready(&hwif->drives[0], 35000) ) {
- printk("Wait for drive sleep timeout!\n");
- retval = -1;
- }
-
- /*
- * sequenz to tell the high level ide driver that pm is resuming
- */
- memset(&rq, 0, sizeof(rq));
- memset(&rqpm, 0, sizeof(rqpm));
- memset(&args, 0, sizeof(args));
- rq.flags = REQ_PM_SUSPEND;
- rq.special = &args;
- rq.pm = &rqpm;
- rqpm.pm_step = ide_pm_state_start_suspend;
- rqpm.pm_state = PMSG_SUSPEND;
-
- retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_wait);
-
- if (wait_for_ready (&hwif->drives[0], 35000)) {
- printk("Wait for drive sleep timeout!\n");
- retval = -1;
- }
-
- /*
- * stop dbdma channels
- */
- au1xxx_dbdma_reset(auide_hwif.tx_chan);
- au1xxx_dbdma_reset(auide_hwif.rx_chan);
-
- auide_hwif.pm.stopped = 1;
-
- return retval;
-}
-
-static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev ) {
-
- int retval;
- ide_hwif_t *hwif = auide_hwif.hwif;
- struct request rq;
- struct request_pm_state rqpm;
- ide_task_t args;
-
- if(!auide_hwif.pm.stopped)
- return -1;
-
- /*
- * start dbdma channels
- */
- au1xxx_dbdma_start(auide_hwif.tx_chan);
- au1xxx_dbdma_start(auide_hwif.rx_chan);
-
- /*
- * wait until hard disc is ready
- */
- if (wait_for_ready ( &hwif->drives[0], 35000)) {
- printk("Wait for drive wake up timeout!\n");
- retval = -1;
- }
-
- /*
- * sequenz to tell the high level ide driver that pm is resuming
- */
- memset(&rq, 0, sizeof(rq));
- memset(&rqpm, 0, sizeof(rqpm));
- memset(&args, 0, sizeof(args));
- rq.flags = REQ_PM_RESUME;
- rq.special = &args;
- rq.pm = &rqpm;
- rqpm.pm_step = ide_pm_state_start_resume;
- rqpm.pm_state = PMSG_ON;
-
- retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_head_wait);
-
- /*
- * wait for hard disc
- */
- if ( wait_for_ready(&hwif->drives[0], 35000) ) {
- printk("Wait for drive wake up timeout!\n");
- retval = -1;
- }
-
- auide_hwif.pm.stopped = 0;
-
- return retval;
-}
-
-static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev ) {
- return dev->cur_state;
-}
-
-static int au1xxxide_pm_access( au1xxx_power_dev_t *dev ) {
- if (dev->cur_state != AWAKE_STATE)
- return 0;
- else
- return -1;
-}
-
-static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev ) {
- return 0;
-}
-
-static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev ) {
- return 0;
-}
-#endif /* CONFIG_PM */
-
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("AU1200 IDE driver");
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index af526b671c4e..4ee597d08797 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -622,12 +622,18 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
ide_hwif_t *hwif;
int h;
+ /*
+ * Find an empty HWIF; if none available, return -ENOMEM.
+ */
for (h = 0; h < MAX_HWIFS; ++h) {
hwif = &ide_hwifs[h];
- /* Find an empty HWIF */
if (hwif->chipset == ide_unknown)
break;
}
+ if (h == MAX_HWIFS) {
+ printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", d->name);
+ return -ENOMEM;
+ }
/* Get the CmdBlk and CtrlBlk Base Registers */
base = pci_resource_start(dev, 0) + IOC4_CMD_OFFSET;
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 7161ce0ef5aa..86fb1e0286d3 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -80,6 +80,7 @@ static struct via_isa_bridge {
u16 flags;
} via_isa_bridges[] = {
{ "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+ { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h
index 38f42112dff0..ae9b02cc013f 100644
--- a/drivers/ieee1394/hosts.h
+++ b/drivers/ieee1394/hosts.h
@@ -41,6 +41,7 @@ struct hpsb_host {
/* this nodes state */
unsigned in_bus_reset:1;
unsigned is_shutdown:1;
+ unsigned resume_packet_sent:1;
/* this nodes' duties on the bus */
unsigned is_root:1;
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 7fff5a1d2ea4..0ea37b1bccb2 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -1349,6 +1349,33 @@ static void nodemgr_update_pdrv(struct node_entry *ne)
}
+/* Write the BROADCAST_CHANNEL as per IEEE1394a 8.3.2.3.11 and 8.4.2.3. This
+ * seems like an optional service but in the end it is practically mandatory
+ * as a consequence of these clauses.
+ *
+ * Note that we cannot do a broadcast write to all nodes at once because some
+ * pre-1394a devices would hang. */
+static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
+{
+ const u64 bc_addr = (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL);
+ quadlet_t bc_remote, bc_local;
+ int ret;
+
+ if (!ne->host->is_irm || ne->generation != generation ||
+ ne->nodeid == ne->host->node_id)
+ return;
+
+ bc_local = cpu_to_be32(ne->host->csr.broadcast_channel);
+
+ /* Check if the register is implemented and 1394a compliant. */
+ ret = hpsb_read(ne->host, ne->nodeid, generation, bc_addr, &bc_remote,
+ sizeof(bc_remote));
+ if (!ret && bc_remote & cpu_to_be32(0x80000000) &&
+ bc_remote != bc_local)
+ hpsb_node_write(ne, bc_addr, &bc_local, sizeof(bc_local));
+}
+
+
static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
{
struct device *dev;
@@ -1360,6 +1387,8 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
if (!dev)
return;
+ nodemgr_irm_write_bc(ne, generation);
+
/* If "needs_probe", then this is either a new or changed node we
* rescan totally. If the generation matches for an existing node
* (one that existed prior to the bus reset) we send update calls
@@ -1413,9 +1442,25 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
return;
}
-/* Because we are a 1394a-2000 compliant IRM, we need to inform all the other
- * nodes of the broadcast channel. (Really we're only setting the validity
- * bit). Other IRM responsibilities go in here as well. */
+static int nodemgr_send_resume_packet(struct hpsb_host *host)
+{
+ struct hpsb_packet *packet;
+ int ret = 1;
+
+ packet = hpsb_make_phypacket(host,
+ 0x003c0000 | NODEID_TO_NODE(host->node_id) << 24);
+ if (packet) {
+ packet->no_waiter = 1;
+ packet->generation = get_hpsb_generation(host);
+ ret = hpsb_send_packet(packet);
+ }
+ if (ret)
+ HPSB_WARN("fw-host%d: Failed to broadcast resume packet",
+ host->id);
+ return ret;
+}
+
+/* Perform a few high-level IRM responsibilities. */
static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
{
quadlet_t bc;
@@ -1424,13 +1469,8 @@ static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
if (!host->is_irm || host->irm_id == (nodeid_t)-1)
return 1;
- host->csr.broadcast_channel |= 0x40000000; /* set validity bit */
-
- bc = cpu_to_be32(host->csr.broadcast_channel);
-
- hpsb_write(host, LOCAL_BUS | ALL_NODES, get_hpsb_generation(host),
- (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL),
- &bc, sizeof(quadlet_t));
+ /* We are a 1394a-2000 compliant IRM. Set the validity bit. */
+ host->csr.broadcast_channel |= 0x40000000;
/* If there is no bus manager then we should set the root node's
* force_root bit to promote bus stability per the 1394
@@ -1463,6 +1503,13 @@ static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
}
}
+ /* Some devices suspend their ports while being connected to an inactive
+ * host adapter, i.e. if connected before the low-level driver is
+ * loaded. They become visible either when physically unplugged and
+ * replugged, or when receiving a resume packet. Send one once. */
+ if (!host->resume_packet_sent && !nodemgr_send_resume_packet(host))
+ host->resume_packet_sent = 1;
+
return 1;
}
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index 49d0416a2a9a..bac3085185fe 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -320,7 +320,7 @@ static struct dmi_system_id dmi_ids[] = {
},
.driver_data = keymap_acer_aspire_1500
},
- { 0, }
+ { NULL, }
};
static int __init select_keymap(void)
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 4acc7fd4cd0f..4f41ec3e4332 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -42,7 +42,7 @@ static struct alps_model_info alps_model_data[] = {
{ { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
{ { 0x63, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
{ { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
- { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, 0 },
+ { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */
{ { 0x63, 0x02, 0x3c }, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */
{ { 0x63, 0x02, 0x50 }, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */
{ { 0x63, 0x02, 0x64 }, 0xf8, 0xf8, 0 },
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index e6541aff3996..2239651969c8 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -406,7 +406,7 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
}
dprintk(verbose, DST_CA_DEBUG, 1, " ");
- if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) {
+ if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg))) {
result = -EFAULT;
goto free_mem_and_exit;
}
@@ -579,7 +579,7 @@ static int dst_ca_release(struct inode *inode, struct file *file)
return 0;
}
-static int dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
+static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
{
int bytes_read = 0;
@@ -588,7 +588,7 @@ static int dst_ca_read(struct file *file, char __user *buffer, size_t length, lo
return bytes_read;
}
-static int dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
+static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
{
dprintk(verbose, DST_CA_DEBUG, 1, " Device write.");
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index e8a1c2247567..ec11619f8ea9 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -126,7 +126,7 @@ u32 em28xx_request_buffers(struct em28xx *dev, u32 count)
const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */
void *buff = NULL;
u32 i;
- em28xx_coredbg("requested %i buffers with size %i", count, imagesize);
+ em28xx_coredbg("requested %i buffers with size %zd", count, imagesize);
if (count > EM28XX_NUM_FRAMES)
count = EM28XX_NUM_FRAMES;
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
index 81ef306cb124..ee7075fa1ec3 100644
--- a/drivers/message/i2o/pci.c
+++ b/drivers/message/i2o/pci.c
@@ -303,6 +303,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
struct i2o_controller *c;
int rc;
struct pci_dev *i960 = NULL;
+ int pci_dev_busy = 0;
printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n");
@@ -395,6 +396,8 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
if ((rc = i2o_pci_alloc(c))) {
printk(KERN_ERR "%s: DMA / IO allocation for I2O controller "
" failed\n", c->name);
+ if (rc == -ENODEV)
+ pci_dev_busy = 1;
goto free_controller;
}
@@ -425,7 +428,8 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
i2o_iop_free(c);
disable:
- pci_disable_device(pdev);
+ if (!pci_dev_busy)
+ pci_disable_device(pdev);
return rc;
}
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index b586a83a9b4c..eb41391e06e9 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -679,7 +679,15 @@ static void mmc_idle_cards(struct mmc_host *host)
}
/*
- * Apply power to the MMC stack.
+ * Apply power to the MMC stack. This is a two-stage process.
+ * First, we enable power to the card without the clock running.
+ * We then wait a bit for the power to stabilise. Finally,
+ * enable the bus drivers and clock to the card.
+ *
+ * We must _NOT_ enable the clock prior to power stablising.
+ *
+ * If a host does all the power sequencing itself, ignore the
+ * initial MMC_POWER_UP stage.
*/
static void mmc_power_up(struct mmc_host *host)
{
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
index 48cce431f89f..45c077d0f063 100644
--- a/drivers/mtd/onenand/generic.c
+++ b/drivers/mtd/onenand/generic.c
@@ -12,9 +12,9 @@
* This is a device driver for the OneNAND flash for generic boards.
*/
-#include <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>
#include <linux/mtd/partitions.h>
@@ -39,7 +39,7 @@ static int __devinit generic_onenand_probe(struct device *dev)
{
struct onenand_info *info;
struct platform_device *pdev = to_platform_device(dev);
- struct onenand_platform_data *pdata = pdev->dev.platform_data;
+ struct flash_platform_data *pdata = pdev->dev.platform_data;
struct resource *res = pdev->resource;
unsigned long size = res->end - res->start + 1;
int err;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index f67d5d6eb9a6..a53a73fc2a5a 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -940,7 +940,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
u_char *eccbuf, struct nand_oobinfo *oobsel)
{
struct onenand_chip *this = mtd->priv;
- unsigned char buffer[MAX_ONENAND_PAGESIZE], *pbuf;
+ unsigned char *pbuf;
size_t total_len, len;
int i, written = 0;
int ret = 0;
@@ -975,7 +975,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
/* Loop until all keve's data has been written */
len = 0;
while (count) {
- pbuf = buffer;
+ pbuf = this->page_buf;
/*
* If the given tuple is >= pagesize then
* write it out from the iov
@@ -995,7 +995,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
int cnt = 0, thislen;
while (cnt < mtd->oobblock) {
thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
- memcpy(buffer + cnt, vecs->iov_base + len, thislen);
+ memcpy(this->page_buf + cnt, vecs->iov_base + len, thislen);
cnt += thislen;
len += thislen;
@@ -1296,6 +1296,12 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
/* Block lock scheme */
for (block = start; block < end; block++) {
+ /* Set block address */
+ value = onenand_block_address(this, block);
+ this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
+ /* Select DataRAM for DDP */
+ value = onenand_bufferram_address(this, block);
+ this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
/* Set start block address */
this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
/* Write unlock command */
@@ -1309,10 +1315,6 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
& ONENAND_CTRL_ONGO)
continue;
- /* Set block address for read block status */
- value = onenand_block_address(this, block);
- this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
-
/* Check lock status */
status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
if (!(status & ONENAND_WP_US))
@@ -1346,7 +1348,6 @@ static void onenand_print_device_info(int device)
static const struct onenand_manufacturers onenand_manuf_ids[] = {
{ONENAND_MFR_SAMSUNG, "Samsung"},
- {ONENAND_MFR_UNKNOWN, "Unknown"}
};
/**
@@ -1357,17 +1358,22 @@ static const struct onenand_manufacturers onenand_manuf_ids[] = {
*/
static int onenand_check_maf(int manuf)
{
+ int size = ARRAY_SIZE(onenand_manuf_ids);
+ char *name;
int i;
- for (i = 0; onenand_manuf_ids[i].id; i++) {
+ for (i = 0; i < size; i++)
if (manuf == onenand_manuf_ids[i].id)
break;
- }
- printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n",
- onenand_manuf_ids[i].name, manuf);
+ if (i < size)
+ name = onenand_manuf_ids[i].name;
+ else
+ name = "Unknown";
+
+ printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf);
- return (i != ONENAND_MFR_UNKNOWN);
+ return (i == size);
}
/**
@@ -1513,6 +1519,18 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
this->read_bufferram = onenand_sync_read_bufferram;
}
+ /* Allocate buffers, if necessary */
+ if (!this->page_buf) {
+ size_t len;
+ len = mtd->oobblock + mtd->oobsize;
+ this->page_buf = kmalloc(len, GFP_KERNEL);
+ if (!this->page_buf) {
+ printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
+ return -ENOMEM;
+ }
+ this->options |= ONENAND_PAGEBUF_ALLOC;
+ }
+
this->state = FL_READY;
init_waitqueue_head(&this->wq);
spin_lock_init(&this->chip_lock);
@@ -1574,12 +1592,21 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
*/
void onenand_release(struct mtd_info *mtd)
{
+ struct onenand_chip *this = mtd->priv;
+
#ifdef CONFIG_MTD_PARTITIONS
/* Deregister partitions */
del_mtd_partitions (mtd);
#endif
/* Deregister the device */
del_mtd_device (mtd);
+
+ /* Free bad block table memory, if allocated */
+ if (this->bbm)
+ kfree(this->bbm);
+ /* Buffer allocated by onenand_scan */
+ if (this->options & ONENAND_PAGEBUF_ALLOC)
+ kfree(this->page_buf);
}
EXPORT_SYMBOL_GPL(onenand_scan);
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
index f40190f499e1..4510d3361eaa 100644
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -118,10 +118,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
*/
static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
{
- unsigned char data_buf[MAX_ONENAND_PAGESIZE];
+ struct onenand_chip *this = mtd->priv;
bd->options &= ~NAND_BBT_SCANEMPTY;
- return create_bbt(mtd, data_buf, bd, -1);
+ return create_bbt(mtd, this->page_buf, bd, -1);
}
/**
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index e57df8dfe6b4..669dd52c412a 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -3078,7 +3078,7 @@ int s2io_set_swapper(nic_t * sp)
static int wait_for_msix_trans(nic_t *nic, int i)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u64 val64;
int ret = 0, cnt = 0;
@@ -3099,7 +3099,7 @@ static int wait_for_msix_trans(nic_t *nic, int i)
void restore_xmsi_data(nic_t *nic)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u64 val64;
int i;
@@ -3117,7 +3117,7 @@ void restore_xmsi_data(nic_t *nic)
static void store_xmsi_data(nic_t *nic)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u64 val64, addr, data;
int i;
@@ -3140,7 +3140,7 @@ static void store_xmsi_data(nic_t *nic)
int s2io_enable_msi(nic_t *nic)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u16 msi_ctrl, msg_val;
struct config_param *config = &nic->config;
struct net_device *dev = nic->dev;
@@ -3190,7 +3190,7 @@ int s2io_enable_msi(nic_t *nic)
int s2io_enable_msi_x(nic_t *nic)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u64 tx_mat, rx_mat;
u16 msi_control; /* Temp variable */
int ret, i, j, msix_indx = 1;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 47bd4a394420..a23ed28a72b8 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -68,8 +68,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.44"
-#define DRV_MODULE_RELDATE "Dec 6, 2005"
+#define DRV_MODULE_VERSION "3.45"
+#define DRV_MODULE_RELDATE "Dec 13, 2005"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -1025,7 +1025,9 @@ static void tg3_frob_aux_power(struct tg3 *tp)
if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 ||
- (tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0) {
+ (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0 ||
+ (tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 ||
+ (tp_peer->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
@@ -1105,6 +1107,8 @@ static int tg3_setup_phy(struct tg3 *, int);
static void tg3_write_sig_post_reset(struct tg3 *, int);
static int tg3_halt_cpu(struct tg3 *, u32);
+static int tg3_nvram_lock(struct tg3 *);
+static void tg3_nvram_unlock(struct tg3 *);
static int tg3_set_power_state(struct tg3 *tp, int state)
{
@@ -1179,6 +1183,21 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
tg3_setup_phy(tp, 0);
}
+ if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+ int i;
+ u32 val;
+
+ for (i = 0; i < 200; i++) {
+ tg3_read_mem(tp, NIC_SRAM_FW_ASF_STATUS_MBOX, &val);
+ if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
+ break;
+ msleep(1);
+ }
+ }
+ tg3_write_mem(tp, NIC_SRAM_WOL_MBOX, WOL_SIGNATURE |
+ WOL_DRV_STATE_SHUTDOWN |
+ WOL_DRV_WOL | WOL_SET_MAGIC_PKT);
+
pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps);
if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) {
@@ -1268,6 +1287,17 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
}
}
+ if (!(tp->tg3_flags & TG3_FLAG_WOL_ENABLE) &&
+ !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+ /* Turn off the PHY */
+ if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
+ tg3_writephy(tp, MII_TG3_EXT_CTRL,
+ MII_TG3_EXT_CTRL_FORCE_LED_OFF);
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
+ tg3_writephy(tp, MII_BMCR, BMCR_PDOWN);
+ }
+ }
+
tg3_frob_aux_power(tp);
/* Workaround for unstable PLL clock */
@@ -1277,8 +1307,12 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1);
tw32(0x7d00, val);
- if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+ if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+ tg3_nvram_lock(tp);
tg3_halt_cpu(tp, RX_CPU_BASE);
+ tw32_f(NVRAM_SWARB, SWARB_REQ_CLR0);
+ tg3_nvram_unlock(tp);
+ }
}
/* Finally, set the new power state. */
@@ -1812,7 +1846,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
}
}
relink:
- if (current_link_up == 0) {
+ if (current_link_up == 0 || tp->link_config.phy_is_low_power) {
u32 tmp;
tg3_phy_copper_begin(tp);
@@ -8533,6 +8567,7 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
tp->tg3_flags |= TG3_FLAG_NVRAM;
+ tg3_nvram_lock(tp);
tg3_enable_nvram_access(tp);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
@@ -8543,6 +8578,7 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
tg3_get_nvram_size(tp);
tg3_disable_nvram_access(tp);
+ tg3_nvram_unlock(tp);
} else {
tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED);
@@ -8640,10 +8676,10 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
if (ret == 0)
*val = swab32(tr32(NVRAM_RDDATA));
- tg3_nvram_unlock(tp);
-
tg3_disable_nvram_access(tp);
+ tg3_nvram_unlock(tp);
+
return ret;
}
@@ -8728,6 +8764,10 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
offset = offset + (pagesize - page_off);
+ /* Nvram lock released by tg3_nvram_read() above,
+ * so need to get it again.
+ */
+ tg3_nvram_lock(tp);
tg3_enable_nvram_access(tp);
/*
@@ -10437,8 +10477,13 @@ static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp)
break;
pci_dev_put(peer);
}
- if (!peer || peer == tp->pdev)
- BUG();
+ /* 5704 can be configured in single-port mode, set peer to
+ * tp->pdev in that case.
+ */
+ if (!peer) {
+ peer = tp->pdev;
+ return peer;
+ }
/*
* We don't need to keep the refcount elevated; there's no way
@@ -10820,12 +10865,14 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
tg3_full_lock(tp, 0);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+ tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
tg3_full_unlock(tp);
err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
if (err) {
tg3_full_lock(tp, 0);
+ tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
tg3_init_hw(tp);
tp->timer.expires = jiffies + tp->timer_offset;
@@ -10859,6 +10906,7 @@ static int tg3_resume(struct pci_dev *pdev)
tg3_full_lock(tp, 0);
+ tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
tg3_init_hw(tp);
tp->timer.expires = jiffies + tp->timer_offset;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index fb7e2a5f4a08..94dbcf3537ec 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1529,6 +1529,12 @@
#define NIC_SRAM_MAC_ADDR_HIGH_MBOX 0x00000c14
#define NIC_SRAM_MAC_ADDR_LOW_MBOX 0x00000c18
+#define NIC_SRAM_WOL_MBOX 0x00000d30
+#define WOL_SIGNATURE 0x474c0000
+#define WOL_DRV_STATE_SHUTDOWN 0x00000001
+#define WOL_DRV_WOL 0x00000002
+#define WOL_SET_MAGIC_PKT 0x00000004
+
#define NIC_SRAM_DATA_CFG_2 0x00000d38
#define SHASTA_EXT_LED_MODE_MASK 0x00018000
@@ -1565,6 +1571,7 @@
#define MII_TG3_EXT_CTRL 0x10 /* Extended control register */
#define MII_TG3_EXT_CTRL_FIFO_ELASTIC 0x0001
#define MII_TG3_EXT_CTRL_LNK3_LED_MODE 0x0002
+#define MII_TG3_EXT_CTRL_FORCE_LED_OFF 0x0008
#define MII_TG3_EXT_CTRL_TBI 0x8000
#define MII_TG3_EXT_STAT 0x11 /* Extended status register */
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 716df015f8d0..6707df968934 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -6,6 +6,9 @@ obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \
pci-driver.o search.o pci-sysfs.o rom.o setup-res.o
obj-$(CONFIG_PROC_FS) += proc.o
+# Build PCI Express stuff if needed
+obj-$(CONFIG_PCIEPORTBUS) += pcie/
+
obj-$(CONFIG_HOTPLUG) += hotplug.o
# Build the PCI Hotplug drivers if we were asked to
@@ -40,7 +43,3 @@ endif
ifeq ($(CONFIG_PCI_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
endif
-
-# Build PCI Express stuff if needed
-obj-$(CONFIG_PCIEPORTBUS) += pcie/
-
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index c12c5046e2fa..14631ac11bc7 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -249,11 +249,11 @@ static loff_t jsf_lseek(struct file * file, loff_t offset, int orig)
/*
* OS SIMM Cannot be read in other size but a 32bits word.
*/
-static ssize_t jsf_read(struct file * file, char * buf,
+static ssize_t jsf_read(struct file * file, char __user * buf,
size_t togo, loff_t *ppos)
{
unsigned long p = *ppos;
- char *tmp = buf;
+ char __user *tmp = buf;
union byte4 {
char s[4];
@@ -305,7 +305,7 @@ static ssize_t jsf_read(struct file * file, char * buf,
return tmp-buf;
}
-static ssize_t jsf_write(struct file * file, const char * buf,
+static ssize_t jsf_write(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{
return -ENOSPC;
@@ -356,10 +356,10 @@ static int jsf_ioctl_erase(unsigned long arg)
* Program a block of flash.
* Very simple because we can do it byte by byte anyway.
*/
-static int jsf_ioctl_program(unsigned long arg)
+static int jsf_ioctl_program(void __user *arg)
{
struct jsflash_program_arg abuf;
- char *uptr;
+ char __user *uptr;
unsigned long p;
unsigned int togo;
union {
@@ -367,13 +367,13 @@ static int jsf_ioctl_program(unsigned long arg)
char s[4];
} b;
- if (copy_from_user(&abuf, (char *)arg, JSFPRGSZ))
+ if (copy_from_user(&abuf, arg, JSFPRGSZ))
return -EFAULT;
p = abuf.off;
togo = abuf.size;
if ((togo & 3) || (p & 3)) return -EINVAL;
- uptr = (char *) (unsigned long) abuf.data;
+ uptr = (char __user *) (unsigned long) abuf.data;
while (togo != 0) {
togo -= 4;
if (copy_from_user(&b.s[0], uptr, 4))
@@ -390,19 +390,20 @@ static int jsf_ioctl(struct inode *inode, struct file *f, unsigned int cmd,
unsigned long arg)
{
int error = -ENOTTY;
+ void __user *argp = (void __user *)arg;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
switch (cmd) {
case JSFLASH_IDENT:
- if (copy_to_user((void *)arg, &jsf0.id, JSFIDSZ))
+ if (copy_to_user(argp, &jsf0.id, JSFIDSZ))
return -EFAULT;
break;
case JSFLASH_ERASE:
error = jsf_ioctl_erase(arg);
break;
case JSFLASH_PROGRAM:
- error = jsf_ioctl_program(arg);
+ error = jsf_ioctl_program(argp);
break;
}
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
index 858cc683f85c..e2d9a7c85427 100644
--- a/drivers/sbus/char/uctrl.c
+++ b/drivers/sbus/char/uctrl.c
@@ -309,7 +309,7 @@ static void uctrl_do_txn(struct uctrl_txn *txn)
}
}
-void uctrl_get_event_status()
+void uctrl_get_event_status(void)
{
struct uctrl_driver *driver = &drv;
struct uctrl_txn txn;
@@ -318,7 +318,7 @@ void uctrl_get_event_status()
txn.opcode = READ_EVENT_STATUS;
txn.inbits = 0;
txn.outbits = 2;
- txn.inbuf = 0;
+ txn.inbuf = NULL;
txn.outbuf = outbits;
uctrl_do_txn(&txn);
@@ -329,7 +329,7 @@ void uctrl_get_event_status()
dprintk(("ev is %x\n", driver->status.event_status));
}
-void uctrl_get_external_status()
+void uctrl_get_external_status(void)
{
struct uctrl_driver *driver = &drv;
struct uctrl_txn txn;
@@ -339,7 +339,7 @@ void uctrl_get_external_status()
txn.opcode = READ_EXTERNAL_STATUS;
txn.inbits = 0;
txn.outbits = 2;
- txn.inbuf = 0;
+ txn.inbuf = NULL;
txn.outbuf = outbits;
uctrl_do_txn(&txn);
@@ -414,7 +414,7 @@ static void __exit ts102_uctrl_cleanup(void)
if (driver->irq)
free_irq(driver->irq, driver);
if (driver->regs)
- driver->regs = 0;
+ driver->regs = NULL;
}
module_init(ts102_uctrl_init);
diff --git a/drivers/sbus/char/vfc.h b/drivers/sbus/char/vfc.h
index a7782e7da42e..8045cd5e7cb3 100644
--- a/drivers/sbus/char/vfc.h
+++ b/drivers/sbus/char/vfc.h
@@ -125,7 +125,7 @@ struct vfc_regs {
struct vfc_dev {
- volatile struct vfc_regs *regs;
+ volatile struct vfc_regs __iomem *regs;
struct vfc_regs *phys_regs;
unsigned int control_reg;
struct semaphore device_lock_sem;
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index 7a103698fa3c..dfdd6be551f3 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -149,7 +149,7 @@ int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev, int instance)
}
printk("Initializing vfc%d\n",instance);
dev->regs = NULL;
- dev->regs = (volatile struct vfc_regs *)
+ dev->regs = (volatile struct vfc_regs __iomem *)
sbus_ioremap(&sdev->resource[0], 0,
sizeof(struct vfc_regs), vfcstr);
dev->which_io = sdev->reg_addrs[0].which_io;
@@ -319,7 +319,7 @@ int vfc_capture_poll(struct vfc_dev *dev)
int timeout = 1000;
while (!timeout--) {
- if (dev->regs->control & VFC_STATUS_CAPTURE)
+ if (sbus_readl(&dev->regs->control) & VFC_STATUS_CAPTURE)
break;
vfc_i2c_delay_no_busy(dev, 100);
}
@@ -718,7 +718,7 @@ static void deinit_vfc_device(struct vfc_dev *dev)
if(dev == NULL)
return;
devfs_remove("vfc/%d", dev->instance);
- sbus_iounmap((unsigned long)dev->regs, sizeof(struct vfc_regs));
+ sbus_iounmap(dev->regs, sizeof(struct vfc_regs));
kfree(dev);
}
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 418fc7b896ac..6252b9ddc01e 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -660,7 +660,12 @@ static int adpt_abort(struct scsi_cmnd * cmd)
msg[2] = 0;
msg[3]= 0;
msg[4] = (u32)cmd;
- if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){
+ if (pHba->host)
+ spin_lock_irq(pHba->host->host_lock);
+ rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER);
+ if (pHba->host)
+ spin_unlock_irq(pHba->host->host_lock);
+ if (rcode != 0) {
if(rcode == -EOPNOTSUPP ){
printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name);
return FAILED;
@@ -697,10 +702,15 @@ static int adpt_device_reset(struct scsi_cmnd* cmd)
msg[2] = 0;
msg[3] = 0;
+ if (pHba->host)
+ spin_lock_irq(pHba->host->host_lock);
old_state = d->state;
d->state |= DPTI_DEV_RESET;
- if( (rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER)) ){
- d->state = old_state;
+ rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
+ d->state = old_state;
+ if (pHba->host)
+ spin_unlock_irq(pHba->host->host_lock);
+ if (rcode != 0) {
if(rcode == -EOPNOTSUPP ){
printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);
return FAILED;
@@ -708,7 +718,6 @@ static int adpt_device_reset(struct scsi_cmnd* cmd)
printk(KERN_INFO"%s: Device reset failed\n",pHba->name);
return FAILED;
} else {
- d->state = old_state;
printk(KERN_INFO"%s: Device reset successful\n",pHba->name);
return SUCCESS;
}
@@ -721,6 +730,7 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd)
{
adpt_hba* pHba;
u32 msg[4];
+ u32 rcode;
pHba = (adpt_hba*)cmd->device->host->hostdata[0];
memset(msg, 0, sizeof(msg));
@@ -729,7 +739,12 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd)
msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid);
msg[2] = 0;
msg[3] = 0;
- if(adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER) ){
+ if (pHba->host)
+ spin_lock_irq(pHba->host->host_lock);
+ rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
+ if (pHba->host)
+ spin_unlock_irq(pHba->host->host_lock);
+ if (rcode != 0) {
printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name);
return FAILED;
} else {
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h
index 8bec0438dc8a..5b0edd1f1921 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.h
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.h
@@ -100,7 +100,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
void ibmvscsi_release_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata,
int max_requests);
-void ibmvscsi_reset_crq_queue(struct crq_queue *queue,
+int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata);
void ibmvscsi_handle_crq(struct viosrp_crq *crq,
diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c
index 1045872b0175..ce15d9e39621 100644
--- a/drivers/scsi/ibmvscsi/iseries_vscsi.c
+++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c
@@ -117,9 +117,10 @@ void ibmvscsi_release_crq_queue(struct crq_queue *queue,
*
* no-op for iSeries
*/
-void ibmvscsi_reset_crq_queue(struct crq_queue *queue,
+int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata)
{
+ return 0;
}
/**
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c
index 8bf5652f1060..75db2f5c545e 100644
--- a/drivers/scsi/ibmvscsi/rpa_vscsi.c
+++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c
@@ -230,6 +230,11 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
rc = plpar_hcall_norets(H_REG_CRQ,
vdev->unit_address,
queue->msg_token, PAGE_SIZE);
+ if (rc == H_Resource)
+ /* maybe kexecing and resource is busy. try a reset */
+ rc = ibmvscsi_reset_crq_queue(queue,
+ hostdata);
+
if (rc == 2) {
/* Adapter is good, but other end is not ready */
printk(KERN_WARNING "ibmvscsi: Partner adapter not ready\n");
@@ -281,7 +286,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
* @hostdata: ibmvscsi_host_data of host
*
*/
-void ibmvscsi_reset_crq_queue(struct crq_queue *queue,
+int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata)
{
int rc;
@@ -309,4 +314,5 @@ void ibmvscsi_reset_crq_queue(struct crq_queue *queue,
printk(KERN_WARNING
"ibmvscsi: couldn't register crq--rc 0x%x\n", rc);
}
+ return rc;
}
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 4fea3e4edaa7..3d8009f55342 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -3368,7 +3368,7 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param,
switch(param) {
case ISCSI_PARAM_MAX_RECV_DLENGTH: {
char *saveptr = conn->data;
- int flags = GFP_KERNEL;
+ gfp_t flags = GFP_KERNEL;
if (conn->data_size >= value) {
conn->max_recv_dlength = value;
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index f9792528e33f..578143e93a6f 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -664,7 +664,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
sg->offset;
} else
buf = cmd->request_buffer;
- memset(cmd->request_buffer, 0, cmd->cmnd[4]);
+ memset(buf, 0, cmd->cmnd[4]);
if (cmd->use_sg) {
struct scatterlist *sg;
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 7096945ea234..7b3efd531297 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2476,17 +2476,9 @@ typedef struct scsi_qla_host {
*/
#define LOOP_TRANSITION(ha) \
(test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || \
- test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags))
-
-#define LOOP_NOT_READY(ha) \
- ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || \
- test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) || \
- test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \
- test_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags)) || \
+ test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \
atomic_read(&ha->loop_state) == LOOP_DOWN)
-#define LOOP_RDY(ha) (!LOOP_NOT_READY(ha))
-
#define TGT_Q(ha, t) (ha->otgt[t])
#define to_qla_host(x) ((scsi_qla_host_t *) (x)->hostdata)
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 2d720121a0d3..c46d2469b85f 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1259,7 +1259,7 @@ qla2x00_configure_hba(scsi_qla_host_t *ha)
rval = qla2x00_get_adapter_id(ha,
&loop_id, &al_pa, &area, &domain, &topo);
if (rval != QLA_SUCCESS) {
- if (LOOP_NOT_READY(ha) || atomic_read(&ha->loop_down_timer) ||
+ if (LOOP_TRANSITION(ha) || atomic_read(&ha->loop_down_timer) ||
(rval == QLA_COMMAND_ERROR && loop_id == 0x7)) {
DEBUG2(printk("%s(%ld) Loop is in a transition state\n",
__func__, ha->host_no));
@@ -1796,7 +1796,7 @@ qla2x00_configure_loop(scsi_qla_host_t *ha)
}
if (rval == QLA_SUCCESS && test_bit(RSCN_UPDATE, &flags)) {
- if (LOOP_NOT_READY(ha)) {
+ if (LOOP_TRANSITION(ha)) {
rval = QLA_FUNCTION_FAILED;
} else {
rval = qla2x00_configure_fabric(ha);
@@ -2369,7 +2369,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
if (qla2x00_is_reserved_id(ha, loop_id))
continue;
- if (atomic_read(&ha->loop_down_timer) || LOOP_NOT_READY(ha))
+ if (atomic_read(&ha->loop_down_timer) || LOOP_TRANSITION(ha))
break;
if (swl != NULL) {
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 09afc0f06bd4..5181d966fecb 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -909,6 +909,21 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
resid = resid_len;
cp->resid = resid;
CMD_RESID_LEN(cp) = resid;
+
+ if (!lscsi_status &&
+ ((unsigned)(cp->request_bufflen - resid) <
+ cp->underflow)) {
+ qla_printk(KERN_INFO, ha,
+ "scsi(%ld:%d:%d:%d): Mid-layer underflow "
+ "detected (%x of %x bytes)...returning "
+ "error status.\n", ha->host_no,
+ cp->device->channel, cp->device->id,
+ cp->device->lun, resid,
+ cp->request_bufflen);
+
+ cp->result = DID_ERROR << 16;
+ break;
+ }
}
cp->result = DID_OK << 16 | lscsi_status;
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 18c5d2523014..c0ae9e965f6f 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -422,10 +422,15 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd)
**/
static void scsi_eh_done(struct scsi_cmnd *scmd)
{
+ struct completion *eh_action;
+
SCSI_LOG_ERROR_RECOVERY(3,
printk("%s scmd: %p result: %x\n",
__FUNCTION__, scmd, scmd->result));
- complete(scmd->device->host->eh_action);
+
+ eh_action = scmd->device->host->eh_action;
+ if (eh_action)
+ complete(eh_action);
}
/**
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index ce9d73a292e2..dc249cb970ea 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1085,6 +1085,26 @@ static void scsi_generic_done(struct scsi_cmnd *cmd)
scsi_io_completion(cmd, cmd->result == 0 ? cmd->bufflen : 0, 0);
}
+void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd, int retries)
+{
+ struct request *req = cmd->request;
+
+ BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd));
+ memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
+ cmd->cmd_len = req->cmd_len;
+ if (!req->data_len)
+ cmd->sc_data_direction = DMA_NONE;
+ else if (rq_data_dir(req) == WRITE)
+ cmd->sc_data_direction = DMA_TO_DEVICE;
+ else
+ cmd->sc_data_direction = DMA_FROM_DEVICE;
+
+ cmd->transfersize = req->data_len;
+ cmd->allowed = retries;
+ cmd->timeout_per_command = req->timeout;
+}
+EXPORT_SYMBOL_GPL(scsi_setup_blk_pc_cmnd);
+
static int scsi_prep_fn(struct request_queue *q, struct request *req)
{
struct scsi_device *sdev = q->queuedata;
@@ -1220,18 +1240,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
goto kill;
}
} else {
- memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
- cmd->cmd_len = req->cmd_len;
- if (rq_data_dir(req) == WRITE)
- cmd->sc_data_direction = DMA_TO_DEVICE;
- else if (req->data_len)
- cmd->sc_data_direction = DMA_FROM_DEVICE;
- else
- cmd->sc_data_direction = DMA_NONE;
-
- cmd->transfersize = req->data_len;
- cmd->allowed = 3;
- cmd->timeout_per_command = req->timeout;
+ scsi_setup_blk_pc_cmnd(cmd, 3);
cmd->done = scsi_generic_done;
}
}
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 49fd18c1a9c6..e08462d50c97 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -249,7 +249,7 @@ static inline struct list_head *skb_to_lh(struct sk_buff *skb)
}
static void*
-mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data)
+mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data)
{
struct mempool_zone *zone = pool_data;
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 8613a1317712..03fcbab30033 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -245,24 +245,10 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
* SG_IO from block layer already setup, just copy cdb basically
*/
if (blk_pc_request(rq)) {
- if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd))
- return 0;
-
- memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
- SCpnt->cmd_len = rq->cmd_len;
- if (rq_data_dir(rq) == WRITE)
- SCpnt->sc_data_direction = DMA_TO_DEVICE;
- else if (rq->data_len)
- SCpnt->sc_data_direction = DMA_FROM_DEVICE;
- else
- SCpnt->sc_data_direction = DMA_NONE;
-
- this_count = rq->data_len;
+ scsi_setup_blk_pc_cmnd(SCpnt, SD_PASSTHROUGH_RETRIES);
if (rq->timeout)
timeout = rq->timeout;
- SCpnt->transfersize = rq->data_len;
- SCpnt->allowed = SD_PASSTHROUGH_RETRIES;
goto queue;
}
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index d68cea753bb2..fb4012b5c188 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -320,25 +320,11 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
* these are already setup, just copy cdb basically
*/
if (SCpnt->request->flags & REQ_BLOCK_PC) {
- struct request *rq = SCpnt->request;
+ scsi_setup_blk_pc_cmnd(SCpnt, MAX_RETRIES);
- if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd))
- return 0;
-
- memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
- SCpnt->cmd_len = rq->cmd_len;
- if (!rq->data_len)
- SCpnt->sc_data_direction = DMA_NONE;
- else if (rq_data_dir(rq) == WRITE)
- SCpnt->sc_data_direction = DMA_TO_DEVICE;
- else
- SCpnt->sc_data_direction = DMA_FROM_DEVICE;
-
- this_count = rq->data_len;
- if (rq->timeout)
- timeout = rq->timeout;
+ if (SCpnt->timeout_per_command)
+ timeout = SCpnt->timeout_per_command;
- SCpnt->transfersize = rq->data_len;
goto queue;
}
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 7ac6ea141fff..dd592f6a2529 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -4194,27 +4194,10 @@ static void st_intr(struct scsi_cmnd *SCpnt)
*/
static int st_init_command(struct scsi_cmnd *SCpnt)
{
- struct request *rq;
-
if (!(SCpnt->request->flags & REQ_BLOCK_PC))
return 0;
- rq = SCpnt->request;
- if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd))
- return 0;
-
- memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
- SCpnt->cmd_len = rq->cmd_len;
-
- if (rq_data_dir(rq) == WRITE)
- SCpnt->sc_data_direction = DMA_TO_DEVICE;
- else if (rq->data_len)
- SCpnt->sc_data_direction = DMA_FROM_DEVICE;
- else
- SCpnt->sc_data_direction = DMA_NONE;
-
- SCpnt->timeout_per_command = rq->timeout;
- SCpnt->transfersize = rq->data_len;
+ scsi_setup_blk_pc_cmnd(SCpnt, 0);
SCpnt->done = st_intr;
return 1;
}
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index a7420cad4547..1564ca203a3e 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -1405,7 +1405,6 @@ static void sym_check_goals(struct sym_hcb *np, struct scsi_target *starget,
goal->iu = 0;
goal->dt = 0;
goal->qas = 0;
- goal->period = 0;
goal->offset = 0;
return;
}
@@ -1465,7 +1464,8 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp
* Many devices implement PPR in a buggy way, so only use it if we
* really want to.
*/
- if (goal->iu || goal->dt || goal->qas || (goal->period < 0xa)) {
+ if (goal->offset &&
+ (goal->iu || goal->dt || goal->qas || (goal->period < 0xa))) {
nego = NS_PPR;
} else if (spi_width(starget) != goal->width) {
nego = NS_WIDE;
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index ed550132db0b..79efaf7d86a3 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -717,6 +717,7 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
* at the source, so we must turn off PIRQ.
*/
pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
+ mb();
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
uhci->hc_inaccessible = 1;
hcd->poll_rh = 0;
@@ -738,6 +739,7 @@ static int uhci_resume(struct usb_hcd *hcd)
* really don't want to keep a stale HCD_FLAG_HW_ACCESSIBLE=0
*/
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+ mb();
if (uhci->rh_state == UHCI_RH_RESET) /* Dead */
return 0;
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 45f3130fadea..a3e44ef1df43 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -893,8 +893,10 @@ static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_
size = ((report->size - 1) >> 3) + 1;
- if (len < size)
+ if (len < size) {
dbg("report %d is too short, (%d < %d)", report->id, len, size);
+ memset(data + len, 0, size - len);
+ }
if (hid->claimed & HID_CLAIMED_HIDDEV)
hiddev_report_event(hid, report);
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 9ff25eb520a6..1220a5004a5c 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -137,6 +137,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
switch (usage->hid & 0xffff) {
case 0xba: map_abs(ABS_RUDDER); break;
case 0xbb: map_abs(ABS_THROTTLE); break;
+ default: goto ignore;
}
break;
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index 2a28ceeaa66a..b293db3c28c3 100644
--- a/drivers/usb/misc/auerswald.c
+++ b/drivers/usb/misc/auerswald.c
@@ -1696,7 +1696,7 @@ static ssize_t auerchar_write (struct file *file, const char __user *buf, size_t
int ret;
wait_queue_t wait;
- dbg ("auerchar_write %d bytes", len);
+ dbg ("auerchar_write %zd bytes", len);
/* Error checking */
if (!ccp)
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index 080db812ca48..2784f0a9d693 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -441,7 +441,7 @@ static int arcfb_ioctl(struct inode *inode, struct file *file,
* the fb. it's inefficient for them to do anything less than 64*8
* writes since we update the lcd in each write() anyway.
*/
-static ssize_t arcfb_write(struct file *file, const char *buf, size_t count,
+static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t count,
loff_t *ppos)
{
/* modded from epson 1355 */
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index c589d23e7f91..a9300f930ef2 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1512,7 +1512,7 @@ static int cyberpro_pci_enable_mmio(struct cfb_info *cfb)
* I/O cycles storing into a reserved memory space at
* physical address 0x3000000
*/
- unsigned char *iop;
+ unsigned char __iomem *iop;
iop = ioremap(0x3000000, 0x5000);
if (iop == NULL) {
@@ -1526,7 +1526,7 @@ static int cyberpro_pci_enable_mmio(struct cfb_info *cfb)
writeb(EXT_BIU_MISC, iop + 0x3ce);
writeb(EXT_BIU_MISC_LIN_ENABLE, iop + 0x3cf);
- iounmap((void *)iop);
+ iounmap(iop);
#else
/*
* Most other machine types are "normal", so
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 7b4cd250bec8..9fc10b9e6f57 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1396,7 +1396,8 @@ static struct platform_driver pxafb_driver = {
int __devinit pxafb_setup(char *options)
{
# ifdef CONFIG_FB_PXA_PARAMETERS
- strlcpy(g_options, options, sizeof(g_options));
+ if (options)
+ strlcpy(g_options, options, sizeof(g_options));
# endif
return 0;
}