aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/base/dd.c12
-rw-r--r--drivers/base/driver.c5
-rw-r--r--drivers/base/platform.c2
-rw-r--r--drivers/base/power/shutdown.c9
-rw-r--r--drivers/block/amiflop.c30
-rw-r--r--drivers/block/ataflop.c27
-rw-r--r--drivers/block/viodasd.c32
-rw-r--r--drivers/cdrom/viocd.c6
-rw-r--r--drivers/char/amiserial.c21
-rw-r--r--drivers/char/drm/Makefile4
-rw-r--r--drivers/char/drm/ati_pcigart.c23
-rw-r--r--drivers/char/drm/drm.h4
-rw-r--r--drivers/char/drm/drmP.h122
-rw-r--r--drivers/char/drm/drm_agpsupport.c133
-rw-r--r--drivers/char/drm/drm_bufs.c49
-rw-r--r--drivers/char/drm/drm_context.c2
-rw-r--r--drivers/char/drm/drm_core.h4
-rw-r--r--drivers/char/drm/drm_drv.c152
-rw-r--r--drivers/char/drm/drm_fops.c317
-rw-r--r--drivers/char/drm/drm_init.c53
-rw-r--r--drivers/char/drm/drm_ioctl.c27
-rw-r--r--drivers/char/drm/drm_lock.c1
-rw-r--r--drivers/char/drm/drm_memory.c8
-rw-r--r--drivers/char/drm/drm_memory_debug.h269
-rw-r--r--drivers/char/drm/drm_os_linux.h1
-rw-r--r--drivers/char/drm/drm_pciids.h12
-rw-r--r--drivers/char/drm/drm_proc.c16
-rw-r--r--drivers/char/drm/drm_stub.c63
-rw-r--r--drivers/char/drm/drm_sysfs.c68
-rw-r--r--drivers/char/drm/i810_dma.c49
-rw-r--r--drivers/char/drm/i810_drv.c60
-rw-r--r--drivers/char/drm/i810_drv.h10
-rw-r--r--drivers/char/drm/i830_dma.c47
-rw-r--r--drivers/char/drm/i830_drv.c57
-rw-r--r--drivers/char/drm/i830_drv.h8
-rw-r--r--drivers/char/drm/i915_dma.c52
-rw-r--r--drivers/char/drm/i915_drm.h6
-rw-r--r--drivers/char/drm/i915_drv.c66
-rw-r--r--drivers/char/drm/i915_drv.h44
-rw-r--r--drivers/char/drm/i915_irq.c48
-rw-r--r--drivers/char/drm/i915_mem.c5
-rw-r--r--drivers/char/drm/mga_dma.c158
-rw-r--r--drivers/char/drm/mga_drv.c58
-rw-r--r--drivers/char/drm/mga_drv.h14
-rw-r--r--drivers/char/drm/mga_state.c26
-rw-r--r--drivers/char/drm/r128_cce.c15
-rw-r--r--drivers/char/drm/r128_drm.h4
-rw-r--r--drivers/char/drm/r128_drv.c48
-rw-r--r--drivers/char/drm/r128_drv.h8
-rw-r--r--drivers/char/drm/r128_irq.c4
-rw-r--r--drivers/char/drm/r128_state.c42
-rw-r--r--drivers/char/drm/r300_cmdbuf.c38
-rw-r--r--drivers/char/drm/r300_reg.h1
-rw-r--r--drivers/char/drm/radeon_cp.c106
-rw-r--r--drivers/char/drm/radeon_drm.h6
-rw-r--r--drivers/char/drm/radeon_drv.c62
-rw-r--r--drivers/char/drm/radeon_drv.h41
-rw-r--r--drivers/char/drm/radeon_state.c246
-rw-r--r--drivers/char/drm/savage_bci.c81
-rw-r--r--drivers/char/drm/savage_drv.c50
-rw-r--r--drivers/char/drm/savage_drv.h29
-rw-r--r--drivers/char/drm/savage_state.c324
-rw-r--r--drivers/char/drm/sis_drm.h25
-rw-r--r--drivers/char/drm/sis_drv.c42
-rw-r--r--drivers/char/drm/sis_drv.h4
-rw-r--r--drivers/char/drm/sis_ds.h7
-rw-r--r--drivers/char/drm/sis_mm.c30
-rw-r--r--drivers/char/drm/tdfx_drv.c42
-rw-r--r--drivers/char/drm/tdfx_drv.h7
-rw-r--r--drivers/char/drm/via_dma.c38
-rw-r--r--drivers/char/drm/via_dmablit.c805
-rw-r--r--drivers/char/drm/via_dmablit.h140
-rw-r--r--drivers/char/drm/via_drm.h60
-rw-r--r--drivers/char/drm/via_drv.c63
-rw-r--r--drivers/char/drm/via_drv.h56
-rw-r--r--drivers/char/drm/via_ds.c9
-rw-r--r--drivers/char/drm/via_irq.c53
-rw-r--r--drivers/char/drm/via_map.c47
-rw-r--r--drivers/char/drm/via_mm.c20
-rw-r--r--drivers/char/drm/via_verifier.c6
-rw-r--r--drivers/char/drm/via_verifier.h4
-rw-r--r--drivers/char/drm/via_video.c7
-rw-r--r--drivers/char/dsp56k.c29
-rw-r--r--drivers/char/esp.c1
-rw-r--r--drivers/char/generic_serial.c1
-rw-r--r--drivers/char/mem.c8
-rw-r--r--drivers/char/riscom8.c1
-rw-r--r--drivers/char/scc.h2
-rw-r--r--drivers/char/serial167.c1
-rw-r--r--drivers/char/specialix.c3
-rw-r--r--drivers/char/synclink.c1
-rw-r--r--drivers/char/viocons.c31
-rw-r--r--drivers/dio/dio-driver.c4
-rw-r--r--drivers/i2c/busses/i2c-pxa.c10
-rw-r--r--drivers/i2c/i2c-core.c20
-rw-r--r--drivers/ide/ide-cd.c14
-rw-r--r--drivers/ide/ide-disk.c22
-rw-r--r--drivers/ide/ide-floppy.c14
-rw-r--r--drivers/ide/ide-io.c34
-rw-r--r--drivers/ide/ide-probe.c2
-rw-r--r--drivers/ide/ide-tape.c18
-rw-r--r--drivers/ide/ide.c31
-rw-r--r--drivers/infiniband/core/cm.c29
-rw-r--r--drivers/infiniband/core/device.c23
-rw-r--r--drivers/infiniband/core/sysfs.c22
-rw-r--r--drivers/infiniband/core/ucm.c23
-rw-r--r--drivers/infiniband/core/uverbs.h5
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c152
-rw-r--r--drivers/infiniband/core/uverbs_main.c8
-rw-r--r--drivers/infiniband/hw/mthca/mthca_av.c10
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c7
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_eq.c28
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c132
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h6
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c31
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c12
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c105
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_verbs.c8
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c10
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c23
-rw-r--r--drivers/input/evdev.c2
-rw-r--r--drivers/input/gameport/gameport.c12
-rw-r--r--drivers/input/input.c55
-rw-r--r--drivers/input/joystick/amijoy.c4
-rw-r--r--drivers/input/mouse/alps.c38
-rw-r--r--drivers/input/mouse/amimouse.c6
-rw-r--r--drivers/input/mouse/logips2pp.c2
-rw-r--r--drivers/input/mouse/psmouse-base.c316
-rw-r--r--drivers/input/mouse/psmouse.h9
-rw-r--r--drivers/input/mouse/synaptics.c2
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h7
-rw-r--r--drivers/input/serio/serio.c12
-rw-r--r--drivers/input/touchscreen/Kconfig13
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/ads7846.c625
-rw-r--r--drivers/macintosh/adb-iop.c2
-rw-r--r--drivers/macintosh/macio-adb.c13
-rw-r--r--drivers/macintosh/macio_asic.c6
-rw-r--r--drivers/macintosh/via-macii.c4
-rw-r--r--drivers/macintosh/via-maciisi.c22
-rw-r--r--drivers/macintosh/via-pmu68k.c4
-rw-r--r--drivers/md/md.c3
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c23
-rw-r--r--drivers/media/video/bttv-gpio.c24
-rw-r--r--drivers/media/video/bttv.h2
-rw-r--r--drivers/mfd/mcp-core.c4
-rw-r--r--drivers/mfd/ucb1x00-core.c27
-rw-r--r--drivers/mmc/mmc_block.c11
-rw-r--r--drivers/mmc/mmc_sysfs.c26
-rw-r--r--drivers/mtd/devices/Kconfig16
-rw-r--r--drivers/mtd/devices/Makefile2
-rw-r--r--drivers/mtd/devices/m25p80.c582
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c629
-rw-r--r--drivers/net/bonding/bond_alb.c4
-rw-r--r--drivers/net/bonding/bonding.h4
-rw-r--r--drivers/net/e100.c32
-rw-r--r--drivers/net/gianfar.c6
-rw-r--r--drivers/net/gianfar_mii.c5
-rw-r--r--drivers/net/hplance.c2
-rw-r--r--drivers/net/iseries_veth.c4
-rw-r--r--drivers/net/mac8390.c31
-rw-r--r--drivers/net/phy/mdio_bus.c2
-rw-r--r--drivers/net/phy/phy.c2
-rw-r--r--drivers/net/sun3lance.c2
-rw-r--r--drivers/net/tulip/uli526x.c6
-rw-r--r--drivers/net/via-velocity.c2
-rw-r--r--drivers/net/wireless/Kconfig2
-rw-r--r--drivers/net/wireless/atmel.c227
-rw-r--r--drivers/pci/pci-driver.c4
-rw-r--r--drivers/pcmcia/ds.c41
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c15
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c19
-rw-r--r--drivers/pcmcia/socket_sysfs.c25
-rw-r--r--drivers/pnp/driver.c4
-rw-r--r--drivers/rapidio/rio-driver.c6
-rw-r--r--drivers/s390/cio/ccwgroup.c16
-rw-r--r--drivers/s390/cio/css.c36
-rw-r--r--drivers/s390/cio/css.h4
-rw-r--r--drivers/s390/cio/device.c50
-rw-r--r--drivers/sbus/char/aurora.c1
-rw-r--r--drivers/scsi/Makefile3
-rw-r--r--drivers/scsi/NCR53C9x.c5
-rw-r--r--drivers/scsi/blz1230.c4
-rw-r--r--drivers/scsi/blz2060.c4
-rw-r--r--drivers/scsi/cyberstorm.c4
-rw-r--r--drivers/scsi/cyberstormII.c4
-rw-r--r--drivers/scsi/fastlane.c4
-rw-r--r--drivers/scsi/oktagon_esp.c2
-rw-r--r--drivers/scsi/scsi_debug.c4
-rw-r--r--drivers/scsi/wd33c93.c4
-rw-r--r--drivers/serial/68328serial.c1
-rw-r--r--drivers/serial/8250.c11
-rw-r--r--drivers/serial/Kconfig34
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/at91_serial.c894
-rw-r--r--drivers/serial/crisv10.c11
-rw-r--r--drivers/serial/pmac_zilog.c23
-rw-r--r--drivers/serial/serial_core.c15
-rw-r--r--drivers/serial/serial_cs.c2
-rw-r--r--drivers/serial/serial_txx9.c11
-rw-r--r--drivers/sh/superhyway/superhyway.c4
-rw-r--r--drivers/spi/Kconfig109
-rw-r--r--drivers/spi/Makefile25
-rw-r--r--drivers/spi/spi.c642
-rw-r--r--drivers/spi/spi_bitbang.c472
-rw-r--r--drivers/spi/spi_butterfly.c423
-rw-r--r--drivers/usb/gadget/ether.c3
-rw-r--r--drivers/usb/gadget/inode.c3
-rw-r--r--drivers/usb/gadget/serial.c3
-rw-r--r--drivers/usb/gadget/zero.c3
-rw-r--r--drivers/usb/input/Kconfig10
-rw-r--r--drivers/usb/input/hid-core.c30
-rw-r--r--drivers/usb/input/hid-input.c179
-rw-r--r--drivers/usb/input/hid.h30
-rw-r--r--drivers/usb/input/pid.c2
-rw-r--r--drivers/usb/input/wacom.c14
-rw-r--r--drivers/usb/serial/bus.c15
-rw-r--r--drivers/usb/serial/pl2303.c2
-rw-r--r--drivers/video/amifb.c36
-rw-r--r--drivers/video/aty/atyfb_base.c2
-rw-r--r--drivers/video/macfb.c15
-rw-r--r--drivers/zorro/proc.c2
-rw-r--r--drivers/zorro/zorro-driver.c4
227 files changed, 9010 insertions, 2752 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 48f446d3c671..283c089537bc 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -44,6 +44,8 @@ source "drivers/char/Kconfig"
44 44
45source "drivers/i2c/Kconfig" 45source "drivers/i2c/Kconfig"
46 46
47source "drivers/spi/Kconfig"
48
47source "drivers/w1/Kconfig" 49source "drivers/w1/Kconfig"
48 50
49source "drivers/hwmon/Kconfig" 51source "drivers/hwmon/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 7fc3f0f08b29..7c45050ecd03 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_FUSION) += message/
41obj-$(CONFIG_IEEE1394) += ieee1394/ 41obj-$(CONFIG_IEEE1394) += ieee1394/
42obj-y += cdrom/ 42obj-y += cdrom/
43obj-$(CONFIG_MTD) += mtd/ 43obj-$(CONFIG_MTD) += mtd/
44obj-$(CONFIG_SPI) += spi/
44obj-$(CONFIG_PCCARD) += pcmcia/ 45obj-$(CONFIG_PCCARD) += pcmcia/
45obj-$(CONFIG_DIO) += dio/ 46obj-$(CONFIG_DIO) += dio/
46obj-$(CONFIG_SBUS) += sbus/ 47obj-$(CONFIG_SBUS) += sbus/
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 2b905016664d..730a9ce0a14a 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -78,7 +78,13 @@ int driver_probe_device(struct device_driver * drv, struct device * dev)
78 pr_debug("%s: Matched Device %s with Driver %s\n", 78 pr_debug("%s: Matched Device %s with Driver %s\n",
79 drv->bus->name, dev->bus_id, drv->name); 79 drv->bus->name, dev->bus_id, drv->name);
80 dev->driver = drv; 80 dev->driver = drv;
81 if (drv->probe) { 81 if (dev->bus->probe) {
82 ret = dev->bus->probe(dev);
83 if (ret) {
84 dev->driver = NULL;
85 goto ProbeFailed;
86 }
87 } else if (drv->probe) {
82 ret = drv->probe(dev); 88 ret = drv->probe(dev);
83 if (ret) { 89 if (ret) {
84 dev->driver = NULL; 90 dev->driver = NULL;
@@ -203,7 +209,9 @@ static void __device_release_driver(struct device * dev)
203 sysfs_remove_link(&dev->kobj, "driver"); 209 sysfs_remove_link(&dev->kobj, "driver");
204 klist_remove(&dev->knode_driver); 210 klist_remove(&dev->knode_driver);
205 211
206 if (drv->remove) 212 if (dev->bus->remove)
213 dev->bus->remove(dev);
214 else if (drv->remove)
207 drv->remove(dev); 215 drv->remove(dev);
208 dev->driver = NULL; 216 dev->driver = NULL;
209 put_driver(drv); 217 put_driver(drv);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 161f3a390d90..b400314e1c62 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -171,6 +171,11 @@ static void klist_devices_put(struct klist_node *n)
171 */ 171 */
172int driver_register(struct device_driver * drv) 172int driver_register(struct device_driver * drv)
173{ 173{
174 if ((drv->bus->probe && drv->probe) ||
175 (drv->bus->remove && drv->remove) ||
176 (drv->bus->shutdown && drv->shutdown)) {
177 printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name);
178 }
174 klist_init(&drv->klist_devices, klist_devices_get, klist_devices_put); 179 klist_init(&drv->klist_devices, klist_devices_get, klist_devices_put);
175 init_completion(&drv->unloaded); 180 init_completion(&drv->unloaded);
176 return bus_add_driver(drv); 181 return bus_add_driver(drv);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 0f81731bdfa8..461554a02517 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -327,7 +327,7 @@ EXPORT_SYMBOL_GPL(platform_device_register);
327 * @pdev: platform device we're unregistering 327 * @pdev: platform device we're unregistering
328 * 328 *
329 * Unregistration is done in 2 steps. Fisrt we release all resources 329 * Unregistration is done in 2 steps. Fisrt we release all resources
330 * and remove it from the sybsystem, then we drop reference count by 330 * and remove it from the subsystem, then we drop reference count by
331 * calling platform_device_put(). 331 * calling platform_device_put().
332 */ 332 */
333void platform_device_unregister(struct platform_device * pdev) 333void platform_device_unregister(struct platform_device * pdev)
diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c
index f50a08be424b..c2475f3134ea 100644
--- a/drivers/base/power/shutdown.c
+++ b/drivers/base/power/shutdown.c
@@ -35,12 +35,15 @@ extern int sysdev_shutdown(void);
35 */ 35 */
36void device_shutdown(void) 36void device_shutdown(void)
37{ 37{
38 struct device * dev; 38 struct device * dev, *devn;
39 39
40 down_write(&devices_subsys.rwsem); 40 down_write(&devices_subsys.rwsem);
41 list_for_each_entry_reverse(dev, &devices_subsys.kset.list, 41 list_for_each_entry_safe_reverse(dev, devn, &devices_subsys.kset.list,
42 kobj.entry) { 42 kobj.entry) {
43 if (dev->driver && dev->driver->shutdown) { 43 if (dev->bus && dev->bus->shutdown) {
44 dev_dbg(dev, "shutdown\n");
45 dev->bus->shutdown(dev);
46 } else if (dev->driver && dev->driver->shutdown) {
44 dev_dbg(dev, "shutdown\n"); 47 dev_dbg(dev, "shutdown\n");
45 dev->driver->shutdown(dev); 48 dev->driver->shutdown(dev);
46 } 49 }
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 3c679d30b698..b6e290956214 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -194,6 +194,8 @@ static DECLARE_WAIT_QUEUE_HEAD(ms_wait);
194 */ 194 */
195#define MAX_ERRORS 12 195#define MAX_ERRORS 12
196 196
197#define custom amiga_custom
198
197/* Prevent "aliased" accesses. */ 199/* Prevent "aliased" accesses. */
198static int fd_ref[4] = { 0,0,0,0 }; 200static int fd_ref[4] = { 0,0,0,0 };
199static int fd_device[4] = { 0, 0, 0, 0 }; 201static int fd_device[4] = { 0, 0, 0, 0 };
@@ -1439,6 +1441,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
1439{ 1441{
1440 int drive = iminor(inode) & 3; 1442 int drive = iminor(inode) & 3;
1441 static struct floppy_struct getprm; 1443 static struct floppy_struct getprm;
1444 void __user *argp = (void __user *)param;
1442 1445
1443 switch(cmd){ 1446 switch(cmd){
1444 case FDFMTBEG: 1447 case FDFMTBEG:
@@ -1484,9 +1487,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
1484 getprm.head=unit[drive].type->heads; 1487 getprm.head=unit[drive].type->heads;
1485 getprm.sect=unit[drive].dtype->sects * unit[drive].type->sect_mult; 1488 getprm.sect=unit[drive].dtype->sects * unit[drive].type->sect_mult;
1486 getprm.size=unit[drive].blocks; 1489 getprm.size=unit[drive].blocks;
1487 if (copy_to_user((void *)param, 1490 if (copy_to_user(argp, &getprm, sizeof(struct floppy_struct)))
1488 (void *)&getprm,
1489 sizeof(struct floppy_struct)))
1490 return -EFAULT; 1491 return -EFAULT;
1491 break; 1492 break;
1492 case FDSETPRM: 1493 case FDSETPRM:
@@ -1498,8 +1499,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
1498 break; 1499 break;
1499#ifdef RAW_IOCTL 1500#ifdef RAW_IOCTL
1500 case IOCTL_RAW_TRACK: 1501 case IOCTL_RAW_TRACK:
1501 if (copy_to_user((void *)param, raw_buf, 1502 if (copy_to_user(argp, raw_buf, unit[drive].type->read_size))
1502 unit[drive].type->read_size))
1503 return -EFAULT; 1503 return -EFAULT;
1504 else 1504 else
1505 return unit[drive].type->read_size; 1505 return unit[drive].type->read_size;
@@ -1654,12 +1654,6 @@ static struct block_device_operations floppy_fops = {
1654 .media_changed = amiga_floppy_change, 1654 .media_changed = amiga_floppy_change,
1655}; 1655};
1656 1656
1657void __init amiga_floppy_setup (char *str, int *ints)
1658{
1659 printk (KERN_INFO "amiflop: Setting default df0 to %x\n", ints[1]);
1660 fd_def_df0 = ints[1];
1661}
1662
1663static int __init fd_probe_drives(void) 1657static int __init fd_probe_drives(void)
1664{ 1658{
1665 int drive,drives,nomem; 1659 int drive,drives,nomem;
@@ -1845,4 +1839,18 @@ void cleanup_module(void)
1845 unregister_blkdev(FLOPPY_MAJOR, "fd"); 1839 unregister_blkdev(FLOPPY_MAJOR, "fd");
1846} 1840}
1847#endif 1841#endif
1842
1843#else
1844static int __init amiga_floppy_setup (char *str)
1845{
1846 int n;
1847 if (!MACH_IS_AMIGA)
1848 return 0;
1849 if (!get_option(&str, &n))
1850 return 0;
1851 printk (KERN_INFO "amiflop: Setting default df0 to %x\n", n);
1852 fd_def_df0 = n;
1853}
1854
1855__setup("floppy=", amiga_floppy_setup);
1848#endif 1856#endif
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 3aa68a5447d6..f8ce235ccfc3 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -1361,7 +1361,7 @@ static int floppy_revalidate(struct gendisk *disk)
1361 formats, for 'permanent user-defined' parameter: 1361 formats, for 'permanent user-defined' parameter:
1362 restore default_params[] here if flagged valid! */ 1362 restore default_params[] here if flagged valid! */
1363 if (default_params[drive].blocks == 0) 1363 if (default_params[drive].blocks == 0)
1364 UDT = 0; 1364 UDT = NULL;
1365 else 1365 else
1366 UDT = &default_params[drive]; 1366 UDT = &default_params[drive];
1367 } 1367 }
@@ -1495,6 +1495,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
1495 struct floppy_struct getprm; 1495 struct floppy_struct getprm;
1496 int settype; 1496 int settype;
1497 struct floppy_struct setprm; 1497 struct floppy_struct setprm;
1498 void __user *argp = (void __user *)param;
1498 1499
1499 switch (cmd) { 1500 switch (cmd) {
1500 case FDGETPRM: 1501 case FDGETPRM:
@@ -1521,7 +1522,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
1521 getprm.head = 2; 1522 getprm.head = 2;
1522 getprm.track = dtp->blocks/dtp->spt/2; 1523 getprm.track = dtp->blocks/dtp->spt/2;
1523 getprm.stretch = dtp->stretch; 1524 getprm.stretch = dtp->stretch;
1524 if (copy_to_user((void *)param, &getprm, sizeof(getprm))) 1525 if (copy_to_user(argp, &getprm, sizeof(getprm)))
1525 return -EFAULT; 1526 return -EFAULT;
1526 return 0; 1527 return 0;
1527 } 1528 }
@@ -1540,7 +1541,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
1540 /* get the parameters from user space */ 1541 /* get the parameters from user space */
1541 if (floppy->ref != 1 && floppy->ref != -1) 1542 if (floppy->ref != 1 && floppy->ref != -1)
1542 return -EBUSY; 1543 return -EBUSY;
1543 if (copy_from_user(&setprm, (void *) param, sizeof(setprm))) 1544 if (copy_from_user(&setprm, argp, sizeof(setprm)))
1544 return -EFAULT; 1545 return -EFAULT;
1545 /* 1546 /*
1546 * first of all: check for floppy change and revalidate, 1547 * first of all: check for floppy change and revalidate,
@@ -1647,7 +1648,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
1647 case FDFMTTRK: 1648 case FDFMTTRK:
1648 if (floppy->ref != 1 && floppy->ref != -1) 1649 if (floppy->ref != 1 && floppy->ref != -1)
1649 return -EBUSY; 1650 return -EBUSY;
1650 if (copy_from_user(&fmt_desc, (void *) param, sizeof(fmt_desc))) 1651 if (copy_from_user(&fmt_desc, argp, sizeof(fmt_desc)))
1651 return -EFAULT; 1652 return -EFAULT;
1652 return do_format(drive, type, &fmt_desc); 1653 return do_format(drive, type, &fmt_desc);
1653 case FDCLRPRM: 1654 case FDCLRPRM:
@@ -1950,14 +1951,20 @@ Enomem:
1950 return -ENOMEM; 1951 return -ENOMEM;
1951} 1952}
1952 1953
1953 1954#ifndef MODULE
1954void __init atari_floppy_setup( char *str, int *ints ) 1955static int __init atari_floppy_setup(char *str)
1955{ 1956{
1957 int ints[3 + FD_MAX_UNITS];
1956 int i; 1958 int i;
1959
1960 if (!MACH_IS_ATARI)
1961 return 0;
1962
1963 str = get_options(str, 3 + FD_MAX_UNITS, ints);
1957 1964
1958 if (ints[0] < 1) { 1965 if (ints[0] < 1) {
1959 printk(KERN_ERR "ataflop_setup: no arguments!\n" ); 1966 printk(KERN_ERR "ataflop_setup: no arguments!\n" );
1960 return; 1967 return 0;
1961 } 1968 }
1962 else if (ints[0] > 2+FD_MAX_UNITS) { 1969 else if (ints[0] > 2+FD_MAX_UNITS) {
1963 printk(KERN_ERR "ataflop_setup: too many arguments\n" ); 1970 printk(KERN_ERR "ataflop_setup: too many arguments\n" );
@@ -1977,9 +1984,13 @@ void __init atari_floppy_setup( char *str, int *ints )
1977 else 1984 else
1978 UserSteprate[i-3] = ints[i]; 1985 UserSteprate[i-3] = ints[i];
1979 } 1986 }
1987 return 1;
1980} 1988}
1981 1989
1982static void atari_floppy_exit(void) 1990__setup("floppy=", atari_floppy_setup);
1991#endif
1992
1993static void __exit atari_floppy_exit(void)
1983{ 1994{
1984 int i; 1995 int i;
1985 blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); 1996 blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index d1aaf31bd97e..f63e07bd9f9c 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -293,6 +293,7 @@ static int send_request(struct request *req)
293 u16 viocmd; 293 u16 viocmd;
294 HvLpEvent_Rc hvrc; 294 HvLpEvent_Rc hvrc;
295 struct vioblocklpevent *bevent; 295 struct vioblocklpevent *bevent;
296 struct HvLpEvent *hev;
296 struct scatterlist sg[VIOMAXBLOCKDMA]; 297 struct scatterlist sg[VIOMAXBLOCKDMA];
297 int sgindex; 298 int sgindex;
298 int statindex; 299 int statindex;
@@ -347,22 +348,19 @@ static int send_request(struct request *req)
347 * token so we can match the response up later 348 * token so we can match the response up later
348 */ 349 */
349 memset(bevent, 0, sizeof(struct vioblocklpevent)); 350 memset(bevent, 0, sizeof(struct vioblocklpevent));
350 bevent->event.xFlags.xValid = 1; 351 hev = &bevent->event;
351 bevent->event.xFlags.xFunction = HvLpEvent_Function_Int; 352 hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DO_ACK |
352 bevent->event.xFlags.xAckInd = HvLpEvent_AckInd_DoAck; 353 HV_LP_EVENT_INT;
353 bevent->event.xFlags.xAckType = HvLpEvent_AckType_ImmediateAck; 354 hev->xType = HvLpEvent_Type_VirtualIo;
354 bevent->event.xType = HvLpEvent_Type_VirtualIo; 355 hev->xSubtype = viocmd;
355 bevent->event.xSubtype = viocmd; 356 hev->xSourceLp = HvLpConfig_getLpIndex();
356 bevent->event.xSourceLp = HvLpConfig_getLpIndex(); 357 hev->xTargetLp = viopath_hostLp;
357 bevent->event.xTargetLp = viopath_hostLp; 358 hev->xSizeMinus1 =
358 bevent->event.xSizeMinus1 =
359 offsetof(struct vioblocklpevent, u.rw_data.dma_info) + 359 offsetof(struct vioblocklpevent, u.rw_data.dma_info) +
360 (sizeof(bevent->u.rw_data.dma_info[0]) * nsg) - 1; 360 (sizeof(bevent->u.rw_data.dma_info[0]) * nsg) - 1;
361 bevent->event.xSourceInstanceId = 361 hev->xSourceInstanceId = viopath_sourceinst(viopath_hostLp);
362 viopath_sourceinst(viopath_hostLp); 362 hev->xTargetInstanceId = viopath_targetinst(viopath_hostLp);
363 bevent->event.xTargetInstanceId = 363 hev->xCorrelationToken = (u64)req;
364 viopath_targetinst(viopath_hostLp);
365 bevent->event.xCorrelationToken = (u64)req;
366 bevent->version = VIOVERSION; 364 bevent->version = VIOVERSION;
367 bevent->disk = DEVICE_NO(d); 365 bevent->disk = DEVICE_NO(d);
368 bevent->u.rw_data.offset = start; 366 bevent->u.rw_data.offset = start;
@@ -649,10 +647,10 @@ static void handle_block_event(struct HvLpEvent *event)
649 /* Notification that a partition went away! */ 647 /* Notification that a partition went away! */
650 return; 648 return;
651 /* First, we should NEVER get an int here...only acks */ 649 /* First, we should NEVER get an int here...only acks */
652 if (event->xFlags.xFunction == HvLpEvent_Function_Int) { 650 if (hvlpevent_is_int(event)) {
653 printk(VIOD_KERN_WARNING 651 printk(VIOD_KERN_WARNING
654 "Yikes! got an int in viodasd event handler!\n"); 652 "Yikes! got an int in viodasd event handler!\n");
655 if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) { 653 if (hvlpevent_need_ack(event)) {
656 event->xRc = HvLpEvent_Rc_InvalidSubtype; 654 event->xRc = HvLpEvent_Rc_InvalidSubtype;
657 HvCallEvent_ackLpEvent(event); 655 HvCallEvent_ackLpEvent(event);
658 } 656 }
@@ -695,7 +693,7 @@ static void handle_block_event(struct HvLpEvent *event)
695 693
696 default: 694 default:
697 printk(VIOD_KERN_WARNING "invalid subtype!"); 695 printk(VIOD_KERN_WARNING "invalid subtype!");
698 if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) { 696 if (hvlpevent_need_ack(event)) {
699 event->xRc = HvLpEvent_Rc_InvalidSubtype; 697 event->xRc = HvLpEvent_Rc_InvalidSubtype;
700 HvCallEvent_ackLpEvent(event); 698 HvCallEvent_ackLpEvent(event);
701 } 699 }
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index b5191780ecca..193446e6a08a 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -542,10 +542,10 @@ static void vio_handle_cd_event(struct HvLpEvent *event)
542 /* Notification that a partition went away! */ 542 /* Notification that a partition went away! */
543 return; 543 return;
544 /* First, we should NEVER get an int here...only acks */ 544 /* First, we should NEVER get an int here...only acks */
545 if (event->xFlags.xFunction == HvLpEvent_Function_Int) { 545 if (hvlpevent_is_int(event)) {
546 printk(VIOCD_KERN_WARNING 546 printk(VIOCD_KERN_WARNING
547 "Yikes! got an int in viocd event handler!\n"); 547 "Yikes! got an int in viocd event handler!\n");
548 if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) { 548 if (hvlpevent_need_ack(event)) {
549 event->xRc = HvLpEvent_Rc_InvalidSubtype; 549 event->xRc = HvLpEvent_Rc_InvalidSubtype;
550 HvCallEvent_ackLpEvent(event); 550 HvCallEvent_ackLpEvent(event);
551 } 551 }
@@ -616,7 +616,7 @@ return_complete:
616 printk(VIOCD_KERN_WARNING 616 printk(VIOCD_KERN_WARNING
617 "message with invalid subtype %0x04X!\n", 617 "message with invalid subtype %0x04X!\n",
618 event->xSubtype & VIOMINOR_SUBTYPE_MASK); 618 event->xSubtype & VIOMINOR_SUBTYPE_MASK);
619 if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) { 619 if (hvlpevent_need_ack(event)) {
620 event->xRc = HvLpEvent_Rc_InvalidSubtype; 620 event->xRc = HvLpEvent_Rc_InvalidSubtype;
621 HvCallEvent_ackLpEvent(event); 621 HvCallEvent_ackLpEvent(event);
622 } 622 }
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 869518e4035f..7ac365b5d9ec 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -99,6 +99,7 @@ static char *serial_version = "4.30";
99#define _INLINE_ inline 99#define _INLINE_ inline
100#endif 100#endif
101 101
102#define custom amiga_custom
102static char *serial_name = "Amiga-builtin serial driver"; 103static char *serial_name = "Amiga-builtin serial driver";
103 104
104static struct tty_driver *serial_driver; 105static struct tty_driver *serial_driver;
@@ -128,7 +129,6 @@ static struct serial_state rs_table[1];
128 * memory if large numbers of serial ports are open. 129 * memory if large numbers of serial ports are open.
129 */ 130 */
130static unsigned char *tmp_buf; 131static unsigned char *tmp_buf;
131static DECLARE_MUTEX(tmp_buf_sem);
132 132
133#include <asm/uaccess.h> 133#include <asm/uaccess.h>
134 134
@@ -1088,7 +1088,7 @@ static void rs_unthrottle(struct tty_struct * tty)
1088 */ 1088 */
1089 1089
1090static int get_serial_info(struct async_struct * info, 1090static int get_serial_info(struct async_struct * info,
1091 struct serial_struct * retinfo) 1091 struct serial_struct __user * retinfo)
1092{ 1092{
1093 struct serial_struct tmp; 1093 struct serial_struct tmp;
1094 struct serial_state *state = info->state; 1094 struct serial_state *state = info->state;
@@ -1112,7 +1112,7 @@ static int get_serial_info(struct async_struct * info,
1112} 1112}
1113 1113
1114static int set_serial_info(struct async_struct * info, 1114static int set_serial_info(struct async_struct * info,
1115 struct serial_struct * new_info) 1115 struct serial_struct __user * new_info)
1116{ 1116{
1117 struct serial_struct new_serial; 1117 struct serial_struct new_serial;
1118 struct serial_state old_state, *state; 1118 struct serial_state old_state, *state;
@@ -1193,7 +1193,7 @@ check_and_exit:
1193 * transmit holding register is empty. This functionality 1193 * transmit holding register is empty. This functionality
1194 * allows an RS485 driver to be written in user space. 1194 * allows an RS485 driver to be written in user space.
1195 */ 1195 */
1196static int get_lsr_info(struct async_struct * info, unsigned int *value) 1196static int get_lsr_info(struct async_struct * info, unsigned int __user *value)
1197{ 1197{
1198 unsigned char status; 1198 unsigned char status;
1199 unsigned int result; 1199 unsigned int result;
@@ -1284,6 +1284,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
1284 struct async_struct * info = (struct async_struct *)tty->driver_data; 1284 struct async_struct * info = (struct async_struct *)tty->driver_data;
1285 struct async_icount cprev, cnow; /* kernel counter temps */ 1285 struct async_icount cprev, cnow; /* kernel counter temps */
1286 struct serial_icounter_struct icount; 1286 struct serial_icounter_struct icount;
1287 void __user *argp = (void __user *)arg;
1287 unsigned long flags; 1288 unsigned long flags;
1288 1289
1289 if (serial_paranoia_check(info, tty->name, "rs_ioctl")) 1290 if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
@@ -1298,19 +1299,17 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
1298 1299
1299 switch (cmd) { 1300 switch (cmd) {
1300 case TIOCGSERIAL: 1301 case TIOCGSERIAL:
1301 return get_serial_info(info, 1302 return get_serial_info(info, argp);
1302 (struct serial_struct *) arg);
1303 case TIOCSSERIAL: 1303 case TIOCSSERIAL:
1304 return set_serial_info(info, 1304 return set_serial_info(info, argp);
1305 (struct serial_struct *) arg);
1306 case TIOCSERCONFIG: 1305 case TIOCSERCONFIG:
1307 return 0; 1306 return 0;
1308 1307
1309 case TIOCSERGETLSR: /* Get line status register */ 1308 case TIOCSERGETLSR: /* Get line status register */
1310 return get_lsr_info(info, (unsigned int *) arg); 1309 return get_lsr_info(info, argp);
1311 1310
1312 case TIOCSERGSTRUCT: 1311 case TIOCSERGSTRUCT:
1313 if (copy_to_user((struct async_struct *) arg, 1312 if (copy_to_user(argp,
1314 info, sizeof(struct async_struct))) 1313 info, sizeof(struct async_struct)))
1315 return -EFAULT; 1314 return -EFAULT;
1316 return 0; 1315 return 0;
@@ -1369,7 +1368,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
1369 icount.brk = cnow.brk; 1368 icount.brk = cnow.brk;
1370 icount.buf_overrun = cnow.buf_overrun; 1369 icount.buf_overrun = cnow.buf_overrun;
1371 1370
1372 if (copy_to_user((void *)arg, &icount, sizeof(icount))) 1371 if (copy_to_user(argp, &icount, sizeof(icount)))
1373 return -EFAULT; 1372 return -EFAULT;
1374 return 0; 1373 return 0;
1375 case TIOCSERGWILD: 1374 case TIOCSERGWILD:
diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
index e41060c76226..9d180c42816c 100644
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -3,7 +3,7 @@
3# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. 3# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
4 4
5drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \ 5drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
6 drm_drv.o drm_fops.o drm_init.o drm_ioctl.o drm_irq.o \ 6 drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \
7 drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ 7 drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
8 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ 8 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
9 drm_sysfs.o 9 drm_sysfs.o
@@ -18,7 +18,7 @@ radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
18ffb-objs := ffb_drv.o ffb_context.o 18ffb-objs := ffb_drv.o ffb_context.o
19sis-objs := sis_drv.o sis_ds.o sis_mm.o 19sis-objs := sis_drv.o sis_ds.o sis_mm.o
20savage-objs := savage_drv.o savage_bci.o savage_state.o 20savage-objs := savage_drv.o savage_bci.o savage_state.o
21via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o 21via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o
22 22
23ifeq ($(CONFIG_COMPAT),y) 23ifeq ($(CONFIG_COMPAT),y)
24drm-objs += drm_ioc32.o 24drm-objs += drm_ioc32.o
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index efff0eec618c..5485382cadec 100644
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -52,7 +52,7 @@
52# define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */ 52# define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */
53# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ 53# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
54 54
55static unsigned long drm_ati_alloc_pcigart_table(void) 55static void *drm_ati_alloc_pcigart_table(void)
56{ 56{
57 unsigned long address; 57 unsigned long address;
58 struct page *page; 58 struct page *page;
@@ -72,27 +72,26 @@ static unsigned long drm_ati_alloc_pcigart_table(void)
72 } 72 }
73 73
74 DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address); 74 DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address);
75 return address; 75 return (void *)address;
76} 76}
77 77
78static void drm_ati_free_pcigart_table(unsigned long address) 78static void drm_ati_free_pcigart_table(void *address)
79{ 79{
80 struct page *page; 80 struct page *page;
81 int i; 81 int i;
82 DRM_DEBUG("%s\n", __FUNCTION__); 82 DRM_DEBUG("%s\n", __FUNCTION__);
83 83
84 page = virt_to_page(address); 84 page = virt_to_page((unsigned long)address);
85 85
86 for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) { 86 for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) {
87 __put_page(page); 87 __put_page(page);
88 ClearPageReserved(page); 88 ClearPageReserved(page);
89 } 89 }
90 90
91 free_pages(address, ATI_PCIGART_TABLE_ORDER); 91 free_pages((unsigned long)address, ATI_PCIGART_TABLE_ORDER);
92} 92}
93 93
94int drm_ati_pcigart_cleanup(drm_device_t * dev, 94int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
95 drm_ati_pcigart_info * gart_info)
96{ 95{
97 drm_sg_mem_t *entry = dev->sg; 96 drm_sg_mem_t *entry = dev->sg;
98 unsigned long pages; 97 unsigned long pages;
@@ -136,10 +135,10 @@ int drm_ati_pcigart_cleanup(drm_device_t * dev,
136 135
137EXPORT_SYMBOL(drm_ati_pcigart_cleanup); 136EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
138 137
139int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info) 138int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
140{ 139{
141 drm_sg_mem_t *entry = dev->sg; 140 drm_sg_mem_t *entry = dev->sg;
142 unsigned long address = 0; 141 void *address = NULL;
143 unsigned long pages; 142 unsigned long pages;
144 u32 *pci_gart, page_base, bus_address = 0; 143 u32 *pci_gart, page_base, bus_address = 0;
145 int i, j, ret = 0; 144 int i, j, ret = 0;
@@ -163,7 +162,7 @@ int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
163 goto done; 162 goto done;
164 } 163 }
165 164
166 bus_address = pci_map_single(dev->pdev, (void *)address, 165 bus_address = pci_map_single(dev->pdev, address,
167 ATI_PCIGART_TABLE_PAGES * 166 ATI_PCIGART_TABLE_PAGES *
168 PAGE_SIZE, PCI_DMA_TODEVICE); 167 PAGE_SIZE, PCI_DMA_TODEVICE);
169 if (bus_address == 0) { 168 if (bus_address == 0) {
@@ -176,7 +175,7 @@ int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
176 address = gart_info->addr; 175 address = gart_info->addr;
177 bus_address = gart_info->bus_addr; 176 bus_address = gart_info->bus_addr;
178 DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n", 177 DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n",
179 bus_address, address); 178 bus_address, (unsigned long)address);
180 } 179 }
181 180
182 pci_gart = (u32 *) address; 181 pci_gart = (u32 *) address;
@@ -195,7 +194,7 @@ int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
195 if (entry->busaddr[i] == 0) { 194 if (entry->busaddr[i] == 0) {
196 DRM_ERROR("unable to map PCIGART pages!\n"); 195 DRM_ERROR("unable to map PCIGART pages!\n");
197 drm_ati_pcigart_cleanup(dev, gart_info); 196 drm_ati_pcigart_cleanup(dev, gart_info);
198 address = 0; 197 address = NULL;
199 bus_address = 0; 198 bus_address = 0;
200 goto done; 199 goto done;
201 } 200 }
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
index 64d6237fdd0b..9da0ddb892b5 100644
--- a/drivers/char/drm/drm.h
+++ b/drivers/char/drm/drm.h
@@ -90,8 +90,8 @@
90#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */ 90#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */
91#define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */ 91#define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */
92 92
93#define _DRM_LOCK_HELD 0x80000000 /**< Hardware lock is held */ 93#define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */
94#define _DRM_LOCK_CONT 0x40000000 /**< Hardware lock is contended */ 94#define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */
95#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD) 95#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD)
96#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT) 96#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT)
97#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) 97#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 3dc3c9d79ae4..54b561e69486 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -144,20 +144,6 @@
144/** \name Backward compatibility section */ 144/** \name Backward compatibility section */
145/*@{*/ 145/*@{*/
146 146
147#ifndef MODULE_LICENSE
148#define MODULE_LICENSE(x)
149#endif
150
151#ifndef preempt_disable
152#define preempt_disable()
153#define preempt_enable()
154#endif
155
156#ifndef pte_offset_map
157#define pte_offset_map pte_offset
158#define pte_unmap(pte)
159#endif
160
161#define DRM_RPR_ARG(vma) vma, 147#define DRM_RPR_ARG(vma) vma,
162 148
163#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) 149#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT)
@@ -286,10 +272,13 @@ typedef int drm_ioctl_t(struct inode *inode, struct file *filp,
286typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, 272typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
287 unsigned long arg); 273 unsigned long arg);
288 274
275#define DRM_AUTH 0x1
276#define DRM_MASTER 0x2
277#define DRM_ROOT_ONLY 0x4
278
289typedef struct drm_ioctl_desc { 279typedef struct drm_ioctl_desc {
290 drm_ioctl_t *func; 280 drm_ioctl_t *func;
291 int auth_needed; 281 int flags;
292 int root_only;
293} drm_ioctl_desc_t; 282} drm_ioctl_desc_t;
294 283
295typedef struct drm_devstate { 284typedef struct drm_devstate {
@@ -384,6 +373,7 @@ typedef struct drm_buf_entry {
384/** File private data */ 373/** File private data */
385typedef struct drm_file { 374typedef struct drm_file {
386 int authenticated; 375 int authenticated;
376 int master;
387 int minor; 377 int minor;
388 pid_t pid; 378 pid_t pid;
389 uid_t uid; 379 uid_t uid;
@@ -532,8 +522,9 @@ typedef struct drm_vbl_sig {
532typedef struct ati_pcigart_info { 522typedef struct ati_pcigart_info {
533 int gart_table_location; 523 int gart_table_location;
534 int is_pcie; 524 int is_pcie;
535 unsigned long addr; 525 void *addr;
536 dma_addr_t bus_addr; 526 dma_addr_t bus_addr;
527 drm_local_map_t mapping;
537} drm_ati_pcigart_info; 528} drm_ati_pcigart_info;
538 529
539/** 530/**
@@ -544,16 +535,14 @@ typedef struct ati_pcigart_info {
544struct drm_device; 535struct drm_device;
545 536
546struct drm_driver { 537struct drm_driver {
547 int (*preinit) (struct drm_device *, unsigned long flags); 538 int (*load) (struct drm_device *, unsigned long flags);
548 void (*prerelease) (struct drm_device *, struct file * filp); 539 int (*firstopen) (struct drm_device *);
549 void (*pretakedown) (struct drm_device *); 540 int (*open) (struct drm_device *, drm_file_t *);
550 int (*postcleanup) (struct drm_device *); 541 void (*preclose) (struct drm_device *, struct file * filp);
551 int (*presetup) (struct drm_device *); 542 void (*postclose) (struct drm_device *, drm_file_t *);
552 int (*postsetup) (struct drm_device *); 543 void (*lastclose) (struct drm_device *);
544 int (*unload) (struct drm_device *);
553 int (*dma_ioctl) (DRM_IOCTL_ARGS); 545 int (*dma_ioctl) (DRM_IOCTL_ARGS);
554 int (*open_helper) (struct drm_device *, drm_file_t *);
555 void (*free_filp_priv) (struct drm_device *, drm_file_t *);
556 void (*release) (struct drm_device *, struct file * filp);
557 void (*dma_ready) (struct drm_device *); 546 void (*dma_ready) (struct drm_device *);
558 int (*dma_quiescent) (struct drm_device *); 547 int (*dma_quiescent) (struct drm_device *);
559 int (*context_ctor) (struct drm_device * dev, int context); 548 int (*context_ctor) (struct drm_device * dev, int context);
@@ -561,8 +550,9 @@ struct drm_driver {
561 int (*kernel_context_switch) (struct drm_device * dev, int old, 550 int (*kernel_context_switch) (struct drm_device * dev, int old,
562 int new); 551 int new);
563 void (*kernel_context_switch_unlock) (struct drm_device * dev, 552 void (*kernel_context_switch_unlock) (struct drm_device * dev,
564 drm_lock_t * lock); 553 drm_lock_t *lock);
565 int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence); 554 int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence);
555 int (*dri_library_name) (struct drm_device *dev, char *buf);
566 556
567 /** 557 /**
568 * Called by \c drm_device_is_agp. Typically used to determine if a 558 * Called by \c drm_device_is_agp. Typically used to determine if a
@@ -579,16 +569,24 @@ struct drm_driver {
579 569
580 /* these have to be filled in */ 570 /* these have to be filled in */
581 571
582 int (*postinit) (struct drm_device *, unsigned long flags); 572 irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
583 irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
584 void (*irq_preinstall) (struct drm_device * dev); 573 void (*irq_preinstall) (struct drm_device * dev);
585 void (*irq_postinstall) (struct drm_device * dev); 574 void (*irq_postinstall) (struct drm_device * dev);
586 void (*irq_uninstall) (struct drm_device * dev); 575 void (*irq_uninstall) (struct drm_device * dev);
587 void (*reclaim_buffers) (struct drm_device * dev, struct file * filp); 576 void (*reclaim_buffers) (struct drm_device * dev, struct file * filp);
577 void (*reclaim_buffers_locked) (struct drm_device *dev,
578 struct file *filp);
588 unsigned long (*get_map_ofs) (drm_map_t * map); 579 unsigned long (*get_map_ofs) (drm_map_t * map);
589 unsigned long (*get_reg_ofs) (struct drm_device * dev); 580 unsigned long (*get_reg_ofs) (struct drm_device * dev);
590 void (*set_version) (struct drm_device * dev, drm_set_version_t * sv); 581 void (*set_version) (struct drm_device * dev, drm_set_version_t * sv);
591 int (*version) (drm_version_t * version); 582
583 int major;
584 int minor;
585 int patchlevel;
586 char *name;
587 char *desc;
588 char *date;
589
592 u32 driver_features; 590 u32 driver_features;
593 int dev_priv_size; 591 int dev_priv_size;
594 drm_ioctl_desc_t *ioctls; 592 drm_ioctl_desc_t *ioctls;
@@ -752,19 +750,43 @@ static inline int drm_core_has_MTRR(struct drm_device *dev)
752{ 750{
753 return drm_core_check_feature(dev, DRIVER_USE_MTRR); 751 return drm_core_check_feature(dev, DRIVER_USE_MTRR);
754} 752}
753
754#define DRM_MTRR_WC MTRR_TYPE_WRCOMB
755
756static inline int drm_mtrr_add(unsigned long offset, unsigned long size,
757 unsigned int flags)
758{
759 return mtrr_add(offset, size, flags, 1);
760}
761
762static inline int drm_mtrr_del(int handle, unsigned long offset,
763 unsigned long size, unsigned int flags)
764{
765 return mtrr_del(handle, offset, size);
766}
767
755#else 768#else
756#define drm_core_has_MTRR(dev) (0) 769#define drm_core_has_MTRR(dev) (0)
770
771#define DRM_MTRR_WC 0
772
773static inline int drm_mtrr_add(unsigned long offset, unsigned long size,
774 unsigned int flags)
775{
776 return 0;
777}
778
779static inline int drm_mtrr_del(int handle, unsigned long offset,
780 unsigned long size, unsigned int flags)
781{
782 return 0;
783}
757#endif 784#endif
758 785
759/******************************************************************/ 786/******************************************************************/
760/** \name Internal function definitions */ 787/** \name Internal function definitions */
761/*@{*/ 788/*@{*/
762 789
763 /* Misc. support (drm_init.h) */
764extern int drm_flags;
765extern void drm_parse_options(char *s);
766extern int drm_cpu_valid(void);
767
768 /* Driver support (drm_drv.h) */ 790 /* Driver support (drm_drv.h) */
769extern int drm_init(struct drm_driver *driver); 791extern int drm_init(struct drm_driver *driver);
770extern void drm_exit(struct drm_driver *driver); 792extern void drm_exit(struct drm_driver *driver);
@@ -772,12 +794,11 @@ extern int drm_ioctl(struct inode *inode, struct file *filp,
772 unsigned int cmd, unsigned long arg); 794 unsigned int cmd, unsigned long arg);
773extern long drm_compat_ioctl(struct file *filp, 795extern long drm_compat_ioctl(struct file *filp,
774 unsigned int cmd, unsigned long arg); 796 unsigned int cmd, unsigned long arg);
775extern int drm_takedown(drm_device_t * dev); 797extern int drm_lastclose(drm_device_t *dev);
776 798
777 /* Device support (drm_fops.h) */ 799 /* Device support (drm_fops.h) */
778extern int drm_open(struct inode *inode, struct file *filp); 800extern int drm_open(struct inode *inode, struct file *filp);
779extern int drm_stub_open(struct inode *inode, struct file *filp); 801extern int drm_stub_open(struct inode *inode, struct file *filp);
780extern int drm_flush(struct file *filp);
781extern int drm_fasync(int fd, struct file *filp, int on); 802extern int drm_fasync(int fd, struct file *filp, int on);
782extern int drm_release(struct inode *inode, struct file *filp); 803extern int drm_release(struct inode *inode, struct file *filp);
783 804
@@ -819,6 +840,8 @@ extern int drm_getstats(struct inode *inode, struct file *filp,
819 unsigned int cmd, unsigned long arg); 840 unsigned int cmd, unsigned long arg);
820extern int drm_setversion(struct inode *inode, struct file *filp, 841extern int drm_setversion(struct inode *inode, struct file *filp,
821 unsigned int cmd, unsigned long arg); 842 unsigned int cmd, unsigned long arg);
843extern int drm_noop(struct inode *inode, struct file *filp,
844 unsigned int cmd, unsigned long arg);
822 845
823 /* Context IOCTL support (drm_context.h) */ 846 /* Context IOCTL support (drm_context.h) */
824extern int drm_resctx(struct inode *inode, struct file *filp, 847extern int drm_resctx(struct inode *inode, struct file *filp,
@@ -857,10 +880,6 @@ extern int drm_getmagic(struct inode *inode, struct file *filp,
857extern int drm_authmagic(struct inode *inode, struct file *filp, 880extern int drm_authmagic(struct inode *inode, struct file *filp,
858 unsigned int cmd, unsigned long arg); 881 unsigned int cmd, unsigned long arg);
859 882
860 /* Placeholder for ioctls past */
861extern int drm_noop(struct inode *inode, struct file *filp,
862 unsigned int cmd, unsigned long arg);
863
864 /* Locking IOCTL support (drm_lock.h) */ 883 /* Locking IOCTL support (drm_lock.h) */
865extern int drm_lock(struct inode *inode, struct file *filp, 884extern int drm_lock(struct inode *inode, struct file *filp,
866 unsigned int cmd, unsigned long arg); 885 unsigned int cmd, unsigned long arg);
@@ -873,6 +892,7 @@ extern int drm_lock_free(drm_device_t * dev,
873 /* Buffer management support (drm_bufs.h) */ 892 /* Buffer management support (drm_bufs.h) */
874extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request); 893extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request);
875extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request); 894extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request);
895extern int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request);
876extern int drm_addmap(drm_device_t * dev, unsigned int offset, 896extern int drm_addmap(drm_device_t * dev, unsigned int offset,
877 unsigned int size, drm_map_type_t type, 897 unsigned int size, drm_map_type_t type,
878 drm_map_flags_t flags, drm_local_map_t ** map_ptr); 898 drm_map_flags_t flags, drm_local_map_t ** map_ptr);
@@ -908,8 +928,8 @@ extern void drm_core_reclaim_buffers(drm_device_t * dev, struct file *filp);
908 /* IRQ support (drm_irq.h) */ 928 /* IRQ support (drm_irq.h) */
909extern int drm_control(struct inode *inode, struct file *filp, 929extern int drm_control(struct inode *inode, struct file *filp,
910 unsigned int cmd, unsigned long arg); 930 unsigned int cmd, unsigned long arg);
911extern int drm_irq_uninstall(drm_device_t * dev);
912extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS); 931extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
932extern int drm_irq_uninstall(drm_device_t * dev);
913extern void drm_driver_irq_preinstall(drm_device_t * dev); 933extern void drm_driver_irq_preinstall(drm_device_t * dev);
914extern void drm_driver_irq_postinstall(drm_device_t * dev); 934extern void drm_driver_irq_postinstall(drm_device_t * dev);
915extern void drm_driver_irq_uninstall(drm_device_t * dev); 935extern void drm_driver_irq_uninstall(drm_device_t * dev);
@@ -933,13 +953,17 @@ extern int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
933extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info); 953extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info);
934extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp, 954extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
935 unsigned int cmd, unsigned long arg); 955 unsigned int cmd, unsigned long arg);
936extern int drm_agp_alloc(struct inode *inode, struct file *filp, 956extern int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request);
957extern int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp,
937 unsigned int cmd, unsigned long arg); 958 unsigned int cmd, unsigned long arg);
938extern int drm_agp_free(struct inode *inode, struct file *filp, 959extern int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request);
960extern int drm_agp_free_ioctl(struct inode *inode, struct file *filp,
939 unsigned int cmd, unsigned long arg); 961 unsigned int cmd, unsigned long arg);
940extern int drm_agp_unbind(struct inode *inode, struct file *filp, 962extern int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request);
963extern int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp,
941 unsigned int cmd, unsigned long arg); 964 unsigned int cmd, unsigned long arg);
942extern int drm_agp_bind(struct inode *inode, struct file *filp, 965extern int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request);
966extern int drm_agp_bind_ioctl(struct inode *inode, struct file *filp,
943 unsigned int cmd, unsigned long arg); 967 unsigned int cmd, unsigned long arg);
944extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, 968extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge,
945 size_t pages, u32 type); 969 size_t pages, u32 type);
@@ -991,10 +1015,8 @@ extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner,
991 char *name); 1015 char *name);
992extern void drm_sysfs_destroy(struct drm_sysfs_class *cs); 1016extern void drm_sysfs_destroy(struct drm_sysfs_class *cs);
993extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, 1017extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
994 dev_t dev, 1018 drm_head_t *head);
995 struct device *device, 1019extern void drm_sysfs_device_remove(struct class_device *class_dev);
996 const char *fmt, ...);
997extern void drm_sysfs_device_remove(dev_t dev);
998 1020
999/* Inline replacements for DRM_IOREMAP macros */ 1021/* Inline replacements for DRM_IOREMAP macros */
1000static __inline__ void drm_core_ioremap(struct drm_map *map, 1022static __inline__ void drm_core_ioremap(struct drm_map *map,
diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c
index 2b6453a9ffce..fabc930c67a2 100644
--- a/drivers/char/drm/drm_agpsupport.c
+++ b/drivers/char/drm/drm_agpsupport.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * \file drm_agpsupport.h 2 * \file drm_agpsupport.c
3 * DRM support for AGP/GART backend 3 * DRM support for AGP/GART backend
4 * 4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com> 5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -91,7 +91,7 @@ int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
91/** 91/**
92 * Acquire the AGP device. 92 * Acquire the AGP device.
93 * 93 *
94 * \param dev DRM device that is to acquire AGP 94 * \param dev DRM device that is to acquire AGP.
95 * \return zero on success or a negative number on failure. 95 * \return zero on success or a negative number on failure.
96 * 96 *
97 * Verifies the AGP device hasn't been acquired before and calls 97 * Verifies the AGP device hasn't been acquired before and calls
@@ -134,7 +134,7 @@ int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
134/** 134/**
135 * Release the AGP device. 135 * Release the AGP device.
136 * 136 *
137 * \param dev DRM device that is to release AGP 137 * \param dev DRM device that is to release AGP.
138 * \return zero on success or a negative number on failure. 138 * \return zero on success or a negative number on failure.
139 * 139 *
140 * Verifies the AGP device has been acquired and calls \c agp_backend_release. 140 * Verifies the AGP device has been acquired and calls \c agp_backend_release.
@@ -147,7 +147,6 @@ int drm_agp_release(drm_device_t * dev)
147 dev->agp->acquired = 0; 147 dev->agp->acquired = 0;
148 return 0; 148 return 0;
149} 149}
150
151EXPORT_SYMBOL(drm_agp_release); 150EXPORT_SYMBOL(drm_agp_release);
152 151
153int drm_agp_release_ioctl(struct inode *inode, struct file *filp, 152int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
@@ -208,30 +207,22 @@ int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
208 * Verifies the AGP device is present and has been acquired, allocates the 207 * Verifies the AGP device is present and has been acquired, allocates the
209 * memory via alloc_agp() and creates a drm_agp_mem entry for it. 208 * memory via alloc_agp() and creates a drm_agp_mem entry for it.
210 */ 209 */
211int drm_agp_alloc(struct inode *inode, struct file *filp, 210int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request)
212 unsigned int cmd, unsigned long arg)
213{ 211{
214 drm_file_t *priv = filp->private_data;
215 drm_device_t *dev = priv->head->dev;
216 drm_agp_buffer_t request;
217 drm_agp_mem_t *entry; 212 drm_agp_mem_t *entry;
218 DRM_AGP_MEM *memory; 213 DRM_AGP_MEM *memory;
219 unsigned long pages; 214 unsigned long pages;
220 u32 type; 215 u32 type;
221 drm_agp_buffer_t __user *argp = (void __user *)arg;
222 216
223 if (!dev->agp || !dev->agp->acquired) 217 if (!dev->agp || !dev->agp->acquired)
224 return -EINVAL; 218 return -EINVAL;
225 if (copy_from_user(&request, argp, sizeof(request)))
226 return -EFAULT;
227 if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS))) 219 if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS)))
228 return -ENOMEM; 220 return -ENOMEM;
229 221
230 memset(entry, 0, sizeof(*entry)); 222 memset(entry, 0, sizeof(*entry));
231 223
232 pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; 224 pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE;
233 type = (u32) request.type; 225 type = (u32) request->type;
234
235 if (!(memory = drm_alloc_agp(dev, pages, type))) { 226 if (!(memory = drm_alloc_agp(dev, pages, type))) {
236 drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); 227 drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
237 return -ENOMEM; 228 return -ENOMEM;
@@ -247,16 +238,39 @@ int drm_agp_alloc(struct inode *inode, struct file *filp,
247 dev->agp->memory->prev = entry; 238 dev->agp->memory->prev = entry;
248 dev->agp->memory = entry; 239 dev->agp->memory = entry;
249 240
250 request.handle = entry->handle; 241 request->handle = entry->handle;
251 request.physical = memory->physical; 242 request->physical = memory->physical;
243
244 return 0;
245}
246EXPORT_SYMBOL(drm_agp_alloc);
247
248int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp,
249 unsigned int cmd, unsigned long arg)
250{
251 drm_file_t *priv = filp->private_data;
252 drm_device_t *dev = priv->head->dev;
253 drm_agp_buffer_t request;
254 drm_agp_buffer_t __user *argp = (void __user *)arg;
255 int err;
256
257 if (copy_from_user(&request, argp, sizeof(request)))
258 return -EFAULT;
259
260 err = drm_agp_alloc(dev, &request);
261 if (err)
262 return err;
252 263
253 if (copy_to_user(argp, &request, sizeof(request))) { 264 if (copy_to_user(argp, &request, sizeof(request))) {
265 drm_agp_mem_t *entry = dev->agp->memory;
266
254 dev->agp->memory = entry->next; 267 dev->agp->memory = entry->next;
255 dev->agp->memory->prev = NULL; 268 dev->agp->memory->prev = NULL;
256 drm_free_agp(memory, pages); 269 drm_free_agp(entry->memory, entry->pages);
257 drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); 270 drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
258 return -EFAULT; 271 return -EFAULT;
259 } 272 }
273
260 return 0; 274 return 0;
261} 275}
262 276
@@ -293,21 +307,14 @@ static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t * dev,
293 * Verifies the AGP device is present and acquired, looks-up the AGP memory 307 * Verifies the AGP device is present and acquired, looks-up the AGP memory
294 * entry and passes it to the unbind_agp() function. 308 * entry and passes it to the unbind_agp() function.
295 */ 309 */
296int drm_agp_unbind(struct inode *inode, struct file *filp, 310int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request)
297 unsigned int cmd, unsigned long arg)
298{ 311{
299 drm_file_t *priv = filp->private_data;
300 drm_device_t *dev = priv->head->dev;
301 drm_agp_binding_t request;
302 drm_agp_mem_t *entry; 312 drm_agp_mem_t *entry;
303 int ret; 313 int ret;
304 314
305 if (!dev->agp || !dev->agp->acquired) 315 if (!dev->agp || !dev->agp->acquired)
306 return -EINVAL; 316 return -EINVAL;
307 if (copy_from_user 317 if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
308 (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
309 return -EFAULT;
310 if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
311 return -EINVAL; 318 return -EINVAL;
312 if (!entry->bound) 319 if (!entry->bound)
313 return -EINVAL; 320 return -EINVAL;
@@ -316,6 +323,21 @@ int drm_agp_unbind(struct inode *inode, struct file *filp,
316 entry->bound = 0; 323 entry->bound = 0;
317 return ret; 324 return ret;
318} 325}
326EXPORT_SYMBOL(drm_agp_unbind);
327
328int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp,
329 unsigned int cmd, unsigned long arg)
330{
331 drm_file_t *priv = filp->private_data;
332 drm_device_t *dev = priv->head->dev;
333 drm_agp_binding_t request;
334
335 if (copy_from_user
336 (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
337 return -EFAULT;
338
339 return drm_agp_unbind(dev, &request);
340}
319 341
320/** 342/**
321 * Bind AGP memory into the GATT (ioctl) 343 * Bind AGP memory into the GATT (ioctl)
@@ -330,26 +352,19 @@ int drm_agp_unbind(struct inode *inode, struct file *filp,
330 * is currently bound into the GATT. Looks-up the AGP memory entry and passes 352 * is currently bound into the GATT. Looks-up the AGP memory entry and passes
331 * it to bind_agp() function. 353 * it to bind_agp() function.
332 */ 354 */
333int drm_agp_bind(struct inode *inode, struct file *filp, 355int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request)
334 unsigned int cmd, unsigned long arg)
335{ 356{
336 drm_file_t *priv = filp->private_data;
337 drm_device_t *dev = priv->head->dev;
338 drm_agp_binding_t request;
339 drm_agp_mem_t *entry; 357 drm_agp_mem_t *entry;
340 int retcode; 358 int retcode;
341 int page; 359 int page;
342 360
343 if (!dev->agp || !dev->agp->acquired) 361 if (!dev->agp || !dev->agp->acquired)
344 return -EINVAL; 362 return -EINVAL;
345 if (copy_from_user 363 if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
346 (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
347 return -EFAULT;
348 if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
349 return -EINVAL; 364 return -EINVAL;
350 if (entry->bound) 365 if (entry->bound)
351 return -EINVAL; 366 return -EINVAL;
352 page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE; 367 page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE;
353 if ((retcode = drm_bind_agp(entry->memory, page))) 368 if ((retcode = drm_bind_agp(entry->memory, page)))
354 return retcode; 369 return retcode;
355 entry->bound = dev->agp->base + (page << PAGE_SHIFT); 370 entry->bound = dev->agp->base + (page << PAGE_SHIFT);
@@ -357,6 +372,21 @@ int drm_agp_bind(struct inode *inode, struct file *filp,
357 dev->agp->base, entry->bound); 372 dev->agp->base, entry->bound);
358 return 0; 373 return 0;
359} 374}
375EXPORT_SYMBOL(drm_agp_bind);
376
377int drm_agp_bind_ioctl(struct inode *inode, struct file *filp,
378 unsigned int cmd, unsigned long arg)
379{
380 drm_file_t *priv = filp->private_data;
381 drm_device_t *dev = priv->head->dev;
382 drm_agp_binding_t request;
383
384 if (copy_from_user
385 (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
386 return -EFAULT;
387
388 return drm_agp_bind(dev, &request);
389}
360 390
361/** 391/**
362 * Free AGP memory (ioctl). 392 * Free AGP memory (ioctl).
@@ -372,20 +402,13 @@ int drm_agp_bind(struct inode *inode, struct file *filp,
372 * unbind_agp(). Frees it via free_agp() as well as the entry itself 402 * unbind_agp(). Frees it via free_agp() as well as the entry itself
373 * and unlinks from the doubly linked list it's inserted in. 403 * and unlinks from the doubly linked list it's inserted in.
374 */ 404 */
375int drm_agp_free(struct inode *inode, struct file *filp, 405int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request)
376 unsigned int cmd, unsigned long arg)
377{ 406{
378 drm_file_t *priv = filp->private_data;
379 drm_device_t *dev = priv->head->dev;
380 drm_agp_buffer_t request;
381 drm_agp_mem_t *entry; 407 drm_agp_mem_t *entry;
382 408
383 if (!dev->agp || !dev->agp->acquired) 409 if (!dev->agp || !dev->agp->acquired)
384 return -EINVAL; 410 return -EINVAL;
385 if (copy_from_user 411 if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
386 (&request, (drm_agp_buffer_t __user *) arg, sizeof(request)))
387 return -EFAULT;
388 if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
389 return -EINVAL; 412 return -EINVAL;
390 if (entry->bound) 413 if (entry->bound)
391 drm_unbind_agp(entry->memory); 414 drm_unbind_agp(entry->memory);
@@ -402,12 +425,30 @@ int drm_agp_free(struct inode *inode, struct file *filp,
402 drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); 425 drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
403 return 0; 426 return 0;
404} 427}
428EXPORT_SYMBOL(drm_agp_free);
429
430int drm_agp_free_ioctl(struct inode *inode, struct file *filp,
431 unsigned int cmd, unsigned long arg)
432{
433 drm_file_t *priv = filp->private_data;
434 drm_device_t *dev = priv->head->dev;
435 drm_agp_buffer_t request;
436
437 if (copy_from_user
438 (&request, (drm_agp_buffer_t __user *) arg, sizeof(request)))
439 return -EFAULT;
440
441 return drm_agp_free(dev, &request);
442}
405 443
406/** 444/**
407 * Initialize the AGP resources. 445 * Initialize the AGP resources.
408 * 446 *
409 * \return pointer to a drm_agp_head structure. 447 * \return pointer to a drm_agp_head structure.
410 * 448 *
449 * Gets the drm_agp_t structure which is made available by the agpgart module
450 * via the inter_module_* functions. Creates and initializes a drm_agp_head
451 * structure.
411 */ 452 */
412drm_agp_head_t *drm_agp_init(drm_device_t * dev) 453drm_agp_head_t *drm_agp_init(drm_device_t * dev)
413{ 454{
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 319bdea8de8a..1db12dcb6802 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -36,22 +36,21 @@
36#include <linux/vmalloc.h> 36#include <linux/vmalloc.h>
37#include "drmP.h" 37#include "drmP.h"
38 38
39unsigned long drm_get_resource_start(drm_device_t * dev, unsigned int resource) 39unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource)
40{ 40{
41 return pci_resource_start(dev->pdev, resource); 41 return pci_resource_start(dev->pdev, resource);
42} 42}
43
44EXPORT_SYMBOL(drm_get_resource_start); 43EXPORT_SYMBOL(drm_get_resource_start);
45 44
46unsigned long drm_get_resource_len(drm_device_t * dev, unsigned int resource) 45unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
47{ 46{
48 return pci_resource_len(dev->pdev, resource); 47 return pci_resource_len(dev->pdev, resource);
49} 48}
50 49
51EXPORT_SYMBOL(drm_get_resource_len); 50EXPORT_SYMBOL(drm_get_resource_len);
52 51
53static drm_map_list_t *drm_find_matching_map(drm_device_t * dev, 52static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
54 drm_local_map_t * map) 53 drm_local_map_t *map)
55{ 54{
56 struct list_head *list; 55 struct list_head *list;
57 56
@@ -74,7 +73,7 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t * dev,
74 73
75#ifdef _LP64 74#ifdef _LP64
76static __inline__ unsigned int HandleID(unsigned long lhandle, 75static __inline__ unsigned int HandleID(unsigned long lhandle,
77 drm_device_t * dev) 76 drm_device_t *dev)
78{ 77{
79 static unsigned int map32_handle = START_RANGE; 78 static unsigned int map32_handle = START_RANGE;
80 unsigned int hash; 79 unsigned int hash;
@@ -155,7 +154,7 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
155 case _DRM_REGISTERS: 154 case _DRM_REGISTERS:
156 case _DRM_FRAME_BUFFER: 155 case _DRM_FRAME_BUFFER:
157#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) 156#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__)
158 if (map->offset + map->size < map->offset || 157 if (map->offset + (map->size-1) < map->offset ||
159 map->offset < virt_to_phys(high_memory)) { 158 map->offset < virt_to_phys(high_memory)) {
160 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 159 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
161 return -EINVAL; 160 return -EINVAL;
@@ -301,6 +300,9 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
301 return -EFAULT; 300 return -EFAULT;
302 } 301 }
303 302
303 if (!(capable(CAP_SYS_ADMIN) || map.type == _DRM_AGP))
304 return -EPERM;
305
304 err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags, 306 err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags,
305 &maplist); 307 &maplist);
306 308
@@ -332,7 +334,7 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
332 * 334 *
333 * \sa drm_addmap 335 * \sa drm_addmap
334 */ 336 */
335int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map) 337int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
336{ 338{
337 struct list_head *list; 339 struct list_head *list;
338 drm_map_list_t *r_list = NULL; 340 drm_map_list_t *r_list = NULL;
@@ -384,10 +386,9 @@ int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map)
384 386
385 return 0; 387 return 0;
386} 388}
387
388EXPORT_SYMBOL(drm_rmmap_locked); 389EXPORT_SYMBOL(drm_rmmap_locked);
389 390
390int drm_rmmap(drm_device_t * dev, drm_local_map_t * map) 391int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
391{ 392{
392 int ret; 393 int ret;
393 394
@@ -397,7 +398,6 @@ int drm_rmmap(drm_device_t * dev, drm_local_map_t * map)
397 398
398 return ret; 399 return ret;
399} 400}
400
401EXPORT_SYMBOL(drm_rmmap); 401EXPORT_SYMBOL(drm_rmmap);
402 402
403/* The rmmap ioctl appears to be unnecessary. All mappings are torn down on 403/* The rmmap ioctl appears to be unnecessary. All mappings are torn down on
@@ -548,7 +548,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
548 DRM_DEBUG("count: %d\n", count); 548 DRM_DEBUG("count: %d\n", count);
549 DRM_DEBUG("order: %d\n", order); 549 DRM_DEBUG("order: %d\n", order);
550 DRM_DEBUG("size: %d\n", size); 550 DRM_DEBUG("size: %d\n", size);
551 DRM_DEBUG("agp_offset: %lu\n", agp_offset); 551 DRM_DEBUG("agp_offset: %lx\n", agp_offset);
552 DRM_DEBUG("alignment: %d\n", alignment); 552 DRM_DEBUG("alignment: %d\n", alignment);
553 DRM_DEBUG("page_order: %d\n", page_order); 553 DRM_DEBUG("page_order: %d\n", page_order);
554 DRM_DEBUG("total: %d\n", total); 554 DRM_DEBUG("total: %d\n", total);
@@ -649,6 +649,8 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
649 } 649 }
650 650
651 dma->buf_count += entry->buf_count; 651 dma->buf_count += entry->buf_count;
652 dma->seg_count += entry->seg_count;
653 dma->page_count += byte_count >> PAGE_SHIFT;
652 dma->byte_count += byte_count; 654 dma->byte_count += byte_count;
653 655
654 DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); 656 DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
@@ -664,7 +666,6 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
664 atomic_dec(&dev->buf_alloc); 666 atomic_dec(&dev->buf_alloc);
665 return 0; 667 return 0;
666} 668}
667
668EXPORT_SYMBOL(drm_addbufs_agp); 669EXPORT_SYMBOL(drm_addbufs_agp);
669#endif /* __OS_HAS_AGP */ 670#endif /* __OS_HAS_AGP */
670 671
@@ -689,9 +690,13 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
689 690
690 if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) 691 if (!drm_core_check_feature(dev, DRIVER_PCI_DMA))
691 return -EINVAL; 692 return -EINVAL;
693
692 if (!dma) 694 if (!dma)
693 return -EINVAL; 695 return -EINVAL;
694 696
697 if (!capable(CAP_SYS_ADMIN))
698 return -EPERM;
699
695 count = request->count; 700 count = request->count;
696 order = drm_order(request->size); 701 order = drm_order(request->size);
697 size = 1 << order; 702 size = 1 << order;
@@ -882,7 +887,6 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
882 return 0; 887 return 0;
883 888
884} 889}
885
886EXPORT_SYMBOL(drm_addbufs_pci); 890EXPORT_SYMBOL(drm_addbufs_pci);
887 891
888static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) 892static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
@@ -908,6 +912,9 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
908 if (!dma) 912 if (!dma)
909 return -EINVAL; 913 return -EINVAL;
910 914
915 if (!capable(CAP_SYS_ADMIN))
916 return -EPERM;
917
911 count = request->count; 918 count = request->count;
912 order = drm_order(request->size); 919 order = drm_order(request->size);
913 size = 1 << order; 920 size = 1 << order;
@@ -1026,6 +1033,8 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
1026 } 1033 }
1027 1034
1028 dma->buf_count += entry->buf_count; 1035 dma->buf_count += entry->buf_count;
1036 dma->seg_count += entry->seg_count;
1037 dma->page_count += byte_count >> PAGE_SHIFT;
1029 dma->byte_count += byte_count; 1038 dma->byte_count += byte_count;
1030 1039
1031 DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); 1040 DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
@@ -1042,7 +1051,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
1042 return 0; 1051 return 0;
1043} 1052}
1044 1053
1045static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) 1054int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
1046{ 1055{
1047 drm_device_dma_t *dma = dev->dma; 1056 drm_device_dma_t *dma = dev->dma;
1048 drm_buf_entry_t *entry; 1057 drm_buf_entry_t *entry;
@@ -1065,6 +1074,9 @@ static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
1065 if (!dma) 1074 if (!dma)
1066 return -EINVAL; 1075 return -EINVAL;
1067 1076
1077 if (!capable(CAP_SYS_ADMIN))
1078 return -EPERM;
1079
1068 count = request->count; 1080 count = request->count;
1069 order = drm_order(request->size); 1081 order = drm_order(request->size);
1070 size = 1 << order; 1082 size = 1 << order;
@@ -1181,6 +1193,8 @@ static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
1181 } 1193 }
1182 1194
1183 dma->buf_count += entry->buf_count; 1195 dma->buf_count += entry->buf_count;
1196 dma->seg_count += entry->seg_count;
1197 dma->page_count += byte_count >> PAGE_SHIFT;
1184 dma->byte_count += byte_count; 1198 dma->byte_count += byte_count;
1185 1199
1186 DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); 1200 DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
@@ -1196,6 +1210,8 @@ static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
1196 atomic_dec(&dev->buf_alloc); 1210 atomic_dec(&dev->buf_alloc);
1197 return 0; 1211 return 0;
1198} 1212}
1213EXPORT_SYMBOL(drm_addbufs_fb);
1214
1199 1215
1200/** 1216/**
1201 * Add buffers for DMA transfers (ioctl). 1217 * Add buffers for DMA transfers (ioctl).
@@ -1577,5 +1593,6 @@ int drm_order(unsigned long size)
1577 1593
1578 return order; 1594 return order;
1579} 1595}
1580
1581EXPORT_SYMBOL(drm_order); 1596EXPORT_SYMBOL(drm_order);
1597
1598
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
index bd958d69a2ac..f84254526949 100644
--- a/drivers/char/drm/drm_context.c
+++ b/drivers/char/drm/drm_context.c
@@ -433,7 +433,7 @@ int drm_addctx(struct inode *inode, struct file *filp,
433 if (ctx.handle != DRM_KERNEL_CONTEXT) { 433 if (ctx.handle != DRM_KERNEL_CONTEXT) {
434 if (dev->driver->context_ctor) 434 if (dev->driver->context_ctor)
435 if (!dev->driver->context_ctor(dev, ctx.handle)) { 435 if (!dev->driver->context_ctor(dev, ctx.handle)) {
436 DRM_DEBUG( "Running out of ctxs or memory.\n"); 436 DRM_DEBUG("Running out of ctxs or memory.\n");
437 return -ENOMEM; 437 return -ENOMEM;
438 } 438 }
439 } 439 }
diff --git a/drivers/char/drm/drm_core.h b/drivers/char/drm/drm_core.h
index cc97bb906dda..f4f9db6c7ed4 100644
--- a/drivers/char/drm/drm_core.h
+++ b/drivers/char/drm/drm_core.h
@@ -24,11 +24,11 @@
24 24
25#define CORE_NAME "drm" 25#define CORE_NAME "drm"
26#define CORE_DESC "DRM shared core routines" 26#define CORE_DESC "DRM shared core routines"
27#define CORE_DATE "20040925" 27#define CORE_DATE "20051102"
28 28
29#define DRM_IF_MAJOR 1 29#define DRM_IF_MAJOR 1
30#define DRM_IF_MINOR 2 30#define DRM_IF_MINOR 2
31 31
32#define CORE_MAJOR 1 32#define CORE_MAJOR 1
33#define CORE_MINOR 0 33#define CORE_MINOR 0
34#define CORE_PATCHLEVEL 0 34#define CORE_PATCHLEVEL 1
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 4dff7554eb08..c4fa5a29582b 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -56,66 +56,66 @@ static int drm_version(struct inode *inode, struct file *filp,
56 56
57/** Ioctl table */ 57/** Ioctl table */
58static drm_ioctl_desc_t drm_ioctls[] = { 58static drm_ioctl_desc_t drm_ioctls[] = {
59 [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0, 0}, 59 [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0},
60 [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0, 0}, 60 [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0},
61 [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0, 0}, 61 [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0},
62 [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, 0, 1}, 62 [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY},
63 [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0, 0}, 63 [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0},
64 [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0, 0}, 64 [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0},
65 [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0, 0}, 65 [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0},
66 [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, 0, 1}, 66 [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, DRM_MASTER|DRM_ROOT_ONLY},
67 67 [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
68 [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, 1, 1}, 68 [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
69 [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, 1, 1}, 69 [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
70 [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, 1, 1}, 70 [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
71 [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, 1, 1}, 71
72 72 [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
73 [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, 1, 1}, 73 [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, DRM_AUTH},
74 [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, 1, 0}, 74
75 75 [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
76 [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, 1, 1}, 76 [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, DRM_AUTH},
77 [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, 1, 0}, 77
78 78 [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
79 [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, 1, 1}, 79 [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
80 [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, 1, 1}, 80 [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
81 [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, 1, 1}, 81 [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, DRM_AUTH},
82 [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, 1, 0}, 82 [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
83 [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, 1, 1}, 83 [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
84 [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, 1, 1}, 84 [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, DRM_AUTH},
85 [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, 1, 0}, 85
86 86 [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
87 [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, 1, 1}, 87 [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
88 [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, 1, 1}, 88
89 89 [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, DRM_AUTH},
90 [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, 1, 0}, 90 [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, DRM_AUTH},
91 [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, 1, 0}, 91
92 92 [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, DRM_AUTH},
93 [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, 1, 0}, 93
94 94 [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
95 [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, 1, 1}, 95 [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
96 [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, 1, 1}, 96 [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, DRM_AUTH},
97 [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, 1, 0}, 97 [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, DRM_AUTH},
98 [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, 1, 0}, 98 [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, DRM_AUTH},
99 [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, 1, 0},
100 /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ 99 /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
100 [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = {NULL, DRM_AUTH},
101 101
102 [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, 1, 1}, 102 [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
103 103
104#if __OS_HAS_AGP 104#if __OS_HAS_AGP
105 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, 1, 1}, 105 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
106 [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, 1, 1}, 106 [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
107 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, 1, 1}, 107 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
108 [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, 1, 0}, 108 [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, DRM_AUTH},
109 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1}, 109 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
110 [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1}, 110 [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
111 [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind, 1, 1}, 111 [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
112 [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind, 1, 1}, 112 [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
113#endif 113#endif
114 114
115 [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, 1, 1}, 115 [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
116 [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, 1, 1}, 116 [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
117 117
118 [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0, 0}, 118 [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0},
119}; 119};
120 120
121#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls ) 121#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls )
@@ -129,7 +129,7 @@ static drm_ioctl_desc_t drm_ioctls[] = {
129 * 129 *
130 * \sa drm_device 130 * \sa drm_device
131 */ 131 */
132int drm_takedown(drm_device_t * dev) 132int drm_lastclose(drm_device_t * dev)
133{ 133{
134 drm_magic_entry_t *pt, *next; 134 drm_magic_entry_t *pt, *next;
135 drm_map_list_t *r_list; 135 drm_map_list_t *r_list;
@@ -138,9 +138,9 @@ int drm_takedown(drm_device_t * dev)
138 138
139 DRM_DEBUG("\n"); 139 DRM_DEBUG("\n");
140 140
141 if (dev->driver->pretakedown) 141 if (dev->driver->lastclose)
142 dev->driver->pretakedown(dev); 142 dev->driver->lastclose(dev);
143 DRM_DEBUG("driver pretakedown completed\n"); 143 DRM_DEBUG("driver lastclose completed\n");
144 144
145 if (dev->unique) { 145 if (dev->unique) {
146 drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER); 146 drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER);
@@ -233,7 +233,7 @@ int drm_takedown(drm_device_t * dev)
233 } 233 }
234 up(&dev->struct_sem); 234 up(&dev->struct_sem);
235 235
236 DRM_DEBUG("takedown completed\n"); 236 DRM_DEBUG("lastclose completed\n");
237 return 0; 237 return 0;
238} 238}
239 239
@@ -281,7 +281,7 @@ EXPORT_SYMBOL(drm_init);
281/** 281/**
282 * Called via cleanup_module() at module unload time. 282 * Called via cleanup_module() at module unload time.
283 * 283 *
284 * Cleans up all DRM device, calling takedown(). 284 * Cleans up all DRM device, calling drm_lastclose().
285 * 285 *
286 * \sa drm_init 286 * \sa drm_init
287 */ 287 */
@@ -294,7 +294,7 @@ static void drm_cleanup(drm_device_t * dev)
294 return; 294 return;
295 } 295 }
296 296
297 drm_takedown(dev); 297 drm_lastclose(dev);
298 298
299 if (dev->maplist) { 299 if (dev->maplist) {
300 drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); 300 drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
@@ -317,8 +317,8 @@ static void drm_cleanup(drm_device_t * dev)
317 dev->agp = NULL; 317 dev->agp = NULL;
318 } 318 }
319 319
320 if (dev->driver->postcleanup) 320 if (dev->driver->unload)
321 dev->driver->postcleanup(dev); 321 dev->driver->unload(dev);
322 322
323 drm_put_head(&dev->primary); 323 drm_put_head(&dev->primary);
324 if (drm_put_dev(dev)) 324 if (drm_put_dev(dev))
@@ -342,12 +342,12 @@ void drm_exit(struct drm_driver *driver)
342 if (head->dev->driver != driver) 342 if (head->dev->driver != driver)
343 continue; 343 continue;
344 dev = head->dev; 344 dev = head->dev;
345 } 345 if (dev) {
346 if (dev) { 346 /* release the pci driver */
347 /* release the pci driver */ 347 if (dev->pdev)
348 if (dev->pdev) 348 pci_dev_put(dev->pdev);
349 pci_dev_put(dev->pdev); 349 drm_cleanup(dev);
350 drm_cleanup(dev); 350 }
351 } 351 }
352 DRM_INFO("Module unloaded\n"); 352 DRM_INFO("Module unloaded\n");
353} 353}
@@ -432,14 +432,17 @@ static int drm_version(struct inode *inode, struct file *filp,
432 drm_device_t *dev = priv->head->dev; 432 drm_device_t *dev = priv->head->dev;
433 drm_version_t __user *argp = (void __user *)arg; 433 drm_version_t __user *argp = (void __user *)arg;
434 drm_version_t version; 434 drm_version_t version;
435 int ret; 435 int len;
436 436
437 if (copy_from_user(&version, argp, sizeof(version))) 437 if (copy_from_user(&version, argp, sizeof(version)))
438 return -EFAULT; 438 return -EFAULT;
439 439
440 /* version is a required function to return the personality module version */ 440 version.version_major = dev->driver->major;
441 if ((ret = dev->driver->version(&version))) 441 version.version_minor = dev->driver->minor;
442 return ret; 442 version.version_patchlevel = dev->driver->patchlevel;
443 DRM_COPY(version.name, dev->driver->name);
444 DRM_COPY(version.date, dev->driver->date);
445 DRM_COPY(version.desc, dev->driver->desc);
443 446
444 if (copy_to_user(argp, &version, sizeof(version))) 447 if (copy_to_user(argp, &version, sizeof(version)))
445 return -EFAULT; 448 return -EFAULT;
@@ -493,8 +496,9 @@ int drm_ioctl(struct inode *inode, struct file *filp,
493 if (!func) { 496 if (!func) {
494 DRM_DEBUG("no function\n"); 497 DRM_DEBUG("no function\n");
495 retcode = -EINVAL; 498 retcode = -EINVAL;
496 } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN)) || 499 } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) ||
497 (ioctl->auth_needed && !priv->authenticated)) { 500 ((ioctl->flags & DRM_AUTH) && !priv->authenticated) ||
501 ((ioctl->flags & DRM_MASTER) && !priv->master)) {
498 retcode = -EACCES; 502 retcode = -EACCES;
499 } else { 503 } else {
500 retcode = func(inode, filp, cmd, arg); 504 retcode = func(inode, filp, cmd, arg);
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index bf0a740122bf..403f44a1bf01 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -35,6 +35,7 @@
35 */ 35 */
36 36
37#include "drmP.h" 37#include "drmP.h"
38#include "drm_sarea.h"
38#include <linux/poll.h> 39#include <linux/poll.h>
39 40
40static int drm_open_helper(struct inode *inode, struct file *filp, 41static int drm_open_helper(struct inode *inode, struct file *filp,
@@ -42,15 +43,21 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
42 43
43static int drm_setup(drm_device_t * dev) 44static int drm_setup(drm_device_t * dev)
44{ 45{
46 drm_local_map_t *map;
45 int i; 47 int i;
46 int ret; 48 int ret;
47 49
48 if (dev->driver->presetup) { 50 if (dev->driver->firstopen) {
49 ret = dev->driver->presetup(dev); 51 ret = dev->driver->firstopen(dev);
50 if (ret != 0) 52 if (ret != 0)
51 return ret; 53 return ret;
52 } 54 }
53 55
56 /* prebuild the SAREA */
57 i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map);
58 if (i != 0)
59 return i;
60
54 atomic_set(&dev->ioctl_count, 0); 61 atomic_set(&dev->ioctl_count, 0);
55 atomic_set(&dev->vma_count, 0); 62 atomic_set(&dev->vma_count, 0);
56 dev->buf_use = 0; 63 dev->buf_use = 0;
@@ -109,8 +116,6 @@ static int drm_setup(drm_device_t * dev)
109 * drm_select_queue fails between the time the interrupt is 116 * drm_select_queue fails between the time the interrupt is
110 * initialized and the time the queues are initialized. 117 * initialized and the time the queues are initialized.
111 */ 118 */
112 if (dev->driver->postsetup)
113 dev->driver->postsetup(dev);
114 119
115 return 0; 120 return 0;
116} 121}
@@ -154,10 +159,168 @@ int drm_open(struct inode *inode, struct file *filp)
154 159
155 return retcode; 160 return retcode;
156} 161}
157
158EXPORT_SYMBOL(drm_open); 162EXPORT_SYMBOL(drm_open);
159 163
160/** 164/**
165 * File \c open operation.
166 *
167 * \param inode device inode.
168 * \param filp file pointer.
169 *
170 * Puts the dev->fops corresponding to the device minor number into
171 * \p filp, call the \c open method, and restore the file operations.
172 */
173int drm_stub_open(struct inode *inode, struct file *filp)
174{
175 drm_device_t *dev = NULL;
176 int minor = iminor(inode);
177 int err = -ENODEV;
178 struct file_operations *old_fops;
179
180 DRM_DEBUG("\n");
181
182 if (!((minor >= 0) && (minor < drm_cards_limit)))
183 return -ENODEV;
184
185 if (!drm_heads[minor])
186 return -ENODEV;
187
188 if (!(dev = drm_heads[minor]->dev))
189 return -ENODEV;
190
191 old_fops = filp->f_op;
192 filp->f_op = fops_get(&dev->driver->fops);
193 if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
194 fops_put(filp->f_op);
195 filp->f_op = fops_get(old_fops);
196 }
197 fops_put(old_fops);
198
199 return err;
200}
201
202/**
203 * Check whether DRI will run on this CPU.
204 *
205 * \return non-zero if the DRI will run on this CPU, or zero otherwise.
206 */
207static int drm_cpu_valid(void)
208{
209#if defined(__i386__)
210 if (boot_cpu_data.x86 == 3)
211 return 0; /* No cmpxchg on a 386 */
212#endif
213#if defined(__sparc__) && !defined(__sparc_v9__)
214 return 0; /* No cmpxchg before v9 sparc. */
215#endif
216 return 1;
217}
218
219/**
220 * Called whenever a process opens /dev/drm.
221 *
222 * \param inode device inode.
223 * \param filp file pointer.
224 * \param dev device.
225 * \return zero on success or a negative number on failure.
226 *
227 * Creates and initializes a drm_file structure for the file private data in \p
228 * filp and add it into the double linked list in \p dev.
229 */
230static int drm_open_helper(struct inode *inode, struct file *filp,
231 drm_device_t * dev)
232{
233 int minor = iminor(inode);
234 drm_file_t *priv;
235 int ret;
236
237 if (filp->f_flags & O_EXCL)
238 return -EBUSY; /* No exclusive opens */
239 if (!drm_cpu_valid())
240 return -EINVAL;
241
242 DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
243
244 priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
245 if (!priv)
246 return -ENOMEM;
247
248 memset(priv, 0, sizeof(*priv));
249 filp->private_data = priv;
250 priv->uid = current->euid;
251 priv->pid = current->pid;
252 priv->minor = minor;
253 priv->head = drm_heads[minor];
254 priv->ioctl_count = 0;
255 /* for compatibility root is always authenticated */
256 priv->authenticated = capable(CAP_SYS_ADMIN);
257 priv->lock_count = 0;
258
259 if (dev->driver->open) {
260 ret = dev->driver->open(dev, priv);
261 if (ret < 0)
262 goto out_free;
263 }
264
265 down(&dev->struct_sem);
266 if (!dev->file_last) {
267 priv->next = NULL;
268 priv->prev = NULL;
269 dev->file_first = priv;
270 dev->file_last = priv;
271 /* first opener automatically becomes master */
272 priv->master = 1;
273 } else {
274 priv->next = NULL;
275 priv->prev = dev->file_last;
276 dev->file_last->next = priv;
277 dev->file_last = priv;
278 }
279 up(&dev->struct_sem);
280
281#ifdef __alpha__
282 /*
283 * Default the hose
284 */
285 if (!dev->hose) {
286 struct pci_dev *pci_dev;
287 pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
288 if (pci_dev) {
289 dev->hose = pci_dev->sysdata;
290 pci_dev_put(pci_dev);
291 }
292 if (!dev->hose) {
293 struct pci_bus *b = pci_bus_b(pci_root_buses.next);
294 if (b)
295 dev->hose = b->sysdata;
296 }
297 }
298#endif
299
300 return 0;
301 out_free:
302 drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
303 filp->private_data = NULL;
304 return ret;
305}
306
307/** No-op. */
308int drm_fasync(int fd, struct file *filp, int on)
309{
310 drm_file_t *priv = filp->private_data;
311 drm_device_t *dev = priv->head->dev;
312 int retcode;
313
314 DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
315 (long)old_encode_dev(priv->head->device));
316 retcode = fasync_helper(fd, filp, on, &dev->buf_async);
317 if (retcode < 0)
318 return retcode;
319 return 0;
320}
321EXPORT_SYMBOL(drm_fasync);
322
323/**
161 * Release file. 324 * Release file.
162 * 325 *
163 * \param inode device inode 326 * \param inode device inode
@@ -167,7 +330,7 @@ EXPORT_SYMBOL(drm_open);
167 * If the hardware lock is held then free it, and take it again for the kernel 330 * If the hardware lock is held then free it, and take it again for the kernel
168 * context since it's necessary to reclaim buffers. Unlink the file private 331 * context since it's necessary to reclaim buffers. Unlink the file private
169 * data from its list and free it. Decreases the open count and if it reaches 332 * data from its list and free it. Decreases the open count and if it reaches
170 * zero calls takedown(). 333 * zero calls drm_lastclose().
171 */ 334 */
172int drm_release(struct inode *inode, struct file *filp) 335int drm_release(struct inode *inode, struct file *filp)
173{ 336{
@@ -180,8 +343,8 @@ int drm_release(struct inode *inode, struct file *filp)
180 343
181 DRM_DEBUG("open_count = %d\n", dev->open_count); 344 DRM_DEBUG("open_count = %d\n", dev->open_count);
182 345
183 if (dev->driver->prerelease) 346 if (dev->driver->preclose)
184 dev->driver->prerelease(dev, filp); 347 dev->driver->preclose(dev, filp);
185 348
186 /* ======================================================== 349 /* ========================================================
187 * Begin inline drm_release 350 * Begin inline drm_release
@@ -197,8 +360,8 @@ int drm_release(struct inode *inode, struct file *filp)
197 DRM_DEBUG("File %p released, freeing lock for context %d\n", 360 DRM_DEBUG("File %p released, freeing lock for context %d\n",
198 filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); 361 filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
199 362
200 if (dev->driver->release) 363 if (dev->driver->reclaim_buffers_locked)
201 dev->driver->release(dev, filp); 364 dev->driver->reclaim_buffers_locked(dev, filp);
202 365
203 drm_lock_free(dev, &dev->lock.hw_lock->lock, 366 drm_lock_free(dev, &dev->lock.hw_lock->lock,
204 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); 367 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
@@ -207,7 +370,7 @@ int drm_release(struct inode *inode, struct file *filp)
207 hardware at this point, possibly 370 hardware at this point, possibly
208 processed via a callback to the X 371 processed via a callback to the X
209 server. */ 372 server. */
210 } else if (dev->driver->release && priv->lock_count 373 } else if (dev->driver->reclaim_buffers_locked && priv->lock_count
211 && dev->lock.hw_lock) { 374 && dev->lock.hw_lock) {
212 /* The lock is required to reclaim buffers */ 375 /* The lock is required to reclaim buffers */
213 DECLARE_WAITQUEUE(entry, current); 376 DECLARE_WAITQUEUE(entry, current);
@@ -237,15 +400,14 @@ int drm_release(struct inode *inode, struct file *filp)
237 __set_current_state(TASK_RUNNING); 400 __set_current_state(TASK_RUNNING);
238 remove_wait_queue(&dev->lock.lock_queue, &entry); 401 remove_wait_queue(&dev->lock.lock_queue, &entry);
239 if (!retcode) { 402 if (!retcode) {
240 if (dev->driver->release) 403 dev->driver->reclaim_buffers_locked(dev, filp);
241 dev->driver->release(dev, filp);
242 drm_lock_free(dev, &dev->lock.hw_lock->lock, 404 drm_lock_free(dev, &dev->lock.hw_lock->lock,
243 DRM_KERNEL_CONTEXT); 405 DRM_KERNEL_CONTEXT);
244 } 406 }
245 } 407 }
246 408
247 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) 409 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) &&
248 && !dev->driver->release) { 410 !dev->driver->reclaim_buffers_locked) {
249 dev->driver->reclaim_buffers(dev, filp); 411 dev->driver->reclaim_buffers(dev, filp);
250 } 412 }
251 413
@@ -292,9 +454,8 @@ int drm_release(struct inode *inode, struct file *filp)
292 } 454 }
293 up(&dev->struct_sem); 455 up(&dev->struct_sem);
294 456
295 if (dev->driver->free_filp_priv) 457 if (dev->driver->postclose)
296 dev->driver->free_filp_priv(dev, priv); 458 dev->driver->postclose(dev, priv);
297
298 drm_free(priv, sizeof(*priv), DRM_MEM_FILES); 459 drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
299 460
300 /* ======================================================== 461 /* ========================================================
@@ -313,7 +474,7 @@ int drm_release(struct inode *inode, struct file *filp)
313 } 474 }
314 spin_unlock(&dev->count_lock); 475 spin_unlock(&dev->count_lock);
315 unlock_kernel(); 476 unlock_kernel();
316 return drm_takedown(dev); 477 return drm_lastclose(dev);
317 } 478 }
318 spin_unlock(&dev->count_lock); 479 spin_unlock(&dev->count_lock);
319 480
@@ -321,129 +482,11 @@ int drm_release(struct inode *inode, struct file *filp)
321 482
322 return retcode; 483 return retcode;
323} 484}
324
325EXPORT_SYMBOL(drm_release); 485EXPORT_SYMBOL(drm_release);
326 486
327/**
328 * Called whenever a process opens /dev/drm.
329 *
330 * \param inode device inode.
331 * \param filp file pointer.
332 * \param dev device.
333 * \return zero on success or a negative number on failure.
334 *
335 * Creates and initializes a drm_file structure for the file private data in \p
336 * filp and add it into the double linked list in \p dev.
337 */
338static int drm_open_helper(struct inode *inode, struct file *filp,
339 drm_device_t * dev)
340{
341 int minor = iminor(inode);
342 drm_file_t *priv;
343 int ret;
344
345 if (filp->f_flags & O_EXCL)
346 return -EBUSY; /* No exclusive opens */
347 if (!drm_cpu_valid())
348 return -EINVAL;
349
350 DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
351
352 priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
353 if (!priv)
354 return -ENOMEM;
355
356 memset(priv, 0, sizeof(*priv));
357 filp->private_data = priv;
358 priv->uid = current->euid;
359 priv->pid = current->pid;
360 priv->minor = minor;
361 priv->head = drm_heads[minor];
362 priv->ioctl_count = 0;
363 priv->authenticated = capable(CAP_SYS_ADMIN);
364 priv->lock_count = 0;
365
366 if (dev->driver->open_helper) {
367 ret = dev->driver->open_helper(dev, priv);
368 if (ret < 0)
369 goto out_free;
370 }
371
372 down(&dev->struct_sem);
373 if (!dev->file_last) {
374 priv->next = NULL;
375 priv->prev = NULL;
376 dev->file_first = priv;
377 dev->file_last = priv;
378 } else {
379 priv->next = NULL;
380 priv->prev = dev->file_last;
381 dev->file_last->next = priv;
382 dev->file_last = priv;
383 }
384 up(&dev->struct_sem);
385
386#ifdef __alpha__
387 /*
388 * Default the hose
389 */
390 if (!dev->hose) {
391 struct pci_dev *pci_dev;
392 pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
393 if (pci_dev) {
394 dev->hose = pci_dev->sysdata;
395 pci_dev_put(pci_dev);
396 }
397 if (!dev->hose) {
398 struct pci_bus *b = pci_bus_b(pci_root_buses.next);
399 if (b)
400 dev->hose = b->sysdata;
401 }
402 }
403#endif
404
405 return 0;
406 out_free:
407 drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
408 filp->private_data = NULL;
409 return ret;
410}
411
412/** No-op. */
413int drm_flush(struct file *filp)
414{
415 drm_file_t *priv = filp->private_data;
416 drm_device_t *dev = priv->head->dev;
417
418 DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
419 current->pid, (long)old_encode_dev(priv->head->device),
420 dev->open_count);
421 return 0;
422}
423
424EXPORT_SYMBOL(drm_flush);
425
426/** No-op. */
427int drm_fasync(int fd, struct file *filp, int on)
428{
429 drm_file_t *priv = filp->private_data;
430 drm_device_t *dev = priv->head->dev;
431 int retcode;
432
433 DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
434 (long)old_encode_dev(priv->head->device));
435 retcode = fasync_helper(fd, filp, on, &dev->buf_async);
436 if (retcode < 0)
437 return retcode;
438 return 0;
439}
440
441EXPORT_SYMBOL(drm_fasync);
442
443/** No-op. */ 487/** No-op. */
444unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) 488unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
445{ 489{
446 return 0; 490 return 0;
447} 491}
448
449EXPORT_SYMBOL(drm_poll); 492EXPORT_SYMBOL(drm_poll);
diff --git a/drivers/char/drm/drm_init.c b/drivers/char/drm/drm_init.c
deleted file mode 100644
index 754b934715c4..000000000000
--- a/drivers/char/drm/drm_init.c
+++ /dev/null
@@ -1,53 +0,0 @@
1/**
2 * \file drm_init.c
3 * Setup/Cleanup for DRM
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/*
10 * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com
11 *
12 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14 * All Rights Reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice (including the next
24 * paragraph) shall be included in all copies or substantial portions of the
25 * Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 * OTHER DEALINGS IN THE SOFTWARE.
34 */
35
36#include "drmP.h"
37
38/**
39 * Check whether DRI will run on this CPU.
40 *
41 * \return non-zero if the DRI will run on this CPU, or zero otherwise.
42 */
43int drm_cpu_valid(void)
44{
45#if defined(__i386__)
46 if (boot_cpu_data.x86 == 3)
47 return 0; /* No cmpxchg on a 386 */
48#endif
49#if defined(__sparc__) && !defined(__sparc_v9__)
50 return 0; /* No cmpxchg before v9 sparc. */
51#endif
52 return 1;
53}
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
index 9b0feba6b063..bcd4e604d3ec 100644
--- a/drivers/char/drm/drm_ioctl.c
+++ b/drivers/char/drm/drm_ioctl.c
@@ -137,17 +137,22 @@ int drm_setunique(struct inode *inode, struct file *filp,
137 137
138static int drm_set_busid(drm_device_t * dev) 138static int drm_set_busid(drm_device_t * dev)
139{ 139{
140 int len;
141
140 if (dev->unique != NULL) 142 if (dev->unique != NULL)
141 return EBUSY; 143 return EBUSY;
142 144
143 dev->unique_len = 20; 145 dev->unique_len = 40;
144 dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER); 146 dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER);
145 if (dev->unique == NULL) 147 if (dev->unique == NULL)
146 return ENOMEM; 148 return ENOMEM;
147 149
148 snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d", 150 len = snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
149 dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func); 151 dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
150 152
153 if (len > dev->unique_len)
154 DRM_ERROR("Unique buffer overflowed\n");
155
151 dev->devname = 156 dev->devname =
152 drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 157 drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len +
153 2, DRM_MEM_DRIVER); 158 2, DRM_MEM_DRIVER);
@@ -239,7 +244,7 @@ int drm_getclient(struct inode *inode, struct file *filp,
239{ 244{
240 drm_file_t *priv = filp->private_data; 245 drm_file_t *priv = filp->private_data;
241 drm_device_t *dev = priv->head->dev; 246 drm_device_t *dev = priv->head->dev;
242 drm_client_t __user *argp = (void __user *)arg; 247 drm_client_t __user *argp = (drm_client_t __user *)arg;
243 drm_client_t client; 248 drm_client_t client;
244 drm_file_t *pt; 249 drm_file_t *pt;
245 int idx; 250 int idx;
@@ -262,7 +267,7 @@ int drm_getclient(struct inode *inode, struct file *filp,
262 client.iocs = pt->ioctl_count; 267 client.iocs = pt->ioctl_count;
263 up(&dev->struct_sem); 268 up(&dev->struct_sem);
264 269
265 if (copy_to_user((drm_client_t __user *) arg, &client, sizeof(client))) 270 if (copy_to_user(argp, &client, sizeof(client)))
266 return -EFAULT; 271 return -EFAULT;
267 return 0; 272 return 0;
268} 273}
@@ -325,17 +330,13 @@ int drm_setversion(DRM_IOCTL_ARGS)
325 drm_set_version_t retv; 330 drm_set_version_t retv;
326 int if_version; 331 int if_version;
327 drm_set_version_t __user *argp = (void __user *)data; 332 drm_set_version_t __user *argp = (void __user *)data;
328 drm_version_t version;
329 333
330 DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv)); 334 DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv));
331 335
332 memset(&version, 0, sizeof(version));
333
334 dev->driver->version(&version);
335 retv.drm_di_major = DRM_IF_MAJOR; 336 retv.drm_di_major = DRM_IF_MAJOR;
336 retv.drm_di_minor = DRM_IF_MINOR; 337 retv.drm_di_minor = DRM_IF_MINOR;
337 retv.drm_dd_major = version.version_major; 338 retv.drm_dd_major = dev->driver->major;
338 retv.drm_dd_minor = version.version_minor; 339 retv.drm_dd_minor = dev->driver->minor;
339 340
340 DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv)); 341 DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv));
341 342
@@ -343,7 +344,7 @@ int drm_setversion(DRM_IOCTL_ARGS)
343 if (sv.drm_di_major != DRM_IF_MAJOR || 344 if (sv.drm_di_major != DRM_IF_MAJOR ||
344 sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR) 345 sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR)
345 return EINVAL; 346 return EINVAL;
346 if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_dd_minor); 347 if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_di_minor);
347 dev->if_version = DRM_MAX(if_version, dev->if_version); 348 dev->if_version = DRM_MAX(if_version, dev->if_version);
348 if (sv.drm_di_minor >= 1) { 349 if (sv.drm_di_minor >= 1) {
349 /* 350 /*
@@ -354,9 +355,9 @@ int drm_setversion(DRM_IOCTL_ARGS)
354 } 355 }
355 356
356 if (sv.drm_dd_major != -1) { 357 if (sv.drm_dd_major != -1) {
357 if (sv.drm_dd_major != version.version_major || 358 if (sv.drm_dd_major != dev->driver->major ||
358 sv.drm_dd_minor < 0 359 sv.drm_dd_minor < 0
359 || sv.drm_dd_minor > version.version_minor) 360 || sv.drm_dd_minor > dev->driver->minor)
360 return EINVAL; 361 return EINVAL;
361 362
362 if (dev->driver->set_version) 363 if (dev->driver->set_version)
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
index b48a595d54ec..f9e45303498d 100644
--- a/drivers/char/drm/drm_lock.c
+++ b/drivers/char/drm/drm_lock.c
@@ -130,7 +130,6 @@ int drm_lock(struct inode *inode, struct file *filp,
130 /* dev->driver->kernel_context_switch isn't used by any of the x86 130 /* dev->driver->kernel_context_switch isn't used by any of the x86
131 * drivers but is used by the Sparc driver. 131 * drivers but is used by the Sparc driver.
132 */ 132 */
133
134 if (dev->driver->kernel_context_switch && 133 if (dev->driver->kernel_context_switch &&
135 dev->last_context != lock.context) { 134 dev->last_context != lock.context) {
136 dev->driver->kernel_context_switch(dev, dev->last_context, 135 dev->driver->kernel_context_switch(dev, dev->last_context,
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
index abef2acf99f5..8074771e348f 100644
--- a/drivers/char/drm/drm_memory.c
+++ b/drivers/char/drm/drm_memory.c
@@ -145,30 +145,22 @@ DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type)
145 return drm_agp_allocate_memory(dev->agp->bridge, pages, type); 145 return drm_agp_allocate_memory(dev->agp->bridge, pages, type);
146} 146}
147 147
148EXPORT_SYMBOL(drm_alloc_agp);
149
150/** Wrapper around agp_free_memory() */ 148/** Wrapper around agp_free_memory() */
151int drm_free_agp(DRM_AGP_MEM * handle, int pages) 149int drm_free_agp(DRM_AGP_MEM * handle, int pages)
152{ 150{
153 return drm_agp_free_memory(handle) ? 0 : -EINVAL; 151 return drm_agp_free_memory(handle) ? 0 : -EINVAL;
154} 152}
155 153
156EXPORT_SYMBOL(drm_free_agp);
157
158/** Wrapper around agp_bind_memory() */ 154/** Wrapper around agp_bind_memory() */
159int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start) 155int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start)
160{ 156{
161 return drm_agp_bind_memory(handle, start); 157 return drm_agp_bind_memory(handle, start);
162} 158}
163 159
164EXPORT_SYMBOL(drm_bind_agp);
165
166/** Wrapper around agp_unbind_memory() */ 160/** Wrapper around agp_unbind_memory() */
167int drm_unbind_agp(DRM_AGP_MEM * handle) 161int drm_unbind_agp(DRM_AGP_MEM * handle)
168{ 162{
169 return drm_agp_unbind_memory(handle); 163 return drm_agp_unbind_memory(handle);
170} 164}
171
172EXPORT_SYMBOL(drm_unbind_agp);
173#endif /* agp */ 165#endif /* agp */
174#endif /* debug_memory */ 166#endif /* debug_memory */
diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h
index b370aca718d2..e84605fc54af 100644
--- a/drivers/char/drm/drm_memory_debug.h
+++ b/drivers/char/drm/drm_memory_debug.h
@@ -1,5 +1,5 @@
1/** 1/**
2 * \file drm_memory.h 2 * \file drm_memory_debug.h
3 * Memory management wrappers for DRM. 3 * Memory management wrappers for DRM.
4 * 4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com> 5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -43,42 +43,41 @@ typedef struct drm_mem_stats {
43 unsigned long bytes_freed; 43 unsigned long bytes_freed;
44} drm_mem_stats_t; 44} drm_mem_stats_t;
45 45
46static DEFINE_SPINLOCK(DRM(mem_lock)); 46static spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED;
47static unsigned long DRM(ram_available) = 0; /* In pages */ 47static unsigned long drm_ram_available = 0; /* In pages */
48static unsigned long DRM(ram_used) = 0; 48static unsigned long drm_ram_used = 0;
49static drm_mem_stats_t DRM(mem_stats)[] = 49static drm_mem_stats_t drm_mem_stats[] =
50{ 50{
51 [DRM_MEM_DMA] = { 51 [DRM_MEM_DMA] = {"dmabufs"},
52 "dmabufs"},[DRM_MEM_SAREA] = { 52 [DRM_MEM_SAREA] = {"sareas"},
53 "sareas"},[DRM_MEM_DRIVER] = { 53 [DRM_MEM_DRIVER] = {"driver"},
54 "driver"},[DRM_MEM_MAGIC] = { 54 [DRM_MEM_MAGIC] = {"magic"},
55 "magic"},[DRM_MEM_IOCTLS] = { 55 [DRM_MEM_IOCTLS] = {"ioctltab"},
56 "ioctltab"},[DRM_MEM_MAPS] = { 56 [DRM_MEM_MAPS] = {"maplist"},
57 "maplist"},[DRM_MEM_VMAS] = { 57 [DRM_MEM_VMAS] = {"vmalist"},
58 "vmalist"},[DRM_MEM_BUFS] = { 58 [DRM_MEM_BUFS] = {"buflist"},
59 "buflist"},[DRM_MEM_SEGS] = { 59 [DRM_MEM_SEGS] = {"seglist"},
60 "seglist"},[DRM_MEM_PAGES] = { 60 [DRM_MEM_PAGES] = {"pagelist"},
61 "pagelist"},[DRM_MEM_FILES] = { 61 [DRM_MEM_FILES] = {"files"},
62 "files"},[DRM_MEM_QUEUES] = { 62 [DRM_MEM_QUEUES] = {"queues"},
63 "queues"},[DRM_MEM_CMDS] = { 63 [DRM_MEM_CMDS] = {"commands"},
64 "commands"},[DRM_MEM_MAPPINGS] = { 64 [DRM_MEM_MAPPINGS] = {"mappings"},
65 "mappings"},[DRM_MEM_BUFLISTS] = { 65 [DRM_MEM_BUFLISTS] = {"buflists"},
66 "buflists"},[DRM_MEM_AGPLISTS] = { 66 [DRM_MEM_AGPLISTS] = {"agplist"},
67 "agplist"},[DRM_MEM_SGLISTS] = { 67 [DRM_MEM_SGLISTS] = {"sglist"},
68 "sglist"},[DRM_MEM_TOTALAGP] = { 68 [DRM_MEM_TOTALAGP] = {"totalagp"},
69 "totalagp"},[DRM_MEM_BOUNDAGP] = { 69 [DRM_MEM_BOUNDAGP] = {"boundagp"},
70 "boundagp"},[DRM_MEM_CTXBITMAP] = { 70 [DRM_MEM_CTXBITMAP] = {"ctxbitmap"},
71 "ctxbitmap"},[DRM_MEM_CTXLIST] = { 71 [DRM_MEM_CTXLIST] = {"ctxlist"},
72 "ctxlist"},[DRM_MEM_STUB] = { 72 [DRM_MEM_STUB] = {"stub"},
73 "stub"}, { 73 {NULL, 0,} /* Last entry must be null */
74 NULL, 0,} /* Last entry must be null */
75}; 74};
76 75
77void DRM(mem_init) (void) { 76void drm_mem_init (void) {
78 drm_mem_stats_t *mem; 77 drm_mem_stats_t *mem;
79 struct sysinfo si; 78 struct sysinfo si;
80 79
81 for (mem = DRM(mem_stats); mem->name; ++mem) { 80 for (mem = drm_mem_stats; mem->name; ++mem) {
82 mem->succeed_count = 0; 81 mem->succeed_count = 0;
83 mem->free_count = 0; 82 mem->free_count = 0;
84 mem->fail_count = 0; 83 mem->fail_count = 0;
@@ -87,13 +86,13 @@ void DRM(mem_init) (void) {
87 } 86 }
88 87
89 si_meminfo(&si); 88 si_meminfo(&si);
90 DRM(ram_available) = si.totalram; 89 drm_ram_available = si.totalram;
91 DRM(ram_used) = 0; 90 drm_ram_used = 0;
92} 91}
93 92
94/* drm_mem_info is called whenever a process reads /dev/drm/mem. */ 93/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
95 94
96static int DRM(_mem_info) (char *buf, char **start, off_t offset, 95static int drm__mem_info (char *buf, char **start, off_t offset,
97 int request, int *eof, void *data) { 96 int request, int *eof, void *data) {
98 drm_mem_stats_t *pt; 97 drm_mem_stats_t *pt;
99 int len = 0; 98 int len = 0;
@@ -112,11 +111,11 @@ static int DRM(_mem_info) (char *buf, char **start, off_t offset,
112 " | allocs bytes\n\n"); 111 " | allocs bytes\n\n");
113 DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n", 112 DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
114 "system", 0, 0, 0, 113 "system", 0, 0, 0,
115 DRM(ram_available) << (PAGE_SHIFT - 10)); 114 drm_ram_available << (PAGE_SHIFT - 10));
116 DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n", 115 DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
117 "locked", 0, 0, 0, DRM(ram_used) >> 10); 116 "locked", 0, 0, 0, drm_ram_used >> 10);
118 DRM_PROC_PRINT("\n"); 117 DRM_PROC_PRINT("\n");
119 for (pt = DRM(mem_stats); pt->name; pt++) { 118 for (pt = drm_mem_stats; pt->name; pt++) {
120 DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n", 119 DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
121 pt->name, 120 pt->name,
122 pt->succeed_count, 121 pt->succeed_count,
@@ -135,17 +134,17 @@ static int DRM(_mem_info) (char *buf, char **start, off_t offset,
135 return len - offset; 134 return len - offset;
136} 135}
137 136
138int DRM(mem_info) (char *buf, char **start, off_t offset, 137int drm_mem_info (char *buf, char **start, off_t offset,
139 int len, int *eof, void *data) { 138 int len, int *eof, void *data) {
140 int ret; 139 int ret;
141 140
142 spin_lock(&DRM(mem_lock)); 141 spin_lock(&drm_mem_lock);
143 ret = DRM(_mem_info) (buf, start, offset, len, eof, data); 142 ret = drm__mem_info (buf, start, offset, len, eof, data);
144 spin_unlock(&DRM(mem_lock)); 143 spin_unlock(&drm_mem_lock);
145 return ret; 144 return ret;
146} 145}
147 146
148void *DRM(alloc) (size_t size, int area) { 147void *drm_alloc (size_t size, int area) {
149 void *pt; 148 void *pt;
150 149
151 if (!size) { 150 if (!size) {
@@ -154,41 +153,41 @@ void *DRM(alloc) (size_t size, int area) {
154 } 153 }
155 154
156 if (!(pt = kmalloc(size, GFP_KERNEL))) { 155 if (!(pt = kmalloc(size, GFP_KERNEL))) {
157 spin_lock(&DRM(mem_lock)); 156 spin_lock(&drm_mem_lock);
158 ++DRM(mem_stats)[area].fail_count; 157 ++drm_mem_stats[area].fail_count;
159 spin_unlock(&DRM(mem_lock)); 158 spin_unlock(&drm_mem_lock);
160 return NULL; 159 return NULL;
161 } 160 }
162 spin_lock(&DRM(mem_lock)); 161 spin_lock(&drm_mem_lock);
163 ++DRM(mem_stats)[area].succeed_count; 162 ++drm_mem_stats[area].succeed_count;
164 DRM(mem_stats)[area].bytes_allocated += size; 163 drm_mem_stats[area].bytes_allocated += size;
165 spin_unlock(&DRM(mem_lock)); 164 spin_unlock(&drm_mem_lock);
166 return pt; 165 return pt;
167} 166}
168 167
169void *DRM(calloc) (size_t nmemb, size_t size, int area) { 168void *drm_calloc (size_t nmemb, size_t size, int area) {
170 void *addr; 169 void *addr;
171 170
172 addr = DRM(alloc) (nmemb * size, area); 171 addr = drm_alloc (nmemb * size, area);
173 if (addr != NULL) 172 if (addr != NULL)
174 memset((void *)addr, 0, size * nmemb); 173 memset((void *)addr, 0, size * nmemb);
175 174
176 return addr; 175 return addr;
177} 176}
178 177
179void *DRM(realloc) (void *oldpt, size_t oldsize, size_t size, int area) { 178void *drm_realloc (void *oldpt, size_t oldsize, size_t size, int area) {
180 void *pt; 179 void *pt;
181 180
182 if (!(pt = DRM(alloc) (size, area))) 181 if (!(pt = drm_alloc (size, area)))
183 return NULL; 182 return NULL;
184 if (oldpt && oldsize) { 183 if (oldpt && oldsize) {
185 memcpy(pt, oldpt, oldsize); 184 memcpy(pt, oldpt, oldsize);
186 DRM(free) (oldpt, oldsize, area); 185 drm_free (oldpt, oldsize, area);
187 } 186 }
188 return pt; 187 return pt;
189} 188}
190 189
191void DRM(free) (void *pt, size_t size, int area) { 190void drm_free (void *pt, size_t size, int area) {
192 int alloc_count; 191 int alloc_count;
193 int free_count; 192 int free_count;
194 193
@@ -196,43 +195,43 @@ void DRM(free) (void *pt, size_t size, int area) {
196 DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); 195 DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
197 else 196 else
198 kfree(pt); 197 kfree(pt);
199 spin_lock(&DRM(mem_lock)); 198 spin_lock(&drm_mem_lock);
200 DRM(mem_stats)[area].bytes_freed += size; 199 drm_mem_stats[area].bytes_freed += size;
201 free_count = ++DRM(mem_stats)[area].free_count; 200 free_count = ++drm_mem_stats[area].free_count;
202 alloc_count = DRM(mem_stats)[area].succeed_count; 201 alloc_count = drm_mem_stats[area].succeed_count;
203 spin_unlock(&DRM(mem_lock)); 202 spin_unlock(&drm_mem_lock);
204 if (free_count > alloc_count) { 203 if (free_count > alloc_count) {
205 DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n", 204 DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
206 free_count, alloc_count); 205 free_count, alloc_count);
207 } 206 }
208} 207}
209 208
210unsigned long DRM(alloc_pages) (int order, int area) { 209unsigned long drm_alloc_pages (int order, int area) {
211 unsigned long address; 210 unsigned long address;
212 unsigned long bytes = PAGE_SIZE << order; 211 unsigned long bytes = PAGE_SIZE << order;
213 unsigned long addr; 212 unsigned long addr;
214 unsigned int sz; 213 unsigned int sz;
215 214
216 spin_lock(&DRM(mem_lock)); 215 spin_lock(&drm_mem_lock);
217 if ((DRM(ram_used) >> PAGE_SHIFT) 216 if ((drm_ram_used >> PAGE_SHIFT)
218 > (DRM_RAM_PERCENT * DRM(ram_available)) / 100) { 217 > (DRM_RAM_PERCENT * drm_ram_available) / 100) {
219 spin_unlock(&DRM(mem_lock)); 218 spin_unlock(&drm_mem_lock);
220 return 0; 219 return 0;
221 } 220 }
222 spin_unlock(&DRM(mem_lock)); 221 spin_unlock(&drm_mem_lock);
223 222
224 address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order); 223 address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order);
225 if (!address) { 224 if (!address) {
226 spin_lock(&DRM(mem_lock)); 225 spin_lock(&drm_mem_lock);
227 ++DRM(mem_stats)[area].fail_count; 226 ++drm_mem_stats[area].fail_count;
228 spin_unlock(&DRM(mem_lock)); 227 spin_unlock(&drm_mem_lock);
229 return 0; 228 return 0;
230 } 229 }
231 spin_lock(&DRM(mem_lock)); 230 spin_lock(&drm_mem_lock);
232 ++DRM(mem_stats)[area].succeed_count; 231 ++drm_mem_stats[area].succeed_count;
233 DRM(mem_stats)[area].bytes_allocated += bytes; 232 drm_mem_stats[area].bytes_allocated += bytes;
234 DRM(ram_used) += bytes; 233 drm_ram_used += bytes;
235 spin_unlock(&DRM(mem_lock)); 234 spin_unlock(&drm_mem_lock);
236 235
237 /* Zero outside the lock */ 236 /* Zero outside the lock */
238 memset((void *)address, 0, bytes); 237 memset((void *)address, 0, bytes);
@@ -246,7 +245,7 @@ unsigned long DRM(alloc_pages) (int order, int area) {
246 return address; 245 return address;
247} 246}
248 247
249void DRM(free_pages) (unsigned long address, int order, int area) { 248void drm_free_pages (unsigned long address, int order, int area) {
250 unsigned long bytes = PAGE_SIZE << order; 249 unsigned long bytes = PAGE_SIZE << order;
251 int alloc_count; 250 int alloc_count;
252 int free_count; 251 int free_count;
@@ -264,12 +263,12 @@ void DRM(free_pages) (unsigned long address, int order, int area) {
264 free_pages(address, order); 263 free_pages(address, order);
265 } 264 }
266 265
267 spin_lock(&DRM(mem_lock)); 266 spin_lock(&drm_mem_lock);
268 free_count = ++DRM(mem_stats)[area].free_count; 267 free_count = ++drm_mem_stats[area].free_count;
269 alloc_count = DRM(mem_stats)[area].succeed_count; 268 alloc_count = drm_mem_stats[area].succeed_count;
270 DRM(mem_stats)[area].bytes_freed += bytes; 269 drm_mem_stats[area].bytes_freed += bytes;
271 DRM(ram_used) -= bytes; 270 drm_ram_used -= bytes;
272 spin_unlock(&DRM(mem_lock)); 271 spin_unlock(&drm_mem_lock);
273 if (free_count > alloc_count) { 272 if (free_count > alloc_count) {
274 DRM_MEM_ERROR(area, 273 DRM_MEM_ERROR(area,
275 "Excess frees: %d frees, %d allocs\n", 274 "Excess frees: %d frees, %d allocs\n",
@@ -277,7 +276,7 @@ void DRM(free_pages) (unsigned long address, int order, int area) {
277 } 276 }
278} 277}
279 278
280void *DRM(ioremap) (unsigned long offset, unsigned long size, 279void *drm_ioremap (unsigned long offset, unsigned long size,
281 drm_device_t * dev) { 280 drm_device_t * dev) {
282 void *pt; 281 void *pt;
283 282
@@ -288,19 +287,19 @@ void *DRM(ioremap) (unsigned long offset, unsigned long size,
288 } 287 }
289 288
290 if (!(pt = drm_ioremap(offset, size, dev))) { 289 if (!(pt = drm_ioremap(offset, size, dev))) {
291 spin_lock(&DRM(mem_lock)); 290 spin_lock(&drm_mem_lock);
292 ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; 291 ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
293 spin_unlock(&DRM(mem_lock)); 292 spin_unlock(&drm_mem_lock);
294 return NULL; 293 return NULL;
295 } 294 }
296 spin_lock(&DRM(mem_lock)); 295 spin_lock(&drm_mem_lock);
297 ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; 296 ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
298 DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; 297 drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
299 spin_unlock(&DRM(mem_lock)); 298 spin_unlock(&drm_mem_lock);
300 return pt; 299 return pt;
301} 300}
302 301
303void *DRM(ioremap_nocache) (unsigned long offset, unsigned long size, 302void *drm_ioremap_nocache (unsigned long offset, unsigned long size,
304 drm_device_t * dev) { 303 drm_device_t * dev) {
305 void *pt; 304 void *pt;
306 305
@@ -311,19 +310,19 @@ void *DRM(ioremap_nocache) (unsigned long offset, unsigned long size,
311 } 310 }
312 311
313 if (!(pt = drm_ioremap_nocache(offset, size, dev))) { 312 if (!(pt = drm_ioremap_nocache(offset, size, dev))) {
314 spin_lock(&DRM(mem_lock)); 313 spin_lock(&drm_mem_lock);
315 ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; 314 ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
316 spin_unlock(&DRM(mem_lock)); 315 spin_unlock(&drm_mem_lock);
317 return NULL; 316 return NULL;
318 } 317 }
319 spin_lock(&DRM(mem_lock)); 318 spin_lock(&drm_mem_lock);
320 ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; 319 ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
321 DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; 320 drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
322 spin_unlock(&DRM(mem_lock)); 321 spin_unlock(&drm_mem_lock);
323 return pt; 322 return pt;
324} 323}
325 324
326void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) { 325void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) {
327 int alloc_count; 326 int alloc_count;
328 int free_count; 327 int free_count;
329 328
@@ -333,11 +332,11 @@ void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) {
333 else 332 else
334 drm_ioremapfree(pt, size, dev); 333 drm_ioremapfree(pt, size, dev);
335 334
336 spin_lock(&DRM(mem_lock)); 335 spin_lock(&drm_mem_lock);
337 DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size; 336 drm_mem_stats[DRM_MEM_MAPPINGS].bytes_freed += size;
338 free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count; 337 free_count = ++drm_mem_stats[DRM_MEM_MAPPINGS].free_count;
339 alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; 338 alloc_count = drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
340 spin_unlock(&DRM(mem_lock)); 339 spin_unlock(&drm_mem_lock);
341 if (free_count > alloc_count) { 340 if (free_count > alloc_count) {
342 DRM_MEM_ERROR(DRM_MEM_MAPPINGS, 341 DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
343 "Excess frees: %d frees, %d allocs\n", 342 "Excess frees: %d frees, %d allocs\n",
@@ -347,7 +346,7 @@ void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) {
347 346
348#if __OS_HAS_AGP 347#if __OS_HAS_AGP
349 348
350DRM_AGP_MEM *DRM(alloc_agp) (int pages, u32 type) { 349DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) {
351 DRM_AGP_MEM *handle; 350 DRM_AGP_MEM *handle;
352 351
353 if (!pages) { 352 if (!pages) {
@@ -355,21 +354,21 @@ DRM_AGP_MEM *DRM(alloc_agp) (int pages, u32 type) {
355 return NULL; 354 return NULL;
356 } 355 }
357 356
358 if ((handle = DRM(agp_allocate_memory) (pages, type))) { 357 if ((handle = drm_agp_allocate_memory (pages, type))) {
359 spin_lock(&DRM(mem_lock)); 358 spin_lock(&drm_mem_lock);
360 ++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; 359 ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
361 DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated 360 drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated
362 += pages << PAGE_SHIFT; 361 += pages << PAGE_SHIFT;
363 spin_unlock(&DRM(mem_lock)); 362 spin_unlock(&drm_mem_lock);
364 return handle; 363 return handle;
365 } 364 }
366 spin_lock(&DRM(mem_lock)); 365 spin_lock(&drm_mem_lock);
367 ++DRM(mem_stats)[DRM_MEM_TOTALAGP].fail_count; 366 ++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count;
368 spin_unlock(&DRM(mem_lock)); 367 spin_unlock(&drm_mem_lock);
369 return NULL; 368 return NULL;
370} 369}
371 370
372int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) { 371int drm_free_agp (DRM_AGP_MEM * handle, int pages) {
373 int alloc_count; 372 int alloc_count;
374 int free_count; 373 int free_count;
375 int retval = -EINVAL; 374 int retval = -EINVAL;
@@ -380,13 +379,13 @@ int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) {
380 return retval; 379 return retval;
381 } 380 }
382 381
383 if (DRM(agp_free_memory) (handle)) { 382 if (drm_agp_free_memory (handle)) {
384 spin_lock(&DRM(mem_lock)); 383 spin_lock(&drm_mem_lock);
385 free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count; 384 free_count = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count;
386 alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; 385 alloc_count = drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
387 DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed 386 drm_mem_stats[DRM_MEM_TOTALAGP].bytes_freed
388 += pages << PAGE_SHIFT; 387 += pages << PAGE_SHIFT;
389 spin_unlock(&DRM(mem_lock)); 388 spin_unlock(&drm_mem_lock);
390 if (free_count > alloc_count) { 389 if (free_count > alloc_count) {
391 DRM_MEM_ERROR(DRM_MEM_TOTALAGP, 390 DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
392 "Excess frees: %d frees, %d allocs\n", 391 "Excess frees: %d frees, %d allocs\n",
@@ -397,7 +396,7 @@ int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) {
397 return retval; 396 return retval;
398} 397}
399 398
400int DRM(bind_agp) (DRM_AGP_MEM * handle, unsigned int start) { 399int drm_bind_agp (DRM_AGP_MEM * handle, unsigned int start) {
401 int retcode = -EINVAL; 400 int retcode = -EINVAL;
402 401
403 if (!handle) { 402 if (!handle) {
@@ -406,21 +405,21 @@ int DRM(bind_agp) (DRM_AGP_MEM * handle, unsigned int start) {
406 return retcode; 405 return retcode;
407 } 406 }
408 407
409 if (!(retcode = DRM(agp_bind_memory) (handle, start))) { 408 if (!(retcode = drm_agp_bind_memory (handle, start))) {
410 spin_lock(&DRM(mem_lock)); 409 spin_lock(&drm_mem_lock);
411 ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; 410 ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
412 DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated 411 drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated
413 += handle->page_count << PAGE_SHIFT; 412 += handle->page_count << PAGE_SHIFT;
414 spin_unlock(&DRM(mem_lock)); 413 spin_unlock(&drm_mem_lock);
415 return retcode; 414 return retcode;
416 } 415 }
417 spin_lock(&DRM(mem_lock)); 416 spin_lock(&drm_mem_lock);
418 ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].fail_count; 417 ++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count;
419 spin_unlock(&DRM(mem_lock)); 418 spin_unlock(&drm_mem_lock);
420 return retcode; 419 return retcode;
421} 420}
422 421
423int DRM(unbind_agp) (DRM_AGP_MEM * handle) { 422int drm_unbind_agp (DRM_AGP_MEM * handle) {
424 int alloc_count; 423 int alloc_count;
425 int free_count; 424 int free_count;
426 int retcode = -EINVAL; 425 int retcode = -EINVAL;
@@ -431,14 +430,14 @@ int DRM(unbind_agp) (DRM_AGP_MEM * handle) {
431 return retcode; 430 return retcode;
432 } 431 }
433 432
434 if ((retcode = DRM(agp_unbind_memory) (handle))) 433 if ((retcode = drm_agp_unbind_memory (handle)))
435 return retcode; 434 return retcode;
436 spin_lock(&DRM(mem_lock)); 435 spin_lock(&drm_mem_lock);
437 free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count; 436 free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count;
438 alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; 437 alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
439 DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed 438 drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed
440 += handle->page_count << PAGE_SHIFT; 439 += handle->page_count << PAGE_SHIFT;
441 spin_unlock(&DRM(mem_lock)); 440 spin_unlock(&drm_mem_lock);
442 if (free_count > alloc_count) { 441 if (free_count > alloc_count) {
443 DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, 442 DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
444 "Excess frees: %d frees, %d allocs\n", 443 "Excess frees: %d frees, %d allocs\n",
diff --git a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h
index d51aeb4966f4..695115d70382 100644
--- a/drivers/char/drm/drm_os_linux.h
+++ b/drivers/char/drm/drm_os_linux.h
@@ -13,6 +13,7 @@
13#define DRM_ERR(d) -(d) 13#define DRM_ERR(d) -(d)
14/** Current process ID */ 14/** Current process ID */
15#define DRM_CURRENTPID current->pid 15#define DRM_CURRENTPID current->pid
16#define DRM_SUSER(p) capable(CAP_SYS_ADMIN)
16#define DRM_UDELAY(d) udelay(d) 17#define DRM_UDELAY(d) udelay(d)
17/** Read a byte from a MMIO region */ 18/** Read a byte from a MMIO region */
18#define DRM_READ8(map, offset) readb(((void __iomem *)(map)->handle) + (offset)) 19#define DRM_READ8(map, offset) readb(((void __iomem *)(map)->handle) + (offset))
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index d66dc55e29a0..5b1d3a04458d 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -46,6 +46,7 @@
46 {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ 46 {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
47 {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ 47 {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
48 {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ 48 {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
49 {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
49 {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ 50 {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
50 {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ 51 {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
51 {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ 52 {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
@@ -69,6 +70,7 @@
69 {0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 70 {0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
70 {0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 71 {0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
71 {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 72 {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
73 {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
72 {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ 74 {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
73 {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ 75 {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
74 {0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ 76 {0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
@@ -82,10 +84,13 @@
82 {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ 84 {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
83 {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 85 {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
84 {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 86 {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
87 {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
85 {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ 88 {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
86 {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 89 {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
87 {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ 90 {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
88 {0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 91 {0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
92 {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
93 {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \
89 {0, 0, 0} 94 {0, 0, 0}
90 95
91#define r128_PCI_IDS \ 96#define r128_PCI_IDS \
@@ -176,7 +181,7 @@
176 181
177#define viadrv_PCI_IDS \ 182#define viadrv_PCI_IDS \
178 {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 183 {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
179 {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 184 {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
180 {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 185 {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
181 {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 186 {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
182 {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 187 {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
@@ -196,6 +201,10 @@
196 {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 201 {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
197 {0, 0, 0} 202 {0, 0, 0}
198 203
204#define gamma_PCI_IDS \
205 {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
206 {0, 0, 0}
207
199#define savage_PCI_IDS \ 208#define savage_PCI_IDS \
200 {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \ 209 {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
201 {0x5333, 0x8a21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \ 210 {0x5333, 0x8a21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
@@ -234,3 +243,4 @@
234 {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 243 {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
235 {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 244 {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
236 {0, 0, 0} 245 {0, 0, 0}
246
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index 3f452f763f0f..6f943e3309ef 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -61,16 +61,14 @@ static struct drm_proc_list {
61 const char *name; /**< file name */ 61 const char *name; /**< file name */
62 int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ 62 int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/
63} drm_proc_list[] = { 63} drm_proc_list[] = {
64 { 64 {"name", drm_name_info},
65 "name", drm_name_info}, { 65 {"mem", drm_mem_info},
66 "mem", drm_mem_info}, { 66 {"vm", drm_vm_info},
67 "vm", drm_vm_info}, { 67 {"clients", drm_clients_info},
68 "clients", drm_clients_info}, { 68 {"queues", drm_queues_info},
69 "queues", drm_queues_info}, { 69 {"bufs", drm_bufs_info},
70 "bufs", drm_bufs_info},
71#if DRM_DEBUG_CODE 70#if DRM_DEBUG_CODE
72 { 71 {"vma", drm_vma_info},
73 "vma", drm_vma_info},
74#endif 72#endif
75}; 73};
76 74
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 60b6f8e8bf69..42d766359caa 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -93,8 +93,8 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
93 93
94 dev->driver = driver; 94 dev->driver = driver;
95 95
96 if (dev->driver->preinit) 96 if (dev->driver->load)
97 if ((retcode = dev->driver->preinit(dev, ent->driver_data))) 97 if ((retcode = dev->driver->load(dev, ent->driver_data)))
98 goto error_out_unreg; 98 goto error_out_unreg;
99 99
100 if (drm_core_has_AGP(dev)) { 100 if (drm_core_has_AGP(dev)) {
@@ -124,47 +124,10 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
124 return 0; 124 return 0;
125 125
126 error_out_unreg: 126 error_out_unreg:
127 drm_takedown(dev); 127 drm_lastclose(dev);
128 return retcode; 128 return retcode;
129} 129}
130 130
131/**
132 * File \c open operation.
133 *
134 * \param inode device inode.
135 * \param filp file pointer.
136 *
137 * Puts the dev->fops corresponding to the device minor number into
138 * \p filp, call the \c open method, and restore the file operations.
139 */
140int drm_stub_open(struct inode *inode, struct file *filp)
141{
142 drm_device_t *dev = NULL;
143 int minor = iminor(inode);
144 int err = -ENODEV;
145 struct file_operations *old_fops;
146
147 DRM_DEBUG("\n");
148
149 if (!((minor >= 0) && (minor < drm_cards_limit)))
150 return -ENODEV;
151
152 if (!drm_heads[minor])
153 return -ENODEV;
154
155 if (!(dev = drm_heads[minor]->dev))
156 return -ENODEV;
157
158 old_fops = filp->f_op;
159 filp->f_op = fops_get(&dev->driver->fops);
160 if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
161 fops_put(filp->f_op);
162 filp->f_op = fops_get(old_fops);
163 }
164 fops_put(old_fops);
165
166 return err;
167}
168 131
169/** 132/**
170 * Get a secondary minor number. 133 * Get a secondary minor number.
@@ -200,11 +163,7 @@ static int drm_get_head(drm_device_t * dev, drm_head_t * head)
200 goto err_g1; 163 goto err_g1;
201 } 164 }
202 165
203 head->dev_class = drm_sysfs_device_add(drm_class, 166 head->dev_class = drm_sysfs_device_add(drm_class, head);
204 MKDEV(DRM_MAJOR,
205 minor),
206 &dev->pdev->dev,
207 "card%d", minor);
208 if (IS_ERR(head->dev_class)) { 167 if (IS_ERR(head->dev_class)) {
209 printk(KERN_ERR 168 printk(KERN_ERR
210 "DRM: Error sysfs_device_add.\n"); 169 "DRM: Error sysfs_device_add.\n");
@@ -258,11 +217,10 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
258 } 217 }
259 if ((ret = drm_get_head(dev, &dev->primary))) 218 if ((ret = drm_get_head(dev, &dev->primary)))
260 goto err_g1; 219 goto err_g1;
261 220
262 /* postinit is a required function to display the signon banner */ 221 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
263 /* drivers add secondary heads here if needed */ 222 driver->name, driver->major, driver->minor, driver->patchlevel,
264 if ((ret = dev->driver->postinit(dev, ent->driver_data))) 223 driver->date, dev->primary.minor);
265 goto err_g1;
266 224
267 return 0; 225 return 0;
268 226
@@ -318,10 +276,9 @@ int drm_put_head(drm_head_t * head)
318 DRM_DEBUG("release secondary minor %d\n", minor); 276 DRM_DEBUG("release secondary minor %d\n", minor);
319 277
320 drm_proc_cleanup(minor, drm_proc_root, head->dev_root); 278 drm_proc_cleanup(minor, drm_proc_root, head->dev_root);
321 drm_sysfs_device_remove(MKDEV(DRM_MAJOR, head->minor)); 279 drm_sysfs_device_remove(head->dev_class);
322 280
323 *head = (drm_head_t) { 281 *head = (drm_head_t) {.dev = NULL};
324 .dev = NULL};
325 282
326 drm_heads[minor] = NULL; 283 drm_heads[minor] = NULL;
327 284
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
index 6d3449761914..68e43ddc16ae 100644
--- a/drivers/char/drm/drm_sysfs.c
+++ b/drivers/char/drm/drm_sysfs.c
@@ -15,8 +15,6 @@
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/kdev_t.h> 16#include <linux/kdev_t.h>
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/slab.h>
19#include <linux/string.h>
20 18
21#include "drm_core.h" 19#include "drm_core.h"
22#include "drmP.h" 20#include "drmP.h"
@@ -28,15 +26,11 @@ struct drm_sysfs_class {
28#define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class) 26#define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class)
29 27
30struct simple_dev { 28struct simple_dev {
31 struct list_head node;
32 dev_t dev; 29 dev_t dev;
33 struct class_device class_dev; 30 struct class_device class_dev;
34}; 31};
35#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev) 32#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
36 33
37static LIST_HEAD(simple_dev_list);
38static DEFINE_SPINLOCK(simple_dev_list_lock);
39
40static void release_simple_dev(struct class_device *class_dev) 34static void release_simple_dev(struct class_device *class_dev)
41{ 35{
42 struct simple_dev *s_dev = to_simple_dev(class_dev); 36 struct simple_dev *s_dev = to_simple_dev(class_dev);
@@ -124,6 +118,18 @@ void drm_sysfs_destroy(struct drm_sysfs_class *cs)
124 class_unregister(&cs->class); 118 class_unregister(&cs->class);
125} 119}
126 120
121static ssize_t show_dri(struct class_device *class_device, char *buf)
122{
123 drm_device_t * dev = ((drm_head_t *)class_get_devdata(class_device))->dev;
124 if (dev->driver->dri_library_name)
125 return dev->driver->dri_library_name(dev, buf);
126 return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name);
127}
128
129static struct class_device_attribute class_device_attrs[] = {
130 __ATTR(dri_library_name, S_IRUGO, show_dri, NULL),
131};
132
127/** 133/**
128 * drm_sysfs_device_add - adds a class device to sysfs for a character driver 134 * drm_sysfs_device_add - adds a class device to sysfs for a character driver
129 * @cs: pointer to the struct drm_sysfs_class that this device should be registered to. 135 * @cs: pointer to the struct drm_sysfs_class that this device should be registered to.
@@ -138,13 +144,11 @@ void drm_sysfs_destroy(struct drm_sysfs_class *cs)
138 * Note: the struct drm_sysfs_class passed to this function must have previously been 144 * Note: the struct drm_sysfs_class passed to this function must have previously been
139 * created with a call to drm_sysfs_create(). 145 * created with a call to drm_sysfs_create().
140 */ 146 */
141struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev, 147struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
142 struct device *device, 148 drm_head_t *head)
143 const char *fmt, ...)
144{ 149{
145 va_list args;
146 struct simple_dev *s_dev = NULL; 150 struct simple_dev *s_dev = NULL;
147 int retval; 151 int i, retval;
148 152
149 if ((cs == NULL) || (IS_ERR(cs))) { 153 if ((cs == NULL) || (IS_ERR(cs))) {
150 retval = -ENODEV; 154 retval = -ENODEV;
@@ -158,26 +162,23 @@ struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev,
158 } 162 }
159 memset(s_dev, 0x00, sizeof(*s_dev)); 163 memset(s_dev, 0x00, sizeof(*s_dev));
160 164
161 s_dev->dev = dev; 165 s_dev->dev = MKDEV(DRM_MAJOR, head->minor);
162 s_dev->class_dev.dev = device; 166 s_dev->class_dev.dev = &(head->dev->pdev)->dev;
163 s_dev->class_dev.class = &cs->class; 167 s_dev->class_dev.class = &cs->class;
164 168
165 va_start(args, fmt); 169 snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor);
166 vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args);
167 va_end(args);
168 retval = class_device_register(&s_dev->class_dev); 170 retval = class_device_register(&s_dev->class_dev);
169 if (retval) 171 if (retval)
170 goto error; 172 goto error;
171 173
172 class_device_create_file(&s_dev->class_dev, &cs->attr); 174 class_device_create_file(&s_dev->class_dev, &cs->attr);
175 class_set_devdata(&s_dev->class_dev, head);
173 176
174 spin_lock(&simple_dev_list_lock); 177 for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
175 list_add(&s_dev->node, &simple_dev_list); 178 class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]);
176 spin_unlock(&simple_dev_list_lock);
177
178 return &s_dev->class_dev; 179 return &s_dev->class_dev;
179 180
180 error: 181error:
181 kfree(s_dev); 182 kfree(s_dev);
182 return ERR_PTR(retval); 183 return ERR_PTR(retval);
183} 184}
@@ -189,23 +190,12 @@ struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, dev_t dev,
189 * This call unregisters and cleans up a class device that was created with a 190 * This call unregisters and cleans up a class device that was created with a
190 * call to drm_sysfs_device_add() 191 * call to drm_sysfs_device_add()
191 */ 192 */
192void drm_sysfs_device_remove(dev_t dev) 193void drm_sysfs_device_remove(struct class_device *class_dev)
193{ 194{
194 struct simple_dev *s_dev = NULL; 195 struct simple_dev *s_dev = to_simple_dev(class_dev);
195 int found = 0; 196 int i;
196 197
197 spin_lock(&simple_dev_list_lock); 198 for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
198 list_for_each_entry(s_dev, &simple_dev_list, node) { 199 class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]);
199 if (s_dev->dev == dev) { 200 class_device_unregister(&s_dev->class_dev);
200 found = 1;
201 break;
202 }
203 }
204 if (found) {
205 list_del(&s_dev->node);
206 spin_unlock(&simple_dev_list_lock);
207 class_device_unregister(&s_dev->class_dev);
208 } else {
209 spin_unlock(&simple_dev_list_lock);
210 }
211} 201}
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index dba502373da1..cc1b89086876 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -114,7 +114,6 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
114 114
115static struct file_operations i810_buffer_fops = { 115static struct file_operations i810_buffer_fops = {
116 .open = drm_open, 116 .open = drm_open,
117 .flush = drm_flush,
118 .release = drm_release, 117 .release = drm_release,
119 .ioctl = drm_ioctl, 118 .ioctl = drm_ioctl,
120 .mmap = i810_mmap_buffers, 119 .mmap = i810_mmap_buffers,
@@ -1319,12 +1318,24 @@ static int i810_flip_bufs(struct inode *inode, struct file *filp,
1319 return 0; 1318 return 0;
1320} 1319}
1321 1320
1322void i810_driver_pretakedown(drm_device_t * dev) 1321int i810_driver_load(drm_device_t *dev, unsigned long flags)
1322{
1323 /* i810 has 4 more counters */
1324 dev->counters += 4;
1325 dev->types[6] = _DRM_STAT_IRQ;
1326 dev->types[7] = _DRM_STAT_PRIMARY;
1327 dev->types[8] = _DRM_STAT_SECONDARY;
1328 dev->types[9] = _DRM_STAT_DMA;
1329
1330 return 0;
1331}
1332
1333void i810_driver_lastclose(drm_device_t * dev)
1323{ 1334{
1324 i810_dma_cleanup(dev); 1335 i810_dma_cleanup(dev);
1325} 1336}
1326 1337
1327void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp) 1338void i810_driver_preclose(drm_device_t * dev, DRMFILE filp)
1328{ 1339{
1329 if (dev->dev_private) { 1340 if (dev->dev_private) {
1330 drm_i810_private_t *dev_priv = dev->dev_private; 1341 drm_i810_private_t *dev_priv = dev->dev_private;
@@ -1334,7 +1345,7 @@ void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp)
1334 } 1345 }
1335} 1346}
1336 1347
1337void i810_driver_release(drm_device_t * dev, struct file *filp) 1348void i810_driver_reclaim_buffers_locked(drm_device_t * dev, struct file *filp)
1338{ 1349{
1339 i810_reclaim_buffers(dev, filp); 1350 i810_reclaim_buffers(dev, filp);
1340} 1351}
@@ -1346,21 +1357,21 @@ int i810_driver_dma_quiescent(drm_device_t * dev)
1346} 1357}
1347 1358
1348drm_ioctl_desc_t i810_ioctls[] = { 1359drm_ioctl_desc_t i810_ioctls[] = {
1349 [DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, 1, 1}, 1360 [DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1350 [DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, 1, 0}, 1361 [DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, DRM_AUTH},
1351 [DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, 1, 0}, 1362 [DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, DRM_AUTH},
1352 [DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, 1, 0}, 1363 [DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, DRM_AUTH},
1353 [DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, 1, 0}, 1364 [DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, DRM_AUTH},
1354 [DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, 1, 0}, 1365 [DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, DRM_AUTH},
1355 [DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, 1, 0}, 1366 [DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, DRM_AUTH},
1356 [DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, 1, 0}, 1367 [DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, DRM_AUTH},
1357 [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, 1, 0}, 1368 [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, DRM_AUTH},
1358 [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, 1, 0}, 1369 [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, DRM_AUTH},
1359 [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, 1, 0}, 1370 [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, DRM_AUTH},
1360 [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, 1, 0}, 1371 [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, DRM_AUTH},
1361 [DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, 1, 1}, 1372 [DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1362 [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, 1, 0}, 1373 [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, DRM_AUTH},
1363 [DRM_IOCTL_NR(DRM_I810_FLIP)] = {i810_flip_bufs, 1, 0} 1374 [DRM_IOCTL_NR(DRM_I810_FLIP)] = {i810_flip_bufs, DRM_AUTH}
1364}; 1375};
1365 1376
1366int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); 1377int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c
index 070cef6c2b46..dfe6ad2b6a6e 100644
--- a/drivers/char/drm/i810_drv.c
+++ b/drivers/char/drm/i810_drv.c
@@ -38,38 +38,6 @@
38 38
39#include "drm_pciids.h" 39#include "drm_pciids.h"
40 40
41static int postinit(struct drm_device *dev, unsigned long flags)
42{
43 /* i810 has 4 more counters */
44 dev->counters += 4;
45 dev->types[6] = _DRM_STAT_IRQ;
46 dev->types[7] = _DRM_STAT_PRIMARY;
47 dev->types[8] = _DRM_STAT_SECONDARY;
48 dev->types[9] = _DRM_STAT_DMA;
49
50 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
51 DRIVER_NAME,
52 DRIVER_MAJOR,
53 DRIVER_MINOR,
54 DRIVER_PATCHLEVEL,
55 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
56 );
57 return 0;
58}
59
60static int version(drm_version_t * version)
61{
62 int len;
63
64 version->version_major = DRIVER_MAJOR;
65 version->version_minor = DRIVER_MINOR;
66 version->version_patchlevel = DRIVER_PATCHLEVEL;
67 DRM_COPY(version->name, DRIVER_NAME);
68 DRM_COPY(version->date, DRIVER_DATE);
69 DRM_COPY(version->desc, DRIVER_DESC);
70 return 0;
71}
72
73static struct pci_device_id pciidlist[] = { 41static struct pci_device_id pciidlist[] = {
74 i810_PCI_IDS 42 i810_PCI_IDS
75}; 43};
@@ -79,16 +47,14 @@ static struct drm_driver driver = {
79 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | 47 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
80 DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE, 48 DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
81 .dev_priv_size = sizeof(drm_i810_buf_priv_t), 49 .dev_priv_size = sizeof(drm_i810_buf_priv_t),
82 .pretakedown = i810_driver_pretakedown, 50 .load = i810_driver_load,
83 .prerelease = i810_driver_prerelease, 51 .lastclose = i810_driver_lastclose,
52 .preclose = i810_driver_preclose,
84 .device_is_agp = i810_driver_device_is_agp, 53 .device_is_agp = i810_driver_device_is_agp,
85 .release = i810_driver_release, 54 .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked,
86 .dma_quiescent = i810_driver_dma_quiescent, 55 .dma_quiescent = i810_driver_dma_quiescent,
87 .reclaim_buffers = i810_reclaim_buffers,
88 .get_map_ofs = drm_core_get_map_ofs, 56 .get_map_ofs = drm_core_get_map_ofs,
89 .get_reg_ofs = drm_core_get_reg_ofs, 57 .get_reg_ofs = drm_core_get_reg_ofs,
90 .postinit = postinit,
91 .version = version,
92 .ioctls = i810_ioctls, 58 .ioctls = i810_ioctls,
93 .fops = { 59 .fops = {
94 .owner = THIS_MODULE, 60 .owner = THIS_MODULE,
@@ -98,13 +64,19 @@ static struct drm_driver driver = {
98 .mmap = drm_mmap, 64 .mmap = drm_mmap,
99 .poll = drm_poll, 65 .poll = drm_poll,
100 .fasync = drm_fasync, 66 .fasync = drm_fasync,
101 } 67 },
102 , 68
103 .pci_driver = { 69 .pci_driver = {
104 .name = DRIVER_NAME, 70 .name = DRIVER_NAME,
105 .id_table = pciidlist, 71 .id_table = pciidlist,
106 } 72 },
107 , 73
74 .name = DRIVER_NAME,
75 .desc = DRIVER_DESC,
76 .date = DRIVER_DATE,
77 .major = DRIVER_MAJOR,
78 .minor = DRIVER_MINOR,
79 .patchlevel = DRIVER_PATCHLEVEL,
108}; 80};
109 81
110static int __init i810_init(void) 82static int __init i810_init(void)
diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h
index c78f36aaa2f0..a18b80d91920 100644
--- a/drivers/char/drm/i810_drv.h
+++ b/drivers/char/drm/i810_drv.h
@@ -116,9 +116,13 @@ typedef struct drm_i810_private {
116extern void i810_reclaim_buffers(drm_device_t * dev, struct file *filp); 116extern void i810_reclaim_buffers(drm_device_t * dev, struct file *filp);
117 117
118extern int i810_driver_dma_quiescent(drm_device_t * dev); 118extern int i810_driver_dma_quiescent(drm_device_t * dev);
119extern void i810_driver_release(drm_device_t * dev, struct file *filp); 119extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev,
120extern void i810_driver_pretakedown(drm_device_t * dev); 120 struct file *filp);
121extern void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp); 121extern int i810_driver_load(struct drm_device *, unsigned long flags);
122extern void i810_driver_lastclose(drm_device_t * dev);
123extern void i810_driver_preclose(drm_device_t * dev, DRMFILE filp);
124extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev,
125 struct file *filp);
122extern int i810_driver_device_is_agp(drm_device_t * dev); 126extern int i810_driver_device_is_agp(drm_device_t * dev);
123 127
124extern drm_ioctl_desc_t i810_ioctls[]; 128extern drm_ioctl_desc_t i810_ioctls[];
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index dc94f1914425..4fea32aed6d2 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -116,7 +116,6 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
116 116
117static struct file_operations i830_buffer_fops = { 117static struct file_operations i830_buffer_fops = {
118 .open = drm_open, 118 .open = drm_open,
119 .flush = drm_flush,
120 .release = drm_release, 119 .release = drm_release,
121 .ioctl = drm_ioctl, 120 .ioctl = drm_ioctl,
122 .mmap = i830_mmap_buffers, 121 .mmap = i830_mmap_buffers,
@@ -1517,12 +1516,24 @@ static int i830_setparam(struct inode *inode, struct file *filp,
1517 return 0; 1516 return 0;
1518} 1517}
1519 1518
1520void i830_driver_pretakedown(drm_device_t * dev) 1519int i830_driver_load(drm_device_t *dev, unsigned long flags)
1520{
1521 /* i830 has 4 more counters */
1522 dev->counters += 4;
1523 dev->types[6] = _DRM_STAT_IRQ;
1524 dev->types[7] = _DRM_STAT_PRIMARY;
1525 dev->types[8] = _DRM_STAT_SECONDARY;
1526 dev->types[9] = _DRM_STAT_DMA;
1527
1528 return 0;
1529}
1530
1531void i830_driver_lastclose(drm_device_t * dev)
1521{ 1532{
1522 i830_dma_cleanup(dev); 1533 i830_dma_cleanup(dev);
1523} 1534}
1524 1535
1525void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp) 1536void i830_driver_preclose(drm_device_t * dev, DRMFILE filp)
1526{ 1537{
1527 if (dev->dev_private) { 1538 if (dev->dev_private) {
1528 drm_i830_private_t *dev_priv = dev->dev_private; 1539 drm_i830_private_t *dev_priv = dev->dev_private;
@@ -1532,7 +1543,7 @@ void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp)
1532 } 1543 }
1533} 1544}
1534 1545
1535void i830_driver_release(drm_device_t * dev, struct file *filp) 1546void i830_driver_reclaim_buffers_locked(drm_device_t * dev, struct file *filp)
1536{ 1547{
1537 i830_reclaim_buffers(dev, filp); 1548 i830_reclaim_buffers(dev, filp);
1538} 1549}
@@ -1544,20 +1555,20 @@ int i830_driver_dma_quiescent(drm_device_t * dev)
1544} 1555}
1545 1556
1546drm_ioctl_desc_t i830_ioctls[] = { 1557drm_ioctl_desc_t i830_ioctls[] = {
1547 [DRM_IOCTL_NR(DRM_I830_INIT)] = {i830_dma_init, 1, 1}, 1558 [DRM_IOCTL_NR(DRM_I830_INIT)] = {i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1548 [DRM_IOCTL_NR(DRM_I830_VERTEX)] = {i830_dma_vertex, 1, 0}, 1559 [DRM_IOCTL_NR(DRM_I830_VERTEX)] = {i830_dma_vertex, DRM_AUTH},
1549 [DRM_IOCTL_NR(DRM_I830_CLEAR)] = {i830_clear_bufs, 1, 0}, 1560 [DRM_IOCTL_NR(DRM_I830_CLEAR)] = {i830_clear_bufs, DRM_AUTH},
1550 [DRM_IOCTL_NR(DRM_I830_FLUSH)] = {i830_flush_ioctl, 1, 0}, 1561 [DRM_IOCTL_NR(DRM_I830_FLUSH)] = {i830_flush_ioctl, DRM_AUTH},
1551 [DRM_IOCTL_NR(DRM_I830_GETAGE)] = {i830_getage, 1, 0}, 1562 [DRM_IOCTL_NR(DRM_I830_GETAGE)] = {i830_getage, DRM_AUTH},
1552 [DRM_IOCTL_NR(DRM_I830_GETBUF)] = {i830_getbuf, 1, 0}, 1563 [DRM_IOCTL_NR(DRM_I830_GETBUF)] = {i830_getbuf, DRM_AUTH},
1553 [DRM_IOCTL_NR(DRM_I830_SWAP)] = {i830_swap_bufs, 1, 0}, 1564 [DRM_IOCTL_NR(DRM_I830_SWAP)] = {i830_swap_bufs, DRM_AUTH},
1554 [DRM_IOCTL_NR(DRM_I830_COPY)] = {i830_copybuf, 1, 0}, 1565 [DRM_IOCTL_NR(DRM_I830_COPY)] = {i830_copybuf, DRM_AUTH},
1555 [DRM_IOCTL_NR(DRM_I830_DOCOPY)] = {i830_docopy, 1, 0}, 1566 [DRM_IOCTL_NR(DRM_I830_DOCOPY)] = {i830_docopy, DRM_AUTH},
1556 [DRM_IOCTL_NR(DRM_I830_FLIP)] = {i830_flip_bufs, 1, 0}, 1567 [DRM_IOCTL_NR(DRM_I830_FLIP)] = {i830_flip_bufs, DRM_AUTH},
1557 [DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = {i830_irq_emit, 1, 0}, 1568 [DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = {i830_irq_emit, DRM_AUTH},
1558 [DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = {i830_irq_wait, 1, 0}, 1569 [DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = {i830_irq_wait, DRM_AUTH},
1559 [DRM_IOCTL_NR(DRM_I830_GETPARAM)] = {i830_getparam, 1, 0}, 1570 [DRM_IOCTL_NR(DRM_I830_GETPARAM)] = {i830_getparam, DRM_AUTH},
1560 [DRM_IOCTL_NR(DRM_I830_SETPARAM)] = {i830_setparam, 1, 0} 1571 [DRM_IOCTL_NR(DRM_I830_SETPARAM)] = {i830_setparam, DRM_AUTH}
1561}; 1572};
1562 1573
1563int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); 1574int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);
diff --git a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
index acd821e8fe4d..722658188f5f 100644
--- a/drivers/char/drm/i830_drv.c
+++ b/drivers/char/drm/i830_drv.c
@@ -40,37 +40,6 @@
40 40
41#include "drm_pciids.h" 41#include "drm_pciids.h"
42 42
43static int postinit(struct drm_device *dev, unsigned long flags)
44{
45 dev->counters += 4;
46 dev->types[6] = _DRM_STAT_IRQ;
47 dev->types[7] = _DRM_STAT_PRIMARY;
48 dev->types[8] = _DRM_STAT_SECONDARY;
49 dev->types[9] = _DRM_STAT_DMA;
50
51 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
52 DRIVER_NAME,
53 DRIVER_MAJOR,
54 DRIVER_MINOR,
55 DRIVER_PATCHLEVEL,
56 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
57 );
58 return 0;
59}
60
61static int version(drm_version_t * version)
62{
63 int len;
64
65 version->version_major = DRIVER_MAJOR;
66 version->version_minor = DRIVER_MINOR;
67 version->version_patchlevel = DRIVER_PATCHLEVEL;
68 DRM_COPY(version->name, DRIVER_NAME);
69 DRM_COPY(version->date, DRIVER_DATE);
70 DRM_COPY(version->desc, DRIVER_DESC);
71 return 0;
72}
73
74static struct pci_device_id pciidlist[] = { 43static struct pci_device_id pciidlist[] = {
75 i830_PCI_IDS 44 i830_PCI_IDS
76}; 45};
@@ -83,12 +52,12 @@ static struct drm_driver driver = {
83 .driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ, 52 .driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ,
84#endif 53#endif
85 .dev_priv_size = sizeof(drm_i830_buf_priv_t), 54 .dev_priv_size = sizeof(drm_i830_buf_priv_t),
86 .pretakedown = i830_driver_pretakedown, 55 .load = i830_driver_load,
87 .prerelease = i830_driver_prerelease, 56 .lastclose = i830_driver_lastclose,
57 .preclose = i830_driver_preclose,
88 .device_is_agp = i830_driver_device_is_agp, 58 .device_is_agp = i830_driver_device_is_agp,
89 .release = i830_driver_release, 59 .reclaim_buffers_locked = i830_driver_reclaim_buffers_locked,
90 .dma_quiescent = i830_driver_dma_quiescent, 60 .dma_quiescent = i830_driver_dma_quiescent,
91 .reclaim_buffers = i830_reclaim_buffers,
92 .get_map_ofs = drm_core_get_map_ofs, 61 .get_map_ofs = drm_core_get_map_ofs,
93 .get_reg_ofs = drm_core_get_reg_ofs, 62 .get_reg_ofs = drm_core_get_reg_ofs,
94#if USE_IRQS 63#if USE_IRQS
@@ -97,8 +66,6 @@ static struct drm_driver driver = {
97 .irq_uninstall = i830_driver_irq_uninstall, 66 .irq_uninstall = i830_driver_irq_uninstall,
98 .irq_handler = i830_driver_irq_handler, 67 .irq_handler = i830_driver_irq_handler,
99#endif 68#endif
100 .postinit = postinit,
101 .version = version,
102 .ioctls = i830_ioctls, 69 .ioctls = i830_ioctls,
103 .fops = { 70 .fops = {
104 .owner = THIS_MODULE, 71 .owner = THIS_MODULE,
@@ -108,13 +75,19 @@ static struct drm_driver driver = {
108 .mmap = drm_mmap, 75 .mmap = drm_mmap,
109 .poll = drm_poll, 76 .poll = drm_poll,
110 .fasync = drm_fasync, 77 .fasync = drm_fasync,
111 } 78 },
112 , 79
113 .pci_driver = { 80 .pci_driver = {
114 .name = DRIVER_NAME, 81 .name = DRIVER_NAME,
115 .id_table = pciidlist, 82 .id_table = pciidlist,
116 } 83 },
117 84
85 .name = DRIVER_NAME,
86 .desc = DRIVER_DESC,
87 .date = DRIVER_DATE,
88 .major = DRIVER_MAJOR,
89 .minor = DRIVER_MINOR,
90 .patchlevel = DRIVER_PATCHLEVEL,
118}; 91};
119 92
120static int __init i830_init(void) 93static int __init i830_init(void)
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
index bc4bd49fb0cc..bf9075b576bd 100644
--- a/drivers/char/drm/i830_drv.h
+++ b/drivers/char/drm/i830_drv.h
@@ -136,10 +136,12 @@ extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS);
136extern void i830_driver_irq_preinstall(drm_device_t * dev); 136extern void i830_driver_irq_preinstall(drm_device_t * dev);
137extern void i830_driver_irq_postinstall(drm_device_t * dev); 137extern void i830_driver_irq_postinstall(drm_device_t * dev);
138extern void i830_driver_irq_uninstall(drm_device_t * dev); 138extern void i830_driver_irq_uninstall(drm_device_t * dev);
139extern void i830_driver_pretakedown(drm_device_t * dev); 139extern int i830_driver_load(struct drm_device *, unsigned long flags);
140extern void i830_driver_release(drm_device_t * dev, struct file *filp); 140extern void i830_driver_preclose(drm_device_t * dev, DRMFILE filp);
141extern void i830_driver_lastclose(drm_device_t * dev);
142extern void i830_driver_reclaim_buffers_locked(drm_device_t * dev,
143 struct file *filp);
141extern int i830_driver_dma_quiescent(drm_device_t * dev); 144extern int i830_driver_dma_quiescent(drm_device_t * dev);
142extern void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp);
143extern int i830_driver_device_is_agp(drm_device_t * dev); 145extern int i830_driver_device_is_agp(drm_device_t * dev);
144 146
145#define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg) 147#define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg)
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index f3aa0c370127..9140703da1ba 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -1,7 +1,6 @@
1/* i915_dma.c -- DMA support for the I915 -*- linux-c -*- 1/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
2 */ 2 */
3/************************************************************************** 3/*
4 *
5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * All Rights Reserved. 5 * All Rights Reserved.
7 * 6 *
@@ -25,7 +24,7 @@
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * 26 *
28 **************************************************************************/ 27 */
29 28
30#include "drmP.h" 29#include "drmP.h"
31#include "drm.h" 30#include "drm.h"
@@ -196,7 +195,7 @@ static int i915_initialize(drm_device_t * dev,
196 return 0; 195 return 0;
197} 196}
198 197
199static int i915_resume(drm_device_t * dev) 198static int i915_dma_resume(drm_device_t * dev)
200{ 199{
201 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 200 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
202 201
@@ -253,7 +252,7 @@ static int i915_dma_init(DRM_IOCTL_ARGS)
253 retcode = i915_dma_cleanup(dev); 252 retcode = i915_dma_cleanup(dev);
254 break; 253 break;
255 case I915_RESUME_DMA: 254 case I915_RESUME_DMA:
256 retcode = i915_resume(dev); 255 retcode = i915_dma_resume(dev);
257 break; 256 break;
258 default: 257 default:
259 retcode = -EINVAL; 258 retcode = -EINVAL;
@@ -654,6 +653,9 @@ static int i915_getparam(DRM_IOCTL_ARGS)
654 case I915_PARAM_ALLOW_BATCHBUFFER: 653 case I915_PARAM_ALLOW_BATCHBUFFER:
655 value = dev_priv->allow_batchbuffer ? 1 : 0; 654 value = dev_priv->allow_batchbuffer ? 1 : 0;
656 break; 655 break;
656 case I915_PARAM_LAST_DISPATCH:
657 value = READ_BREADCRUMB(dev_priv);
658 break;
657 default: 659 default:
658 DRM_ERROR("Unkown parameter %d\n", param.param); 660 DRM_ERROR("Unkown parameter %d\n", param.param);
659 return DRM_ERR(EINVAL); 661 return DRM_ERR(EINVAL);
@@ -699,7 +701,19 @@ static int i915_setparam(DRM_IOCTL_ARGS)
699 return 0; 701 return 0;
700} 702}
701 703
702void i915_driver_pretakedown(drm_device_t * dev) 704int i915_driver_load(drm_device_t *dev, unsigned long flags)
705{
706 /* i915 has 4 more counters */
707 dev->counters += 4;
708 dev->types[6] = _DRM_STAT_IRQ;
709 dev->types[7] = _DRM_STAT_PRIMARY;
710 dev->types[8] = _DRM_STAT_SECONDARY;
711 dev->types[9] = _DRM_STAT_DMA;
712
713 return 0;
714}
715
716void i915_driver_lastclose(drm_device_t * dev)
703{ 717{
704 if (dev->dev_private) { 718 if (dev->dev_private) {
705 drm_i915_private_t *dev_priv = dev->dev_private; 719 drm_i915_private_t *dev_priv = dev->dev_private;
@@ -708,7 +722,7 @@ void i915_driver_pretakedown(drm_device_t * dev)
708 i915_dma_cleanup(dev); 722 i915_dma_cleanup(dev);
709} 723}
710 724
711void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp) 725void i915_driver_preclose(drm_device_t * dev, DRMFILE filp)
712{ 726{
713 if (dev->dev_private) { 727 if (dev->dev_private) {
714 drm_i915_private_t *dev_priv = dev->dev_private; 728 drm_i915_private_t *dev_priv = dev->dev_private;
@@ -717,18 +731,18 @@ void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp)
717} 731}
718 732
719drm_ioctl_desc_t i915_ioctls[] = { 733drm_ioctl_desc_t i915_ioctls[] = {
720 [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, 1, 1}, 734 [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
721 [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, 1, 0}, 735 [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, DRM_AUTH},
722 [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, 1, 0}, 736 [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, DRM_AUTH},
723 [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, 1, 0}, 737 [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, DRM_AUTH},
724 [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, 1, 0}, 738 [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, DRM_AUTH},
725 [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, 1, 0}, 739 [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, DRM_AUTH},
726 [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, 1, 0}, 740 [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, DRM_AUTH},
727 [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, 1, 1}, 741 [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
728 [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, 1, 0}, 742 [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH},
729 [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, 1, 0}, 743 [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH},
730 [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, 1, 1}, 744 [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
731 [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, 1, 0} 745 [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH}
732}; 746};
733 747
734int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); 748int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h
index 23e027d29080..77412ddac007 100644
--- a/drivers/char/drm/i915_drm.h
+++ b/drivers/char/drm/i915_drm.h
@@ -1,5 +1,4 @@
1/************************************************************************** 1/*
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 2 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved. 3 * All Rights Reserved.
5 * 4 *
@@ -23,7 +22,7 @@
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 * 24 *
26 **************************************************************************/ 25 */
27 26
28#ifndef _I915_DRM_H_ 27#ifndef _I915_DRM_H_
29#define _I915_DRM_H_ 28#define _I915_DRM_H_
@@ -152,6 +151,7 @@ typedef struct drm_i915_irq_wait {
152 */ 151 */
153#define I915_PARAM_IRQ_ACTIVE 1 152#define I915_PARAM_IRQ_ACTIVE 1
154#define I915_PARAM_ALLOW_BATCHBUFFER 2 153#define I915_PARAM_ALLOW_BATCHBUFFER 2
154#define I915_PARAM_LAST_DISPATCH 3
155 155
156typedef struct drm_i915_getparam { 156typedef struct drm_i915_getparam {
157 int param; 157 int param;
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
index 0508240f4e3b..8e2e6095c4b3 100644
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -1,6 +1,6 @@
1/* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*- 1/* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*-
2 */ 2 */
3/************************************************************************** 3/*
4 * 4 *
5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * All Rights Reserved. 6 * All Rights Reserved.
@@ -25,7 +25,7 @@
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * 27 *
28 **************************************************************************/ 28 */
29 29
30#include "drmP.h" 30#include "drmP.h"
31#include "drm.h" 31#include "drm.h"
@@ -34,48 +34,22 @@
34 34
35#include "drm_pciids.h" 35#include "drm_pciids.h"
36 36
37static int postinit(struct drm_device *dev, unsigned long flags)
38{
39 dev->counters += 4;
40 dev->types[6] = _DRM_STAT_IRQ;
41 dev->types[7] = _DRM_STAT_PRIMARY;
42 dev->types[8] = _DRM_STAT_SECONDARY;
43 dev->types[9] = _DRM_STAT_DMA;
44
45 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
46 DRIVER_NAME,
47 DRIVER_MAJOR,
48 DRIVER_MINOR,
49 DRIVER_PATCHLEVEL,
50 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
51 );
52 return 0;
53}
54
55static int version(drm_version_t * version)
56{
57 int len;
58
59 version->version_major = DRIVER_MAJOR;
60 version->version_minor = DRIVER_MINOR;
61 version->version_patchlevel = DRIVER_PATCHLEVEL;
62 DRM_COPY(version->name, DRIVER_NAME);
63 DRM_COPY(version->date, DRIVER_DATE);
64 DRM_COPY(version->desc, DRIVER_DESC);
65 return 0;
66}
67
68static struct pci_device_id pciidlist[] = { 37static struct pci_device_id pciidlist[] = {
69 i915_PCI_IDS 38 i915_PCI_IDS
70}; 39};
71 40
72static struct drm_driver driver = { 41static struct drm_driver driver = {
42 /* don't use mtrr's here, the Xserver or user space app should
43 * deal with them for intel hardware.
44 */
73 .driver_features = 45 .driver_features =
74 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | 46 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
75 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, 47 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
76 .pretakedown = i915_driver_pretakedown, 48 .load = i915_driver_load,
77 .prerelease = i915_driver_prerelease, 49 .lastclose = i915_driver_lastclose,
50 .preclose = i915_driver_preclose,
78 .device_is_agp = i915_driver_device_is_agp, 51 .device_is_agp = i915_driver_device_is_agp,
52 .vblank_wait = i915_driver_vblank_wait,
79 .irq_preinstall = i915_driver_irq_preinstall, 53 .irq_preinstall = i915_driver_irq_preinstall,
80 .irq_postinstall = i915_driver_irq_postinstall, 54 .irq_postinstall = i915_driver_irq_postinstall,
81 .irq_uninstall = i915_driver_irq_uninstall, 55 .irq_uninstall = i915_driver_irq_uninstall,
@@ -83,8 +57,6 @@ static struct drm_driver driver = {
83 .reclaim_buffers = drm_core_reclaim_buffers, 57 .reclaim_buffers = drm_core_reclaim_buffers,
84 .get_map_ofs = drm_core_get_map_ofs, 58 .get_map_ofs = drm_core_get_map_ofs,
85 .get_reg_ofs = drm_core_get_reg_ofs, 59 .get_reg_ofs = drm_core_get_reg_ofs,
86 .postinit = postinit,
87 .version = version,
88 .ioctls = i915_ioctls, 60 .ioctls = i915_ioctls,
89 .fops = { 61 .fops = {
90 .owner = THIS_MODULE, 62 .owner = THIS_MODULE,
@@ -97,11 +69,19 @@ static struct drm_driver driver = {
97#ifdef CONFIG_COMPAT 69#ifdef CONFIG_COMPAT
98 .compat_ioctl = i915_compat_ioctl, 70 .compat_ioctl = i915_compat_ioctl,
99#endif 71#endif
100 }, 72 },
73
101 .pci_driver = { 74 .pci_driver = {
102 .name = DRIVER_NAME, 75 .name = DRIVER_NAME,
103 .id_table = pciidlist, 76 .id_table = pciidlist,
104 } 77 },
78
79 .name = DRIVER_NAME,
80 .desc = DRIVER_DESC,
81 .date = DRIVER_DATE,
82 .major = DRIVER_MAJOR,
83 .minor = DRIVER_MINOR,
84 .patchlevel = DRIVER_PATCHLEVEL,
105}; 85};
106 86
107static int __init i915_init(void) 87static int __init i915_init(void)
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index 17e457c73dc7..c6c71b45f101 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -1,6 +1,6 @@
1/* i915_drv.h -- Private header for the I915 driver -*- linux-c -*- 1/* i915_drv.h -- Private header for the I915 driver -*- linux-c -*-
2 */ 2 */
3/************************************************************************** 3/*
4 * 4 *
5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * All Rights Reserved. 6 * All Rights Reserved.
@@ -25,7 +25,7 @@
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * 27 *
28 **************************************************************************/ 28 */
29 29
30#ifndef _I915_DRV_H_ 30#ifndef _I915_DRV_H_
31#define _I915_DRV_H_ 31#define _I915_DRV_H_
@@ -37,21 +37,18 @@
37 37
38#define DRIVER_NAME "i915" 38#define DRIVER_NAME "i915"
39#define DRIVER_DESC "Intel Graphics" 39#define DRIVER_DESC "Intel Graphics"
40#define DRIVER_DATE "20040405" 40#define DRIVER_DATE "20051209"
41 41
42/* Interface history: 42/* Interface history:
43 * 43 *
44 * 1.1: Original. 44 * 1.1: Original.
45 * 1.2: Add Power Management
46 * 1.3: Add vblank support
45 */ 47 */
46#define DRIVER_MAJOR 1 48#define DRIVER_MAJOR 1
47#define DRIVER_MINOR 1 49#define DRIVER_MINOR 3
48#define DRIVER_PATCHLEVEL 0 50#define DRIVER_PATCHLEVEL 0
49 51
50/* We use our own dma mechanisms, not the drm template code. However,
51 * the shared IRQ code is useful to us:
52 */
53#define __HAVE_PM 1
54
55typedef struct _drm_i915_ring_buffer { 52typedef struct _drm_i915_ring_buffer {
56 int tail_mask; 53 int tail_mask;
57 unsigned long Start; 54 unsigned long Start;
@@ -97,6 +94,7 @@ typedef struct drm_i915_private {
97 int tex_lru_log_granularity; 94 int tex_lru_log_granularity;
98 int allow_batchbuffer; 95 int allow_batchbuffer;
99 struct mem_block *agp_heap; 96 struct mem_block *agp_heap;
97 unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
100} drm_i915_private_t; 98} drm_i915_private_t;
101 99
102extern drm_ioctl_desc_t i915_ioctls[]; 100extern drm_ioctl_desc_t i915_ioctls[];
@@ -104,14 +102,18 @@ extern int i915_max_ioctl;
104 102
105 /* i915_dma.c */ 103 /* i915_dma.c */
106extern void i915_kernel_lost_context(drm_device_t * dev); 104extern void i915_kernel_lost_context(drm_device_t * dev);
107extern void i915_driver_pretakedown(drm_device_t * dev); 105extern int i915_driver_load(struct drm_device *, unsigned long flags);
108extern void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp); 106extern void i915_driver_lastclose(drm_device_t * dev);
107extern void i915_driver_preclose(drm_device_t * dev, DRMFILE filp);
109extern int i915_driver_device_is_agp(drm_device_t * dev); 108extern int i915_driver_device_is_agp(drm_device_t * dev);
109extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
110 unsigned long arg);
110 111
111/* i915_irq.c */ 112/* i915_irq.c */
112extern int i915_irq_emit(DRM_IOCTL_ARGS); 113extern int i915_irq_emit(DRM_IOCTL_ARGS);
113extern int i915_irq_wait(DRM_IOCTL_ARGS); 114extern int i915_irq_wait(DRM_IOCTL_ARGS);
114 115
116extern int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence);
115extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); 117extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
116extern void i915_driver_irq_preinstall(drm_device_t * dev); 118extern void i915_driver_irq_preinstall(drm_device_t * dev);
117extern void i915_driver_irq_postinstall(drm_device_t * dev); 119extern void i915_driver_irq_postinstall(drm_device_t * dev);
@@ -125,13 +127,10 @@ extern void i915_mem_takedown(struct mem_block **heap);
125extern void i915_mem_release(drm_device_t * dev, 127extern void i915_mem_release(drm_device_t * dev,
126 DRMFILE filp, struct mem_block *heap); 128 DRMFILE filp, struct mem_block *heap);
127 129
128extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, 130#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
129 unsigned long arg); 131#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
130 132#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
131#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, reg) 133#define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val))
132#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val)
133#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg)
134#define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, reg, val)
135 134
136#define I915_VERBOSE 0 135#define I915_VERBOSE 0
137 136
@@ -195,6 +194,13 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);
195#define PPCR 0x61204 194#define PPCR 0x61204
196#define PPCR_ON (1<<0) 195#define PPCR_ON (1<<0)
197 196
197#define DVOB 0x61140
198#define DVOB_ON (1<<31)
199#define DVOC 0x61160
200#define DVOC_ON (1<<31)
201#define LVDS 0x61180
202#define LVDS_ON (1<<31)
203
198#define ADPA 0x61100 204#define ADPA 0x61100
199#define ADPA_DPMS_MASK (~(3<<10)) 205#define ADPA_DPMS_MASK (~(3<<10))
200#define ADPA_DPMS_ON (0<<10) 206#define ADPA_DPMS_ON (0<<10)
@@ -258,4 +264,6 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);
258 264
259#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) 265#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
260 266
267#define READ_BREADCRUMB(dev_priv) (((u32 *)(dev_priv->hw_status_page))[5])
268
261#endif 269#endif
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index 4fa448ee846b..a1381c61aa63 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -1,7 +1,6 @@
1/* i915_dma.c -- DMA support for the I915 -*- linux-c -*- 1/* i915_irq.c -- IRQ support for the I915 -*- linux-c -*-
2 */ 2 */
3/************************************************************************** 3/*
4 *
5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * All Rights Reserved. 5 * All Rights Reserved.
7 * 6 *
@@ -25,16 +24,18 @@
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * 26 *
28 **************************************************************************/ 27 */
29 28
30#include "drmP.h" 29#include "drmP.h"
31#include "drm.h" 30#include "drm.h"
32#include "i915_drm.h" 31#include "i915_drm.h"
33#include "i915_drv.h" 32#include "i915_drv.h"
34 33
35#define USER_INT_FLAG 0x2 34#define USER_INT_FLAG (1<<1)
35#define VSYNC_PIPEB_FLAG (1<<5)
36#define VSYNC_PIPEA_FLAG (1<<7)
37
36#define MAX_NOPID ((u32)~0) 38#define MAX_NOPID ((u32)~0)
37#define READ_BREADCRUMB(dev_priv) (((u32*)(dev_priv->hw_status_page))[5])
38 39
39irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) 40irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
40{ 41{
@@ -43,7 +44,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
43 u16 temp; 44 u16 temp;
44 45
45 temp = I915_READ16(I915REG_INT_IDENTITY_R); 46 temp = I915_READ16(I915REG_INT_IDENTITY_R);
46 temp &= USER_INT_FLAG; 47 temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG);
47 48
48 DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); 49 DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
49 50
@@ -51,7 +52,15 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
51 return IRQ_NONE; 52 return IRQ_NONE;
52 53
53 I915_WRITE16(I915REG_INT_IDENTITY_R, temp); 54 I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
54 DRM_WAKEUP(&dev_priv->irq_queue); 55
56 if (temp & USER_INT_FLAG)
57 DRM_WAKEUP(&dev_priv->irq_queue);
58
59 if (temp & VSYNC_PIPEA_FLAG) {
60 atomic_inc(&dev->vbl_received);
61 DRM_WAKEUP(&dev->vbl_queue);
62 drm_vbl_send_signals(dev);
63 }
55 64
56 return IRQ_HANDLED; 65 return IRQ_HANDLED;
57} 66}
@@ -102,6 +111,27 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr)
102 return ret; 111 return ret;
103} 112}
104 113
114int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
115{
116 drm_i915_private_t *dev_priv = dev->dev_private;
117 unsigned int cur_vblank;
118 int ret = 0;
119
120 if (!dev_priv) {
121 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
122 return DRM_ERR(EINVAL);
123 }
124
125 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
126 (((cur_vblank = atomic_read(&dev->vbl_received))
127 - *sequence) <= (1<<23)));
128
129 *sequence = cur_vblank;
130
131 return ret;
132}
133
134
105/* Needs the lock as it touches the ring. 135/* Needs the lock as it touches the ring.
106 */ 136 */
107int i915_irq_emit(DRM_IOCTL_ARGS) 137int i915_irq_emit(DRM_IOCTL_ARGS)
@@ -165,7 +195,7 @@ void i915_driver_irq_postinstall(drm_device_t * dev)
165{ 195{
166 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 196 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
167 197
168 I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG); 198 I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | VSYNC_PIPEA_FLAG);
169 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); 199 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
170} 200}
171 201
diff --git a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c
index 13176d136a99..ba87ff17ff64 100644
--- a/drivers/char/drm/i915_mem.c
+++ b/drivers/char/drm/i915_mem.c
@@ -1,7 +1,6 @@
1/* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*- 1/* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*-
2 */ 2 */
3/************************************************************************** 3/*
4 *
5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * All Rights Reserved. 5 * All Rights Reserved.
7 * 6 *
@@ -25,7 +24,7 @@
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * 26 *
28 **************************************************************************/ 27 */
29 28
30#include "drmP.h" 29#include "drmP.h"
31#include "drm.h" 30#include "drm.h"
diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c
index 70dc7f64b7b9..c2a4bac14521 100644
--- a/drivers/char/drm/mga_dma.c
+++ b/drivers/char/drm/mga_dma.c
@@ -44,7 +44,9 @@
44#define MGA_DEFAULT_USEC_TIMEOUT 10000 44#define MGA_DEFAULT_USEC_TIMEOUT 10000
45#define MGA_FREELIST_DEBUG 0 45#define MGA_FREELIST_DEBUG 0
46 46
47static int mga_do_cleanup_dma(drm_device_t * dev); 47#define MINIMAL_CLEANUP 0
48#define FULL_CLEANUP 1
49static int mga_do_cleanup_dma(drm_device_t *dev, int full_cleanup);
48 50
49/* ================================================================ 51/* ================================================================
50 * Engine control 52 * Engine control
@@ -391,7 +393,7 @@ int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf)
391 * DMA initialization, cleanup 393 * DMA initialization, cleanup
392 */ 394 */
393 395
394int mga_driver_preinit(drm_device_t * dev, unsigned long flags) 396int mga_driver_load(drm_device_t * dev, unsigned long flags)
395{ 397{
396 drm_mga_private_t *dev_priv; 398 drm_mga_private_t *dev_priv;
397 399
@@ -405,6 +407,14 @@ int mga_driver_preinit(drm_device_t * dev, unsigned long flags)
405 dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; 407 dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
406 dev_priv->chipset = flags; 408 dev_priv->chipset = flags;
407 409
410 dev_priv->mmio_base = drm_get_resource_start(dev, 1);
411 dev_priv->mmio_size = drm_get_resource_len(dev, 1);
412
413 dev->counters += 3;
414 dev->types[6] = _DRM_STAT_IRQ;
415 dev->types[7] = _DRM_STAT_PRIMARY;
416 dev->types[8] = _DRM_STAT_SECONDARY;
417
408 return 0; 418 return 0;
409} 419}
410 420
@@ -438,17 +448,19 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
438 drm_buf_desc_t req; 448 drm_buf_desc_t req;
439 drm_agp_mode_t mode; 449 drm_agp_mode_t mode;
440 drm_agp_info_t info; 450 drm_agp_info_t info;
451 drm_agp_buffer_t agp_req;
452 drm_agp_binding_t bind_req;
441 453
442 /* Acquire AGP. */ 454 /* Acquire AGP. */
443 err = drm_agp_acquire(dev); 455 err = drm_agp_acquire(dev);
444 if (err) { 456 if (err) {
445 DRM_ERROR("Unable to acquire AGP\n"); 457 DRM_ERROR("Unable to acquire AGP: %d\n", err);
446 return err; 458 return err;
447 } 459 }
448 460
449 err = drm_agp_info(dev, &info); 461 err = drm_agp_info(dev, &info);
450 if (err) { 462 if (err) {
451 DRM_ERROR("Unable to get AGP info\n"); 463 DRM_ERROR("Unable to get AGP info: %d\n", err);
452 return err; 464 return err;
453 } 465 }
454 466
@@ -472,18 +484,24 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
472 } 484 }
473 485
474 /* Allocate and bind AGP memory. */ 486 /* Allocate and bind AGP memory. */
475 dev_priv->agp_pages = agp_size / PAGE_SIZE; 487 agp_req.size = agp_size;
476 dev_priv->agp_mem = drm_alloc_agp(dev, dev_priv->agp_pages, 0); 488 agp_req.type = 0;
477 if (dev_priv->agp_mem == NULL) { 489 err = drm_agp_alloc(dev, &agp_req);
478 dev_priv->agp_pages = 0; 490 if (err) {
491 dev_priv->agp_size = 0;
479 DRM_ERROR("Unable to allocate %uMB AGP memory\n", 492 DRM_ERROR("Unable to allocate %uMB AGP memory\n",
480 dma_bs->agp_size); 493 dma_bs->agp_size);
481 return DRM_ERR(ENOMEM); 494 return err;
482 } 495 }
496
497 dev_priv->agp_size = agp_size;
498 dev_priv->agp_handle = agp_req.handle;
483 499
484 err = drm_bind_agp(dev_priv->agp_mem, 0); 500 bind_req.handle = agp_req.handle;
501 bind_req.offset = 0;
502 err = drm_agp_bind(dev, &bind_req);
485 if (err) { 503 if (err) {
486 DRM_ERROR("Unable to bind AGP memory\n"); 504 DRM_ERROR("Unable to bind AGP memory: %d\n", err);
487 return err; 505 return err;
488 } 506 }
489 507
@@ -497,7 +515,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
497 err = drm_addmap(dev, offset, warp_size, 515 err = drm_addmap(dev, offset, warp_size,
498 _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp); 516 _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp);
499 if (err) { 517 if (err) {
500 DRM_ERROR("Unable to map WARP microcode\n"); 518 DRM_ERROR("Unable to map WARP microcode: %d\n", err);
501 return err; 519 return err;
502 } 520 }
503 521
@@ -505,7 +523,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
505 err = drm_addmap(dev, offset, dma_bs->primary_size, 523 err = drm_addmap(dev, offset, dma_bs->primary_size,
506 _DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary); 524 _DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary);
507 if (err) { 525 if (err) {
508 DRM_ERROR("Unable to map primary DMA region\n"); 526 DRM_ERROR("Unable to map primary DMA region: %d\n", err);
509 return err; 527 return err;
510 } 528 }
511 529
@@ -513,7 +531,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
513 err = drm_addmap(dev, offset, secondary_size, 531 err = drm_addmap(dev, offset, secondary_size,
514 _DRM_AGP, 0, &dev->agp_buffer_map); 532 _DRM_AGP, 0, &dev->agp_buffer_map);
515 if (err) { 533 if (err) {
516 DRM_ERROR("Unable to map secondary DMA region\n"); 534 DRM_ERROR("Unable to map secondary DMA region: %d\n", err);
517 return err; 535 return err;
518 } 536 }
519 537
@@ -525,15 +543,29 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
525 543
526 err = drm_addbufs_agp(dev, &req); 544 err = drm_addbufs_agp(dev, &req);
527 if (err) { 545 if (err) {
528 DRM_ERROR("Unable to add secondary DMA buffers\n"); 546 DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err);
529 return err; 547 return err;
530 } 548 }
531 549
550 {
551 drm_map_list_t *_entry;
552 unsigned long agp_token = 0;
553
554 list_for_each_entry(_entry, &dev->maplist->head, head) {
555 if (_entry->map == dev->agp_buffer_map)
556 agp_token = _entry->user_token;
557 }
558 if (!agp_token)
559 return -EFAULT;
560
561 dev->agp_buffer_token = agp_token;
562 }
563
532 offset += secondary_size; 564 offset += secondary_size;
533 err = drm_addmap(dev, offset, agp_size - offset, 565 err = drm_addmap(dev, offset, agp_size - offset,
534 _DRM_AGP, 0, &dev_priv->agp_textures); 566 _DRM_AGP, 0, &dev_priv->agp_textures);
535 if (err) { 567 if (err) {
536 DRM_ERROR("Unable to map AGP texture region\n"); 568 DRM_ERROR("Unable to map AGP texture region %d\n", err);
537 return err; 569 return err;
538 } 570 }
539 571
@@ -603,7 +635,8 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
603 err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT, 635 err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT,
604 _DRM_READ_ONLY, &dev_priv->warp); 636 _DRM_READ_ONLY, &dev_priv->warp);
605 if (err != 0) { 637 if (err != 0) {
606 DRM_ERROR("Unable to create mapping for WARP microcode\n"); 638 DRM_ERROR("Unable to create mapping for WARP microcode: %d\n",
639 err);
607 return err; 640 return err;
608 } 641 }
609 642
@@ -622,7 +655,7 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
622 } 655 }
623 656
624 if (err != 0) { 657 if (err != 0) {
625 DRM_ERROR("Unable to allocate primary DMA region\n"); 658 DRM_ERROR("Unable to allocate primary DMA region: %d\n", err);
626 return DRM_ERR(ENOMEM); 659 return DRM_ERR(ENOMEM);
627 } 660 }
628 661
@@ -646,7 +679,7 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
646 } 679 }
647 680
648 if (bin_count == 0) { 681 if (bin_count == 0) {
649 DRM_ERROR("Unable to add secondary DMA buffers\n"); 682 DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err);
650 return err; 683 return err;
651 } 684 }
652 685
@@ -682,7 +715,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev,
682 err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size, 715 err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size,
683 _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio); 716 _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio);
684 if (err) { 717 if (err) {
685 DRM_ERROR("Unable to map MMIO region\n"); 718 DRM_ERROR("Unable to map MMIO region: %d\n", err);
686 return err; 719 return err;
687 } 720 }
688 721
@@ -690,7 +723,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev,
690 _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL, 723 _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL,
691 &dev_priv->status); 724 &dev_priv->status);
692 if (err) { 725 if (err) {
693 DRM_ERROR("Unable to map status region\n"); 726 DRM_ERROR("Unable to map status region: %d\n", err);
694 return err; 727 return err;
695 } 728 }
696 729
@@ -708,7 +741,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev,
708 */ 741 */
709 742
710 if (err) { 743 if (err) {
711 mga_do_cleanup_dma(dev); 744 mga_do_cleanup_dma(dev, MINIMAL_CLEANUP);
712 } 745 }
713 746
714 /* Not only do we want to try and initialized PCI cards for PCI DMA, 747 /* Not only do we want to try and initialized PCI cards for PCI DMA,
@@ -731,35 +764,32 @@ int mga_dma_bootstrap(DRM_IOCTL_ARGS)
731 DRM_DEVICE; 764 DRM_DEVICE;
732 drm_mga_dma_bootstrap_t bootstrap; 765 drm_mga_dma_bootstrap_t bootstrap;
733 int err; 766 int err;
767 static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 };
768 const drm_mga_private_t *const dev_priv =
769 (drm_mga_private_t *) dev->dev_private;
734 770
735 DRM_COPY_FROM_USER_IOCTL(bootstrap, 771 DRM_COPY_FROM_USER_IOCTL(bootstrap,
736 (drm_mga_dma_bootstrap_t __user *) data, 772 (drm_mga_dma_bootstrap_t __user *) data,
737 sizeof(bootstrap)); 773 sizeof(bootstrap));
738 774
739 err = mga_do_dma_bootstrap(dev, &bootstrap); 775 err = mga_do_dma_bootstrap(dev, &bootstrap);
740 if (!err) { 776 if (err) {
741 static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 }; 777 mga_do_cleanup_dma(dev, FULL_CLEANUP);
742 const drm_mga_private_t *const dev_priv = 778 return err;
743 (drm_mga_private_t *) dev->dev_private; 779 }
744
745 if (dev_priv->agp_textures != NULL) {
746 bootstrap.texture_handle =
747 dev_priv->agp_textures->offset;
748 bootstrap.texture_size = dev_priv->agp_textures->size;
749 } else {
750 bootstrap.texture_handle = 0;
751 bootstrap.texture_size = 0;
752 }
753 780
754 bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07]; 781 if (dev_priv->agp_textures != NULL) {
755 if (DRM_COPY_TO_USER((void __user *)data, &bootstrap, 782 bootstrap.texture_handle = dev_priv->agp_textures->offset;
756 sizeof(bootstrap))) { 783 bootstrap.texture_size = dev_priv->agp_textures->size;
757 err = DRM_ERR(EFAULT);
758 }
759 } else { 784 } else {
760 mga_do_cleanup_dma(dev); 785 bootstrap.texture_handle = 0;
786 bootstrap.texture_size = 0;
761 } 787 }
762 788
789 bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07];
790 DRM_COPY_TO_USER_IOCTL((drm_mga_dma_bootstrap_t __user *)data,
791 bootstrap, sizeof(bootstrap));
792
763 return err; 793 return err;
764} 794}
765 795
@@ -853,13 +883,13 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
853 883
854 ret = mga_warp_install_microcode(dev_priv); 884 ret = mga_warp_install_microcode(dev_priv);
855 if (ret < 0) { 885 if (ret < 0) {
856 DRM_ERROR("failed to install WARP ucode!\n"); 886 DRM_ERROR("failed to install WARP ucode!: %d\n", ret);
857 return ret; 887 return ret;
858 } 888 }
859 889
860 ret = mga_warp_init(dev_priv); 890 ret = mga_warp_init(dev_priv);
861 if (ret < 0) { 891 if (ret < 0) {
862 DRM_ERROR("failed to init WARP engine!\n"); 892 DRM_ERROR("failed to init WARP engine!: %d\n", ret);
863 return ret; 893 return ret;
864 } 894 }
865 895
@@ -904,7 +934,7 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
904 return 0; 934 return 0;
905} 935}
906 936
907static int mga_do_cleanup_dma(drm_device_t * dev) 937static int mga_do_cleanup_dma(drm_device_t *dev, int full_cleanup)
908{ 938{
909 int err = 0; 939 int err = 0;
910 DRM_DEBUG("\n"); 940 DRM_DEBUG("\n");
@@ -932,31 +962,39 @@ static int mga_do_cleanup_dma(drm_device_t * dev)
932 962
933 if (dev_priv->used_new_dma_init) { 963 if (dev_priv->used_new_dma_init) {
934#if __OS_HAS_AGP 964#if __OS_HAS_AGP
935 if (dev_priv->agp_mem != NULL) { 965 if (dev_priv->agp_handle != 0) {
936 dev_priv->agp_textures = NULL; 966 drm_agp_binding_t unbind_req;
937 drm_unbind_agp(dev_priv->agp_mem); 967 drm_agp_buffer_t free_req;
968
969 unbind_req.handle = dev_priv->agp_handle;
970 drm_agp_unbind(dev, &unbind_req);
938 971
939 drm_free_agp(dev_priv->agp_mem, 972 free_req.handle = dev_priv->agp_handle;
940 dev_priv->agp_pages); 973 drm_agp_free(dev, &free_req);
941 dev_priv->agp_pages = 0; 974
942 dev_priv->agp_mem = NULL; 975 dev_priv->agp_textures = NULL;
976 dev_priv->agp_size = 0;
977 dev_priv->agp_handle = 0;
943 } 978 }
944 979
945 if ((dev->agp != NULL) && dev->agp->acquired) { 980 if ((dev->agp != NULL) && dev->agp->acquired) {
946 err = drm_agp_release(dev); 981 err = drm_agp_release(dev);
947 } 982 }
948#endif 983#endif
949 dev_priv->used_new_dma_init = 0;
950 } 984 }
951 985
952 dev_priv->warp = NULL; 986 dev_priv->warp = NULL;
953 dev_priv->primary = NULL; 987 dev_priv->primary = NULL;
954 dev_priv->mmio = NULL;
955 dev_priv->status = NULL;
956 dev_priv->sarea = NULL; 988 dev_priv->sarea = NULL;
957 dev_priv->sarea_priv = NULL; 989 dev_priv->sarea_priv = NULL;
958 dev->agp_buffer_map = NULL; 990 dev->agp_buffer_map = NULL;
959 991
992 if (full_cleanup) {
993 dev_priv->mmio = NULL;
994 dev_priv->status = NULL;
995 dev_priv->used_new_dma_init = 0;
996 }
997
960 memset(&dev_priv->prim, 0, sizeof(dev_priv->prim)); 998 memset(&dev_priv->prim, 0, sizeof(dev_priv->prim));
961 dev_priv->warp_pipe = 0; 999 dev_priv->warp_pipe = 0;
962 memset(dev_priv->warp_pipe_phys, 0, 1000 memset(dev_priv->warp_pipe_phys, 0,
@@ -967,7 +1005,7 @@ static int mga_do_cleanup_dma(drm_device_t * dev)
967 } 1005 }
968 } 1006 }
969 1007
970 return err; 1008 return 0;
971} 1009}
972 1010
973int mga_dma_init(DRM_IOCTL_ARGS) 1011int mga_dma_init(DRM_IOCTL_ARGS)
@@ -985,11 +1023,11 @@ int mga_dma_init(DRM_IOCTL_ARGS)
985 case MGA_INIT_DMA: 1023 case MGA_INIT_DMA:
986 err = mga_do_init_dma(dev, &init); 1024 err = mga_do_init_dma(dev, &init);
987 if (err) { 1025 if (err) {
988 (void)mga_do_cleanup_dma(dev); 1026 (void)mga_do_cleanup_dma(dev, FULL_CLEANUP);
989 } 1027 }
990 return err; 1028 return err;
991 case MGA_CLEANUP_DMA: 1029 case MGA_CLEANUP_DMA:
992 return mga_do_cleanup_dma(dev); 1030 return mga_do_cleanup_dma(dev, FULL_CLEANUP);
993 } 1031 }
994 1032
995 return DRM_ERR(EINVAL); 1033 return DRM_ERR(EINVAL);
@@ -1118,7 +1156,7 @@ int mga_dma_buffers(DRM_IOCTL_ARGS)
1118/** 1156/**
1119 * Called just before the module is unloaded. 1157 * Called just before the module is unloaded.
1120 */ 1158 */
1121int mga_driver_postcleanup(drm_device_t * dev) 1159int mga_driver_unload(drm_device_t * dev)
1122{ 1160{
1123 drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER); 1161 drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
1124 dev->dev_private = NULL; 1162 dev->dev_private = NULL;
@@ -1129,9 +1167,9 @@ int mga_driver_postcleanup(drm_device_t * dev)
1129/** 1167/**
1130 * Called when the last opener of the device is closed. 1168 * Called when the last opener of the device is closed.
1131 */ 1169 */
1132void mga_driver_pretakedown(drm_device_t * dev) 1170void mga_driver_lastclose(drm_device_t * dev)
1133{ 1171{
1134 mga_do_cleanup_dma(dev); 1172 mga_do_cleanup_dma(dev, FULL_CLEANUP);
1135} 1173}
1136 1174
1137int mga_driver_dma_quiescent(drm_device_t * dev) 1175int mga_driver_dma_quiescent(drm_device_t * dev)
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
index 1713451a5cc6..9f7ed0e0351b 100644
--- a/drivers/char/drm/mga_drv.c
+++ b/drivers/char/drm/mga_drv.c
@@ -38,41 +38,6 @@
38#include "drm_pciids.h" 38#include "drm_pciids.h"
39 39
40static int mga_driver_device_is_agp(drm_device_t * dev); 40static int mga_driver_device_is_agp(drm_device_t * dev);
41static int postinit(struct drm_device *dev, unsigned long flags)
42{
43 drm_mga_private_t *const dev_priv =
44 (drm_mga_private_t *) dev->dev_private;
45
46 dev_priv->mmio_base = pci_resource_start(dev->pdev, 1);
47 dev_priv->mmio_size = pci_resource_len(dev->pdev, 1);
48
49 dev->counters += 3;
50 dev->types[6] = _DRM_STAT_IRQ;
51 dev->types[7] = _DRM_STAT_PRIMARY;
52 dev->types[8] = _DRM_STAT_SECONDARY;
53
54 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
55 DRIVER_NAME,
56 DRIVER_MAJOR,
57 DRIVER_MINOR,
58 DRIVER_PATCHLEVEL,
59 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
60 );
61 return 0;
62}
63
64static int version(drm_version_t * version)
65{
66 int len;
67
68 version->version_major = DRIVER_MAJOR;
69 version->version_minor = DRIVER_MINOR;
70 version->version_patchlevel = DRIVER_PATCHLEVEL;
71 DRM_COPY(version->name, DRIVER_NAME);
72 DRM_COPY(version->date, DRIVER_DATE);
73 DRM_COPY(version->desc, DRIVER_DESC);
74 return 0;
75}
76 41
77static struct pci_device_id pciidlist[] = { 42static struct pci_device_id pciidlist[] = {
78 mga_PCI_IDS 43 mga_PCI_IDS
@@ -80,12 +45,12 @@ static struct pci_device_id pciidlist[] = {
80 45
81static struct drm_driver driver = { 46static struct drm_driver driver = {
82 .driver_features = 47 .driver_features =
83 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | 48 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA |
84 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | 49 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
85 DRIVER_IRQ_VBL, 50 DRIVER_IRQ_VBL,
86 .preinit = mga_driver_preinit, 51 .load = mga_driver_load,
87 .postcleanup = mga_driver_postcleanup, 52 .unload = mga_driver_unload,
88 .pretakedown = mga_driver_pretakedown, 53 .lastclose = mga_driver_lastclose,
89 .dma_quiescent = mga_driver_dma_quiescent, 54 .dma_quiescent = mga_driver_dma_quiescent,
90 .device_is_agp = mga_driver_device_is_agp, 55 .device_is_agp = mga_driver_device_is_agp,
91 .vblank_wait = mga_driver_vblank_wait, 56 .vblank_wait = mga_driver_vblank_wait,
@@ -96,8 +61,6 @@ static struct drm_driver driver = {
96 .reclaim_buffers = drm_core_reclaim_buffers, 61 .reclaim_buffers = drm_core_reclaim_buffers,
97 .get_map_ofs = drm_core_get_map_ofs, 62 .get_map_ofs = drm_core_get_map_ofs,
98 .get_reg_ofs = drm_core_get_reg_ofs, 63 .get_reg_ofs = drm_core_get_reg_ofs,
99 .postinit = postinit,
100 .version = version,
101 .ioctls = mga_ioctls, 64 .ioctls = mga_ioctls,
102 .dma_ioctl = mga_dma_buffers, 65 .dma_ioctl = mga_dma_buffers,
103 .fops = { 66 .fops = {
@@ -113,9 +76,16 @@ static struct drm_driver driver = {
113#endif 76#endif
114 }, 77 },
115 .pci_driver = { 78 .pci_driver = {
116 .name = DRIVER_NAME, 79 .name = DRIVER_NAME,
117 .id_table = pciidlist, 80 .id_table = pciidlist,
118 } 81 },
82
83 .name = DRIVER_NAME,
84 .desc = DRIVER_DESC,
85 .date = DRIVER_DATE,
86 .major = DRIVER_MAJOR,
87 .minor = DRIVER_MINOR,
88 .patchlevel = DRIVER_PATCHLEVEL,
119}; 89};
120 90
121static int __init mga_init(void) 91static int __init mga_init(void)
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
index 461728e6a58a..6b0c53193506 100644
--- a/drivers/char/drm/mga_drv.h
+++ b/drivers/char/drm/mga_drv.h
@@ -38,11 +38,11 @@
38 38
39#define DRIVER_NAME "mga" 39#define DRIVER_NAME "mga"
40#define DRIVER_DESC "Matrox G200/G400" 40#define DRIVER_DESC "Matrox G200/G400"
41#define DRIVER_DATE "20050607" 41#define DRIVER_DATE "20051102"
42 42
43#define DRIVER_MAJOR 3 43#define DRIVER_MAJOR 3
44#define DRIVER_MINOR 2 44#define DRIVER_MINOR 2
45#define DRIVER_PATCHLEVEL 0 45#define DRIVER_PATCHLEVEL 1
46 46
47typedef struct drm_mga_primary_buffer { 47typedef struct drm_mga_primary_buffer {
48 u8 *start; 48 u8 *start;
@@ -144,22 +144,22 @@ typedef struct drm_mga_private {
144 drm_local_map_t *primary; 144 drm_local_map_t *primary;
145 drm_local_map_t *agp_textures; 145 drm_local_map_t *agp_textures;
146 146
147 DRM_AGP_MEM *agp_mem; 147 unsigned long agp_handle;
148 unsigned int agp_pages; 148 unsigned int agp_size;
149} drm_mga_private_t; 149} drm_mga_private_t;
150 150
151extern drm_ioctl_desc_t mga_ioctls[]; 151extern drm_ioctl_desc_t mga_ioctls[];
152extern int mga_max_ioctl; 152extern int mga_max_ioctl;
153 153
154 /* mga_dma.c */ 154 /* mga_dma.c */
155extern int mga_driver_preinit(drm_device_t * dev, unsigned long flags);
156extern int mga_dma_bootstrap(DRM_IOCTL_ARGS); 155extern int mga_dma_bootstrap(DRM_IOCTL_ARGS);
157extern int mga_dma_init(DRM_IOCTL_ARGS); 156extern int mga_dma_init(DRM_IOCTL_ARGS);
158extern int mga_dma_flush(DRM_IOCTL_ARGS); 157extern int mga_dma_flush(DRM_IOCTL_ARGS);
159extern int mga_dma_reset(DRM_IOCTL_ARGS); 158extern int mga_dma_reset(DRM_IOCTL_ARGS);
160extern int mga_dma_buffers(DRM_IOCTL_ARGS); 159extern int mga_dma_buffers(DRM_IOCTL_ARGS);
161extern int mga_driver_postcleanup(drm_device_t * dev); 160extern int mga_driver_load(drm_device_t *dev, unsigned long flags);
162extern void mga_driver_pretakedown(drm_device_t * dev); 161extern int mga_driver_unload(drm_device_t * dev);
162extern void mga_driver_lastclose(drm_device_t * dev);
163extern int mga_driver_dma_quiescent(drm_device_t * dev); 163extern int mga_driver_dma_quiescent(drm_device_t * dev);
164 164
165extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv); 165extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv);
diff --git a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c
index 47f54b5ae956..2837e669183a 100644
--- a/drivers/char/drm/mga_state.c
+++ b/drivers/char/drm/mga_state.c
@@ -1127,19 +1127,19 @@ static int mga_wait_fence(DRM_IOCTL_ARGS)
1127} 1127}
1128 1128
1129drm_ioctl_desc_t mga_ioctls[] = { 1129drm_ioctl_desc_t mga_ioctls[] = {
1130 [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, 1, 1}, 1130 [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1131 [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, 1, 0}, 1131 [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, DRM_AUTH},
1132 [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, 1, 0}, 1132 [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, DRM_AUTH},
1133 [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, 1, 0}, 1133 [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, DRM_AUTH},
1134 [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, 1, 0}, 1134 [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, DRM_AUTH},
1135 [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, 1, 0}, 1135 [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, DRM_AUTH},
1136 [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, 1, 0}, 1136 [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, DRM_AUTH},
1137 [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, 1, 0}, 1137 [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, DRM_AUTH},
1138 [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, 1, 0}, 1138 [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, DRM_AUTH},
1139 [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, 1, 0}, 1139 [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, DRM_AUTH},
1140 [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, 1, 0}, 1140 [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, DRM_AUTH},
1141 [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, 1, 0}, 1141 [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, DRM_AUTH},
1142 [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, 1, 1}, 1142 [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1143}; 1143};
1144 1144
1145int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); 1145int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls);
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c
index 7452753d4d01..db5a60450e68 100644
--- a/drivers/char/drm/r128_cce.c
+++ b/drivers/char/drm/r128_cce.c
@@ -1,6 +1,7 @@
1/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*- 1/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*-
2 * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com 2 * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com
3 * 3 */
4/*
4 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. 5 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 6 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved. 7 * All Rights Reserved.
@@ -559,7 +560,8 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init)
559 if (dev_priv->is_pci) { 560 if (dev_priv->is_pci) {
560#endif 561#endif
561 dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; 562 dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN;
562 dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr = 0; 563 dev_priv->gart_info.addr = NULL;
564 dev_priv->gart_info.bus_addr = 0;
563 dev_priv->gart_info.is_pcie = 0; 565 dev_priv->gart_info.is_pcie = 0;
564 if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { 566 if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
565 DRM_ERROR("failed to init PCI GART!\n"); 567 DRM_ERROR("failed to init PCI GART!\n");
@@ -601,15 +603,16 @@ int r128_do_cleanup_cce(drm_device_t * dev)
601 drm_core_ioremapfree(dev_priv->cce_ring, dev); 603 drm_core_ioremapfree(dev_priv->cce_ring, dev);
602 if (dev_priv->ring_rptr != NULL) 604 if (dev_priv->ring_rptr != NULL)
603 drm_core_ioremapfree(dev_priv->ring_rptr, dev); 605 drm_core_ioremapfree(dev_priv->ring_rptr, dev);
604 if (dev->agp_buffer_map != NULL) 606 if (dev->agp_buffer_map != NULL) {
605 drm_core_ioremapfree(dev->agp_buffer_map, dev); 607 drm_core_ioremapfree(dev->agp_buffer_map, dev);
608 dev->agp_buffer_map = NULL;
609 }
606 } else 610 } else
607#endif 611#endif
608 { 612 {
609 if (dev_priv->gart_info.bus_addr) 613 if (dev_priv->gart_info.bus_addr)
610 if (!drm_ati_pcigart_cleanup(dev, 614 if (!drm_ati_pcigart_cleanup(dev,
611 &dev_priv-> 615 &dev_priv->gart_info))
612 gart_info))
613 DRM_ERROR 616 DRM_ERROR
614 ("failed to cleanup PCI GART!\n"); 617 ("failed to cleanup PCI GART!\n");
615 } 618 }
diff --git a/drivers/char/drm/r128_drm.h b/drivers/char/drm/r128_drm.h
index 5ddc03202411..5d835b006f55 100644
--- a/drivers/char/drm/r128_drm.h
+++ b/drivers/char/drm/r128_drm.h
@@ -1,7 +1,7 @@
1/* r128_drm.h -- Public header for the r128 driver -*- linux-c -*- 1/* r128_drm.h -- Public header for the r128 driver -*- linux-c -*-
2 * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com 2 * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com
3 * 3 */
4 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. 4/* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
index 1661e7351402..e20450ae220e 100644
--- a/drivers/char/drm/r128_drv.c
+++ b/drivers/char/drm/r128_drv.c
@@ -37,31 +37,6 @@
37 37
38#include "drm_pciids.h" 38#include "drm_pciids.h"
39 39
40static int postinit(struct drm_device *dev, unsigned long flags)
41{
42 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
43 DRIVER_NAME,
44 DRIVER_MAJOR,
45 DRIVER_MINOR,
46 DRIVER_PATCHLEVEL,
47 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
48 );
49 return 0;
50}
51
52static int version(drm_version_t * version)
53{
54 int len;
55
56 version->version_major = DRIVER_MAJOR;
57 version->version_minor = DRIVER_MINOR;
58 version->version_patchlevel = DRIVER_PATCHLEVEL;
59 DRM_COPY(version->name, DRIVER_NAME);
60 DRM_COPY(version->date, DRIVER_DATE);
61 DRM_COPY(version->desc, DRIVER_DESC);
62 return 0;
63}
64
65static struct pci_device_id pciidlist[] = { 40static struct pci_device_id pciidlist[] = {
66 r128_PCI_IDS 41 r128_PCI_IDS
67}; 42};
@@ -72,8 +47,8 @@ static struct drm_driver driver = {
72 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | 47 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
73 DRIVER_IRQ_VBL, 48 DRIVER_IRQ_VBL,
74 .dev_priv_size = sizeof(drm_r128_buf_priv_t), 49 .dev_priv_size = sizeof(drm_r128_buf_priv_t),
75 .prerelease = r128_driver_prerelease, 50 .preclose = r128_driver_preclose,
76 .pretakedown = r128_driver_pretakedown, 51 .lastclose = r128_driver_lastclose,
77 .vblank_wait = r128_driver_vblank_wait, 52 .vblank_wait = r128_driver_vblank_wait,
78 .irq_preinstall = r128_driver_irq_preinstall, 53 .irq_preinstall = r128_driver_irq_preinstall,
79 .irq_postinstall = r128_driver_irq_postinstall, 54 .irq_postinstall = r128_driver_irq_postinstall,
@@ -82,8 +57,6 @@ static struct drm_driver driver = {
82 .reclaim_buffers = drm_core_reclaim_buffers, 57 .reclaim_buffers = drm_core_reclaim_buffers,
83 .get_map_ofs = drm_core_get_map_ofs, 58 .get_map_ofs = drm_core_get_map_ofs,
84 .get_reg_ofs = drm_core_get_reg_ofs, 59 .get_reg_ofs = drm_core_get_reg_ofs,
85 .postinit = postinit,
86 .version = version,
87 .ioctls = r128_ioctls, 60 .ioctls = r128_ioctls,
88 .dma_ioctl = r128_cce_buffers, 61 .dma_ioctl = r128_cce_buffers,
89 .fops = { 62 .fops = {
@@ -97,12 +70,19 @@ static struct drm_driver driver = {
97#ifdef CONFIG_COMPAT 70#ifdef CONFIG_COMPAT
98 .compat_ioctl = r128_compat_ioctl, 71 .compat_ioctl = r128_compat_ioctl,
99#endif 72#endif
100 } 73 },
101 , 74
102 .pci_driver = { 75 .pci_driver = {
103 .name = DRIVER_NAME, 76 .name = DRIVER_NAME,
104 .id_table = pciidlist, 77 .id_table = pciidlist,
105 } 78 },
79
80 .name = DRIVER_NAME,
81 .desc = DRIVER_DESC,
82 .date = DRIVER_DATE,
83 .major = DRIVER_MAJOR,
84 .minor = DRIVER_MINOR,
85 .patchlevel = DRIVER_PATCHLEVEL,
106}; 86};
107 87
108static int __init r128_init(void) 88static int __init r128_init(void)
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
index 5c79e40eb88f..94abffb2cca5 100644
--- a/drivers/char/drm/r128_drv.h
+++ b/drivers/char/drm/r128_drv.h
@@ -1,7 +1,7 @@
1/* r128_drv.h -- Private header for r128 driver -*- linux-c -*- 1/* r128_drv.h -- Private header for r128 driver -*- linux-c -*-
2 * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com 2 * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com
3 * 3 */
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. 4/* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -154,8 +154,8 @@ extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
154extern void r128_driver_irq_preinstall(drm_device_t * dev); 154extern void r128_driver_irq_preinstall(drm_device_t * dev);
155extern void r128_driver_irq_postinstall(drm_device_t * dev); 155extern void r128_driver_irq_postinstall(drm_device_t * dev);
156extern void r128_driver_irq_uninstall(drm_device_t * dev); 156extern void r128_driver_irq_uninstall(drm_device_t * dev);
157extern void r128_driver_pretakedown(drm_device_t * dev); 157extern void r128_driver_lastclose(drm_device_t * dev);
158extern void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp); 158extern void r128_driver_preclose(drm_device_t * dev, DRMFILE filp);
159 159
160extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, 160extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
161 unsigned long arg); 161 unsigned long arg);
diff --git a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c
index 27eb0e31bd3b..87f8ca2b0685 100644
--- a/drivers/char/drm/r128_irq.c
+++ b/drivers/char/drm/r128_irq.c
@@ -1,5 +1,5 @@
1/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- 1/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- */
2 * 2/*
3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 * 4 *
5 * The Weather Channel (TM) funded Tungsten Graphics to develop the 5 * The Weather Channel (TM) funded Tungsten Graphics to develop the
diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c
index 14479cc08a57..caeecc2c36da 100644
--- a/drivers/char/drm/r128_state.c
+++ b/drivers/char/drm/r128_state.c
@@ -1,7 +1,7 @@
1/* r128_state.c -- State support for r128 -*- linux-c -*- 1/* r128_state.c -- State support for r128 -*- linux-c -*-
2 * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com 2 * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com
3 * 3 */
4 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 4/* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a 7 * Permission is hereby granted, free of charge, to any person obtaining a
@@ -1674,7 +1674,7 @@ static int r128_getparam(DRM_IOCTL_ARGS)
1674 return 0; 1674 return 0;
1675} 1675}
1676 1676
1677void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp) 1677void r128_driver_preclose(drm_device_t * dev, DRMFILE filp)
1678{ 1678{
1679 if (dev->dev_private) { 1679 if (dev->dev_private) {
1680 drm_r128_private_t *dev_priv = dev->dev_private; 1680 drm_r128_private_t *dev_priv = dev->dev_private;
@@ -1684,29 +1684,29 @@ void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp)
1684 } 1684 }
1685} 1685}
1686 1686
1687void r128_driver_pretakedown(drm_device_t * dev) 1687void r128_driver_lastclose(drm_device_t * dev)
1688{ 1688{
1689 r128_do_cleanup_cce(dev); 1689 r128_do_cleanup_cce(dev);
1690} 1690}
1691 1691
1692drm_ioctl_desc_t r128_ioctls[] = { 1692drm_ioctl_desc_t r128_ioctls[] = {
1693 [DRM_IOCTL_NR(DRM_R128_INIT)] = {r128_cce_init, 1, 1}, 1693 [DRM_IOCTL_NR(DRM_R128_INIT)] = {r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1694 [DRM_IOCTL_NR(DRM_R128_CCE_START)] = {r128_cce_start, 1, 1}, 1694 [DRM_IOCTL_NR(DRM_R128_CCE_START)] = {r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1695 [DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = {r128_cce_stop, 1, 1}, 1695 [DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = {r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1696 [DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = {r128_cce_reset, 1, 1}, 1696 [DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = {r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1697 [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = {r128_cce_idle, 1, 0}, 1697 [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = {r128_cce_idle, DRM_AUTH},
1698 [DRM_IOCTL_NR(DRM_R128_RESET)] = {r128_engine_reset, 1, 0}, 1698 [DRM_IOCTL_NR(DRM_R128_RESET)] = {r128_engine_reset, DRM_AUTH},
1699 [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = {r128_fullscreen, 1, 0}, 1699 [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = {r128_fullscreen, DRM_AUTH},
1700 [DRM_IOCTL_NR(DRM_R128_SWAP)] = {r128_cce_swap, 1, 0}, 1700 [DRM_IOCTL_NR(DRM_R128_SWAP)] = {r128_cce_swap, DRM_AUTH},
1701 [DRM_IOCTL_NR(DRM_R128_FLIP)] = {r128_cce_flip, 1, 0}, 1701 [DRM_IOCTL_NR(DRM_R128_FLIP)] = {r128_cce_flip, DRM_AUTH},
1702 [DRM_IOCTL_NR(DRM_R128_CLEAR)] = {r128_cce_clear, 1, 0}, 1702 [DRM_IOCTL_NR(DRM_R128_CLEAR)] = {r128_cce_clear, DRM_AUTH},
1703 [DRM_IOCTL_NR(DRM_R128_VERTEX)] = {r128_cce_vertex, 1, 0}, 1703 [DRM_IOCTL_NR(DRM_R128_VERTEX)] = {r128_cce_vertex, DRM_AUTH},
1704 [DRM_IOCTL_NR(DRM_R128_INDICES)] = {r128_cce_indices, 1, 0}, 1704 [DRM_IOCTL_NR(DRM_R128_INDICES)] = {r128_cce_indices, DRM_AUTH},
1705 [DRM_IOCTL_NR(DRM_R128_BLIT)] = {r128_cce_blit, 1, 0}, 1705 [DRM_IOCTL_NR(DRM_R128_BLIT)] = {r128_cce_blit, DRM_AUTH},
1706 [DRM_IOCTL_NR(DRM_R128_DEPTH)] = {r128_cce_depth, 1, 0}, 1706 [DRM_IOCTL_NR(DRM_R128_DEPTH)] = {r128_cce_depth, DRM_AUTH},
1707 [DRM_IOCTL_NR(DRM_R128_STIPPLE)] = {r128_cce_stipple, 1, 0}, 1707 [DRM_IOCTL_NR(DRM_R128_STIPPLE)] = {r128_cce_stipple, DRM_AUTH},
1708 [DRM_IOCTL_NR(DRM_R128_INDIRECT)] = {r128_cce_indirect, 1, 1}, 1708 [DRM_IOCTL_NR(DRM_R128_INDIRECT)] = {r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1709 [DRM_IOCTL_NR(DRM_R128_GETPARAM)] = {r128_getparam, 1, 0}, 1709 [DRM_IOCTL_NR(DRM_R128_GETPARAM)] = {r128_getparam, DRM_AUTH},
1710}; 1710};
1711 1711
1712int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); 1712int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls);
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
index 3a1ac5f78b43..291dbf4c8186 100644
--- a/drivers/char/drm/r300_cmdbuf.c
+++ b/drivers/char/drm/r300_cmdbuf.c
@@ -52,8 +52,8 @@ static const int r300_cliprect_cntl[4] = {
52 * Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command 52 * Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command
53 * buffer, starting with index n. 53 * buffer, starting with index n.
54 */ 54 */
55static int r300_emit_cliprects(drm_radeon_private_t * dev_priv, 55static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
56 drm_radeon_kcmd_buffer_t * cmdbuf, int n) 56 drm_radeon_kcmd_buffer_t *cmdbuf, int n)
57{ 57{
58 drm_clip_rect_t box; 58 drm_clip_rect_t box;
59 int nr; 59 int nr;
@@ -216,6 +216,7 @@ void r300_init_reg_flags(void)
216 ADD_RANGE(R300_TX_UNK1_0, 16); 216 ADD_RANGE(R300_TX_UNK1_0, 16);
217 ADD_RANGE(R300_TX_SIZE_0, 16); 217 ADD_RANGE(R300_TX_SIZE_0, 16);
218 ADD_RANGE(R300_TX_FORMAT_0, 16); 218 ADD_RANGE(R300_TX_FORMAT_0, 16);
219 ADD_RANGE(R300_TX_PITCH_0, 16);
219 /* Texture offset is dangerous and needs more checking */ 220 /* Texture offset is dangerous and needs more checking */
220 ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET); 221 ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET);
221 ADD_RANGE(R300_TX_UNK4_0, 16); 222 ADD_RANGE(R300_TX_UNK4_0, 16);
@@ -242,7 +243,7 @@ static __inline__ int r300_check_range(unsigned reg, int count)
242 243
243 /* we expect offsets passed to the framebuffer to be either within video memory or 244 /* we expect offsets passed to the framebuffer to be either within video memory or
244 within AGP space */ 245 within AGP space */
245static __inline__ int r300_check_offset(drm_radeon_private_t * dev_priv, 246static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv,
246 u32 offset) 247 u32 offset)
247{ 248{
248 /* we realy want to check against end of video aperture 249 /* we realy want to check against end of video aperture
@@ -317,8 +318,8 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
317 * 318 *
318 * Note that checks are performed on contents and addresses of the registers 319 * Note that checks are performed on contents and addresses of the registers
319 */ 320 */
320static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv, 321static __inline__ int r300_emit_packet0(drm_radeon_private_t *dev_priv,
321 drm_radeon_kcmd_buffer_t * cmdbuf, 322 drm_radeon_kcmd_buffer_t *cmdbuf,
322 drm_r300_cmd_header_t header) 323 drm_r300_cmd_header_t header)
323{ 324{
324 int reg; 325 int reg;
@@ -363,8 +364,8 @@ static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv,
363 * the graphics card. 364 * the graphics card.
364 * Called by r300_do_cp_cmdbuf. 365 * Called by r300_do_cp_cmdbuf.
365 */ 366 */
366static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv, 367static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv,
367 drm_radeon_kcmd_buffer_t * cmdbuf, 368 drm_radeon_kcmd_buffer_t *cmdbuf,
368 drm_r300_cmd_header_t header) 369 drm_r300_cmd_header_t header)
369{ 370{
370 int sz; 371 int sz;
@@ -400,8 +401,8 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv,
400 * Emit a clear packet from userspace. 401 * Emit a clear packet from userspace.
401 * Called by r300_emit_packet3. 402 * Called by r300_emit_packet3.
402 */ 403 */
403static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv, 404static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv,
404 drm_radeon_kcmd_buffer_t * cmdbuf) 405 drm_radeon_kcmd_buffer_t *cmdbuf)
405{ 406{
406 RING_LOCALS; 407 RING_LOCALS;
407 408
@@ -421,8 +422,8 @@ static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv,
421 return 0; 422 return 0;
422} 423}
423 424
424static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv, 425static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv,
425 drm_radeon_kcmd_buffer_t * cmdbuf, 426 drm_radeon_kcmd_buffer_t *cmdbuf,
426 u32 header) 427 u32 header)
427{ 428{
428 int count, i, k; 429 int count, i, k;
@@ -489,8 +490,8 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv,
489 return 0; 490 return 0;
490} 491}
491 492
492static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv, 493static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
493 drm_radeon_kcmd_buffer_t * cmdbuf) 494 drm_radeon_kcmd_buffer_t *cmdbuf)
494{ 495{
495 u32 header; 496 u32 header;
496 int count; 497 int count;
@@ -554,8 +555,8 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv,
554 * Emit a rendering packet3 from userspace. 555 * Emit a rendering packet3 from userspace.
555 * Called by r300_do_cp_cmdbuf. 556 * Called by r300_do_cp_cmdbuf.
556 */ 557 */
557static __inline__ int r300_emit_packet3(drm_radeon_private_t * dev_priv, 558static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv,
558 drm_radeon_kcmd_buffer_t * cmdbuf, 559 drm_radeon_kcmd_buffer_t *cmdbuf,
559 drm_r300_cmd_header_t header) 560 drm_r300_cmd_header_t header)
560{ 561{
561 int n; 562 int n;
@@ -623,7 +624,7 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t * dev_priv,
623/** 624/**
624 * Emit the sequence to pacify R300. 625 * Emit the sequence to pacify R300.
625 */ 626 */
626static __inline__ void r300_pacify(drm_radeon_private_t * dev_priv) 627static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv)
627{ 628{
628 RING_LOCALS; 629 RING_LOCALS;
629 630
@@ -657,9 +658,10 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf)
657 * commands on the DMA ring buffer. 658 * commands on the DMA ring buffer.
658 * Called by the ioctl handler function radeon_cp_cmdbuf. 659 * Called by the ioctl handler function radeon_cp_cmdbuf.
659 */ 660 */
660int r300_do_cp_cmdbuf(drm_device_t * dev, 661int r300_do_cp_cmdbuf(drm_device_t *dev,
661 DRMFILE filp, 662 DRMFILE filp,
662 drm_file_t * filp_priv, drm_radeon_kcmd_buffer_t * cmdbuf) 663 drm_file_t *filp_priv,
664 drm_radeon_kcmd_buffer_t *cmdbuf)
663{ 665{
664 drm_radeon_private_t *dev_priv = dev->dev_private; 666 drm_radeon_private_t *dev_priv = dev->dev_private;
665 drm_device_dma_t *dma = dev->dma; 667 drm_device_dma_t *dma = dev->dma;
diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h
index e5b73c002394..a0ed20e25221 100644
--- a/drivers/char/drm/r300_reg.h
+++ b/drivers/char/drm/r300_reg.h
@@ -797,6 +797,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
797 797
798# define R300_TX_FORMAT_YUV_MODE 0x00800000 798# define R300_TX_FORMAT_YUV_MODE 0x00800000
799 799
800#define R300_TX_PITCH_0 0x4500
800#define R300_TX_OFFSET_0 0x4540 801#define R300_TX_OFFSET_0 0x4540
801/* BEGIN: Guess from R200 */ 802/* BEGIN: Guess from R200 */
802# define R300_TXO_ENDIAN_NO_SWAP (0 << 0) 803# define R300_TXO_ENDIAN_NO_SWAP (0 << 0)
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 342302d46743..915665c7fe7c 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -1,5 +1,5 @@
1/* radeon_cp.c -- CP support for Radeon -*- linux-c -*- 1/* radeon_cp.c -- CP support for Radeon -*- linux-c -*- */
2 * 2/*
3 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. 3 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
4 * Copyright 2000 VA Linux Systems, Inc., Fremont, California. 4 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
5 * All Rights Reserved. 5 * All Rights Reserved.
@@ -824,7 +824,7 @@ static int RADEON_READ_PLL(drm_device_t * dev, int addr)
824 return RADEON_READ(RADEON_CLOCK_CNTL_DATA); 824 return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
825} 825}
826 826
827static int RADEON_READ_PCIE(drm_radeon_private_t * dev_priv, int addr) 827static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
828{ 828{
829 RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); 829 RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff);
830 return RADEON_READ(RADEON_PCIE_DATA); 830 return RADEON_READ(RADEON_PCIE_DATA);
@@ -1125,7 +1125,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
1125 | (dev_priv->fb_location >> 16)); 1125 | (dev_priv->fb_location >> 16));
1126 1126
1127#if __OS_HAS_AGP 1127#if __OS_HAS_AGP
1128 if (!dev_priv->is_pci) { 1128 if (dev_priv->flags & CHIP_IS_AGP) {
1129 RADEON_WRITE(RADEON_MC_AGP_LOCATION, 1129 RADEON_WRITE(RADEON_MC_AGP_LOCATION,
1130 (((dev_priv->gart_vm_start - 1 + 1130 (((dev_priv->gart_vm_start - 1 +
1131 dev_priv->gart_size) & 0xffff0000) | 1131 dev_priv->gart_size) & 0xffff0000) |
@@ -1152,7 +1152,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
1152 dev_priv->ring.tail = cur_read_ptr; 1152 dev_priv->ring.tail = cur_read_ptr;
1153 1153
1154#if __OS_HAS_AGP 1154#if __OS_HAS_AGP
1155 if (!dev_priv->is_pci) { 1155 if (dev_priv->flags & CHIP_IS_AGP) {
1156 /* set RADEON_AGP_BASE here instead of relying on X from user space */ 1156 /* set RADEON_AGP_BASE here instead of relying on X from user space */
1157 RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base); 1157 RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
1158 RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, 1158 RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
@@ -1278,13 +1278,15 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
1278/* Enable or disable PCI GART on the chip */ 1278/* Enable or disable PCI GART on the chip */
1279static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) 1279static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
1280{ 1280{
1281 u32 tmp = RADEON_READ(RADEON_AIC_CNTL); 1281 u32 tmp;
1282 1282
1283 if (dev_priv->flags & CHIP_IS_PCIE) { 1283 if (dev_priv->flags & CHIP_IS_PCIE) {
1284 radeon_set_pciegart(dev_priv, on); 1284 radeon_set_pciegart(dev_priv, on);
1285 return; 1285 return;
1286 } 1286 }
1287 1287
1288 tmp = RADEON_READ(RADEON_AIC_CNTL);
1289
1288 if (on) { 1290 if (on) {
1289 RADEON_WRITE(RADEON_AIC_CNTL, 1291 RADEON_WRITE(RADEON_AIC_CNTL,
1290 tmp | RADEON_PCIGART_TRANSLATE_EN); 1292 tmp | RADEON_PCIGART_TRANSLATE_EN);
@@ -1312,13 +1314,17 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
1312static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) 1314static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1313{ 1315{
1314 drm_radeon_private_t *dev_priv = dev->dev_private; 1316 drm_radeon_private_t *dev_priv = dev->dev_private;
1317
1315 DRM_DEBUG("\n"); 1318 DRM_DEBUG("\n");
1316 1319
1317 dev_priv->is_pci = init->is_pci; 1320 if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP))
1321 {
1322 DRM_DEBUG("Forcing AGP card to PCI mode\n");
1323 dev_priv->flags &= ~CHIP_IS_AGP;
1324 }
1318 1325
1319 if (dev_priv->is_pci && !dev->sg) { 1326 if ((!(dev_priv->flags & CHIP_IS_AGP)) && !dev->sg) {
1320 DRM_ERROR("PCI GART memory not allocated!\n"); 1327 DRM_ERROR("PCI GART memory not allocated!\n");
1321 dev->dev_private = (void *)dev_priv;
1322 radeon_do_cleanup_cp(dev); 1328 radeon_do_cleanup_cp(dev);
1323 return DRM_ERR(EINVAL); 1329 return DRM_ERR(EINVAL);
1324 } 1330 }
@@ -1327,12 +1333,11 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1327 if (dev_priv->usec_timeout < 1 || 1333 if (dev_priv->usec_timeout < 1 ||
1328 dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { 1334 dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) {
1329 DRM_DEBUG("TIMEOUT problem!\n"); 1335 DRM_DEBUG("TIMEOUT problem!\n");
1330 dev->dev_private = (void *)dev_priv;
1331 radeon_do_cleanup_cp(dev); 1336 radeon_do_cleanup_cp(dev);
1332 return DRM_ERR(EINVAL); 1337 return DRM_ERR(EINVAL);
1333 } 1338 }
1334 1339
1335 switch (init->func) { 1340 switch(init->func) {
1336 case RADEON_INIT_R200_CP: 1341 case RADEON_INIT_R200_CP:
1337 dev_priv->microcode_version = UCODE_R200; 1342 dev_priv->microcode_version = UCODE_R200;
1338 break; 1343 break;
@@ -1353,7 +1358,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1353 if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && 1358 if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) &&
1354 (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { 1359 (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) {
1355 DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); 1360 DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode);
1356 dev->dev_private = (void *)dev_priv;
1357 radeon_do_cleanup_cp(dev); 1361 radeon_do_cleanup_cp(dev);
1358 return DRM_ERR(EINVAL); 1362 return DRM_ERR(EINVAL);
1359 } 1363 }
@@ -1416,8 +1420,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1416 1420
1417 DRM_GETSAREA(); 1421 DRM_GETSAREA();
1418 1422
1419 dev_priv->fb_offset = init->fb_offset;
1420 dev_priv->mmio_offset = init->mmio_offset;
1421 dev_priv->ring_offset = init->ring_offset; 1423 dev_priv->ring_offset = init->ring_offset;
1422 dev_priv->ring_rptr_offset = init->ring_rptr_offset; 1424 dev_priv->ring_rptr_offset = init->ring_rptr_offset;
1423 dev_priv->buffers_offset = init->buffers_offset; 1425 dev_priv->buffers_offset = init->buffers_offset;
@@ -1425,29 +1427,19 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1425 1427
1426 if (!dev_priv->sarea) { 1428 if (!dev_priv->sarea) {
1427 DRM_ERROR("could not find sarea!\n"); 1429 DRM_ERROR("could not find sarea!\n");
1428 dev->dev_private = (void *)dev_priv;
1429 radeon_do_cleanup_cp(dev); 1430 radeon_do_cleanup_cp(dev);
1430 return DRM_ERR(EINVAL); 1431 return DRM_ERR(EINVAL);
1431 } 1432 }
1432 1433
1433 dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
1434 if (!dev_priv->mmio) {
1435 DRM_ERROR("could not find mmio region!\n");
1436 dev->dev_private = (void *)dev_priv;
1437 radeon_do_cleanup_cp(dev);
1438 return DRM_ERR(EINVAL);
1439 }
1440 dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); 1434 dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
1441 if (!dev_priv->cp_ring) { 1435 if (!dev_priv->cp_ring) {
1442 DRM_ERROR("could not find cp ring region!\n"); 1436 DRM_ERROR("could not find cp ring region!\n");
1443 dev->dev_private = (void *)dev_priv;
1444 radeon_do_cleanup_cp(dev); 1437 radeon_do_cleanup_cp(dev);
1445 return DRM_ERR(EINVAL); 1438 return DRM_ERR(EINVAL);
1446 } 1439 }
1447 dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); 1440 dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
1448 if (!dev_priv->ring_rptr) { 1441 if (!dev_priv->ring_rptr) {
1449 DRM_ERROR("could not find ring read pointer!\n"); 1442 DRM_ERROR("could not find ring read pointer!\n");
1450 dev->dev_private = (void *)dev_priv;
1451 radeon_do_cleanup_cp(dev); 1443 radeon_do_cleanup_cp(dev);
1452 return DRM_ERR(EINVAL); 1444 return DRM_ERR(EINVAL);
1453 } 1445 }
@@ -1455,7 +1447,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1455 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 1447 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
1456 if (!dev->agp_buffer_map) { 1448 if (!dev->agp_buffer_map) {
1457 DRM_ERROR("could not find dma buffer region!\n"); 1449 DRM_ERROR("could not find dma buffer region!\n");
1458 dev->dev_private = (void *)dev_priv;
1459 radeon_do_cleanup_cp(dev); 1450 radeon_do_cleanup_cp(dev);
1460 return DRM_ERR(EINVAL); 1451 return DRM_ERR(EINVAL);
1461 } 1452 }
@@ -1465,7 +1456,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1465 drm_core_findmap(dev, init->gart_textures_offset); 1456 drm_core_findmap(dev, init->gart_textures_offset);
1466 if (!dev_priv->gart_textures) { 1457 if (!dev_priv->gart_textures) {
1467 DRM_ERROR("could not find GART texture region!\n"); 1458 DRM_ERROR("could not find GART texture region!\n");
1468 dev->dev_private = (void *)dev_priv;
1469 radeon_do_cleanup_cp(dev); 1459 radeon_do_cleanup_cp(dev);
1470 return DRM_ERR(EINVAL); 1460 return DRM_ERR(EINVAL);
1471 } 1461 }
@@ -1476,7 +1466,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1476 init->sarea_priv_offset); 1466 init->sarea_priv_offset);
1477 1467
1478#if __OS_HAS_AGP 1468#if __OS_HAS_AGP
1479 if (!dev_priv->is_pci) { 1469 if (dev_priv->flags & CHIP_IS_AGP) {
1480 drm_core_ioremap(dev_priv->cp_ring, dev); 1470 drm_core_ioremap(dev_priv->cp_ring, dev);
1481 drm_core_ioremap(dev_priv->ring_rptr, dev); 1471 drm_core_ioremap(dev_priv->ring_rptr, dev);
1482 drm_core_ioremap(dev->agp_buffer_map, dev); 1472 drm_core_ioremap(dev->agp_buffer_map, dev);
@@ -1484,7 +1474,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1484 !dev_priv->ring_rptr->handle || 1474 !dev_priv->ring_rptr->handle ||
1485 !dev->agp_buffer_map->handle) { 1475 !dev->agp_buffer_map->handle) {
1486 DRM_ERROR("could not find ioremap agp regions!\n"); 1476 DRM_ERROR("could not find ioremap agp regions!\n");
1487 dev->dev_private = (void *)dev_priv;
1488 radeon_do_cleanup_cp(dev); 1477 radeon_do_cleanup_cp(dev);
1489 return DRM_ERR(EINVAL); 1478 return DRM_ERR(EINVAL);
1490 } 1479 }
@@ -1525,7 +1514,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1525 + RADEON_READ(RADEON_CONFIG_APER_SIZE); 1514 + RADEON_READ(RADEON_CONFIG_APER_SIZE);
1526 1515
1527#if __OS_HAS_AGP 1516#if __OS_HAS_AGP
1528 if (!dev_priv->is_pci) 1517 if (dev_priv->flags & CHIP_IS_AGP)
1529 dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset 1518 dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
1530 - dev->agp->base 1519 - dev->agp->base
1531 + dev_priv->gart_vm_start); 1520 + dev_priv->gart_vm_start);
@@ -1551,7 +1540,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1551 dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; 1540 dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
1552 1541
1553#if __OS_HAS_AGP 1542#if __OS_HAS_AGP
1554 if (!dev_priv->is_pci) { 1543 if (dev_priv->flags & CHIP_IS_AGP) {
1555 /* Turn off PCI GART */ 1544 /* Turn off PCI GART */
1556 radeon_set_pcigart(dev_priv, 0); 1545 radeon_set_pcigart(dev_priv, 0);
1557 } else 1546 } else
@@ -1561,25 +1550,28 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1561 if (dev_priv->pcigart_offset) { 1550 if (dev_priv->pcigart_offset) {
1562 dev_priv->gart_info.bus_addr = 1551 dev_priv->gart_info.bus_addr =
1563 dev_priv->pcigart_offset + dev_priv->fb_location; 1552 dev_priv->pcigart_offset + dev_priv->fb_location;
1553 dev_priv->gart_info.mapping.offset =
1554 dev_priv->gart_info.bus_addr;
1555 dev_priv->gart_info.mapping.size =
1556 RADEON_PCIGART_TABLE_SIZE;
1557
1558 drm_core_ioremap(&dev_priv->gart_info.mapping, dev);
1564 dev_priv->gart_info.addr = 1559 dev_priv->gart_info.addr =
1565 (unsigned long)drm_ioremap(dev_priv->gart_info. 1560 dev_priv->gart_info.mapping.handle;
1566 bus_addr,
1567 RADEON_PCIGART_TABLE_SIZE,
1568 dev);
1569 1561
1570 dev_priv->gart_info.is_pcie = 1562 dev_priv->gart_info.is_pcie =
1571 !!(dev_priv->flags & CHIP_IS_PCIE); 1563 !!(dev_priv->flags & CHIP_IS_PCIE);
1572 dev_priv->gart_info.gart_table_location = 1564 dev_priv->gart_info.gart_table_location =
1573 DRM_ATI_GART_FB; 1565 DRM_ATI_GART_FB;
1574 1566
1575 DRM_DEBUG("Setting phys_pci_gart to %08lX %08lX\n", 1567 DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n",
1576 dev_priv->gart_info.addr, 1568 dev_priv->gart_info.addr,
1577 dev_priv->pcigart_offset); 1569 dev_priv->pcigart_offset);
1578 } else { 1570 } else {
1579 dev_priv->gart_info.gart_table_location = 1571 dev_priv->gart_info.gart_table_location =
1580 DRM_ATI_GART_MAIN; 1572 DRM_ATI_GART_MAIN;
1581 dev_priv->gart_info.addr = 1573 dev_priv->gart_info.addr = NULL;
1582 dev_priv->gart_info.bus_addr = 0; 1574 dev_priv->gart_info.bus_addr = 0;
1583 if (dev_priv->flags & CHIP_IS_PCIE) { 1575 if (dev_priv->flags & CHIP_IS_PCIE) {
1584 DRM_ERROR 1576 DRM_ERROR
1585 ("Cannot use PCI Express without GART in FB memory\n"); 1577 ("Cannot use PCI Express without GART in FB memory\n");
@@ -1590,7 +1582,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1590 1582
1591 if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { 1583 if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
1592 DRM_ERROR("failed to init PCI GART!\n"); 1584 DRM_ERROR("failed to init PCI GART!\n");
1593 dev->dev_private = (void *)dev_priv;
1594 radeon_do_cleanup_cp(dev); 1585 radeon_do_cleanup_cp(dev);
1595 return DRM_ERR(ENOMEM); 1586 return DRM_ERR(ENOMEM);
1596 } 1587 }
@@ -1604,8 +1595,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1604 1595
1605 dev_priv->last_buf = 0; 1596 dev_priv->last_buf = 0;
1606 1597
1607 dev->dev_private = (void *)dev_priv;
1608
1609 radeon_do_engine_reset(dev); 1598 radeon_do_engine_reset(dev);
1610 1599
1611 return 0; 1600 return 0;
@@ -1624,11 +1613,15 @@ static int radeon_do_cleanup_cp(drm_device_t * dev)
1624 drm_irq_uninstall(dev); 1613 drm_irq_uninstall(dev);
1625 1614
1626#if __OS_HAS_AGP 1615#if __OS_HAS_AGP
1627 if (!dev_priv->is_pci) { 1616 if (dev_priv->flags & CHIP_IS_AGP) {
1628 if (dev_priv->cp_ring != NULL) 1617 if (dev_priv->cp_ring != NULL) {
1629 drm_core_ioremapfree(dev_priv->cp_ring, dev); 1618 drm_core_ioremapfree(dev_priv->cp_ring, dev);
1630 if (dev_priv->ring_rptr != NULL) 1619 dev_priv->cp_ring = NULL;
1620 }
1621 if (dev_priv->ring_rptr != NULL) {
1631 drm_core_ioremapfree(dev_priv->ring_rptr, dev); 1622 drm_core_ioremapfree(dev_priv->ring_rptr, dev);
1623 dev_priv->ring_rptr = NULL;
1624 }
1632 if (dev->agp_buffer_map != NULL) { 1625 if (dev->agp_buffer_map != NULL) {
1633 drm_core_ioremapfree(dev->agp_buffer_map, dev); 1626 drm_core_ioremapfree(dev->agp_buffer_map, dev);
1634 dev->agp_buffer_map = NULL; 1627 dev->agp_buffer_map = NULL;
@@ -1636,17 +1629,20 @@ static int radeon_do_cleanup_cp(drm_device_t * dev)
1636 } else 1629 } else
1637#endif 1630#endif
1638 { 1631 {
1639 if (dev_priv->gart_info.bus_addr) 1632
1633 if (dev_priv->gart_info.bus_addr) {
1634 /* Turn off PCI GART */
1635 radeon_set_pcigart(dev_priv, 0);
1640 if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) 1636 if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info))
1641 DRM_ERROR("failed to cleanup PCI GART!\n"); 1637 DRM_ERROR("failed to cleanup PCI GART!\n");
1638 }
1642 1639
1643 if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { 1640 if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB)
1644 drm_ioremapfree((void *)dev_priv->gart_info.addr, 1641 {
1645 RADEON_PCIGART_TABLE_SIZE, dev); 1642 drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
1646 dev_priv->gart_info.addr = 0; 1643 dev_priv->gart_info.addr = 0;
1647 } 1644 }
1648 } 1645 }
1649
1650 /* only clear to the start of flags */ 1646 /* only clear to the start of flags */
1651 memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); 1647 memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
1652 1648
@@ -1672,7 +1668,7 @@ static int radeon_do_resume_cp(drm_device_t * dev)
1672 DRM_DEBUG("Starting radeon_do_resume_cp()\n"); 1668 DRM_DEBUG("Starting radeon_do_resume_cp()\n");
1673 1669
1674#if __OS_HAS_AGP 1670#if __OS_HAS_AGP
1675 if (!dev_priv->is_pci) { 1671 if (dev_priv->flags & CHIP_IS_AGP) {
1676 /* Turn off PCI GART */ 1672 /* Turn off PCI GART */
1677 radeon_set_pcigart(dev_priv, 0); 1673 radeon_set_pcigart(dev_priv, 0);
1678 } else 1674 } else
@@ -2103,7 +2099,7 @@ int radeon_cp_buffers(DRM_IOCTL_ARGS)
2103 return ret; 2099 return ret;
2104} 2100}
2105 2101
2106int radeon_driver_preinit(struct drm_device *dev, unsigned long flags) 2102int radeon_driver_load(struct drm_device *dev, unsigned long flags)
2107{ 2103{
2108 drm_radeon_private_t *dev_priv; 2104 drm_radeon_private_t *dev_priv;
2109 int ret = 0; 2105 int ret = 0;
@@ -2136,11 +2132,14 @@ int radeon_driver_preinit(struct drm_device *dev, unsigned long flags)
2136 dev_priv->flags |= CHIP_IS_PCIE; 2132 dev_priv->flags |= CHIP_IS_PCIE;
2137 2133
2138 DRM_DEBUG("%s card detected\n", 2134 DRM_DEBUG("%s card detected\n",
2139 ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI")); 2135 ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : (((dev_priv->flags & CHIP_IS_PCIE) ? "PCIE" : "PCI"))));
2140 return ret; 2136 return ret;
2141} 2137}
2142 2138
2143int radeon_presetup(struct drm_device *dev) 2139/* Create mappings for registers and framebuffer so userland doesn't necessarily
2140 * have to find them.
2141 */
2142int radeon_driver_firstopen(struct drm_device *dev)
2144{ 2143{
2145 int ret; 2144 int ret;
2146 drm_local_map_t *map; 2145 drm_local_map_t *map;
@@ -2161,12 +2160,11 @@ int radeon_presetup(struct drm_device *dev)
2161 return 0; 2160 return 0;
2162} 2161}
2163 2162
2164int radeon_driver_postcleanup(struct drm_device *dev) 2163int radeon_driver_unload(struct drm_device *dev)
2165{ 2164{
2166 drm_radeon_private_t *dev_priv = dev->dev_private; 2165 drm_radeon_private_t *dev_priv = dev->dev_private;
2167 2166
2168 DRM_DEBUG("\n"); 2167 DRM_DEBUG("\n");
2169
2170 drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); 2168 drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
2171 2169
2172 dev->dev_private = NULL; 2170 dev->dev_private = NULL;
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
index 1cd81a671a36..9c177a6b2a4c 100644
--- a/drivers/char/drm/radeon_drm.h
+++ b/drivers/char/drm/radeon_drm.h
@@ -624,6 +624,11 @@ typedef struct drm_radeon_indirect {
624 int discard; 624 int discard;
625} drm_radeon_indirect_t; 625} drm_radeon_indirect_t;
626 626
627/* enum for card type parameters */
628#define RADEON_CARD_PCI 0
629#define RADEON_CARD_AGP 1
630#define RADEON_CARD_PCIE 2
631
627/* 1.3: An ioctl to get parameters that aren't available to the 3d 632/* 1.3: An ioctl to get parameters that aren't available to the 3d
628 * client any other way. 633 * client any other way.
629 */ 634 */
@@ -640,6 +645,7 @@ typedef struct drm_radeon_indirect {
640#define RADEON_PARAM_SAREA_HANDLE 9 645#define RADEON_PARAM_SAREA_HANDLE 9
641#define RADEON_PARAM_GART_TEX_HANDLE 10 646#define RADEON_PARAM_GART_TEX_HANDLE 10
642#define RADEON_PARAM_SCRATCH_OFFSET 11 647#define RADEON_PARAM_SCRATCH_OFFSET 11
648#define RADEON_PARAM_CARD_TYPE 12
643 649
644typedef struct drm_radeon_getparam { 650typedef struct drm_radeon_getparam {
645 int param; 651 int param;
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
index ee49670d8162..b04ed1b562b9 100644
--- a/drivers/char/drm/radeon_drv.c
+++ b/drivers/char/drm/radeon_drv.c
@@ -42,29 +42,15 @@ int radeon_no_wb;
42MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n"); 42MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n");
43module_param_named(no_wb, radeon_no_wb, int, 0444); 43module_param_named(no_wb, radeon_no_wb, int, 0444);
44 44
45static int postinit(struct drm_device *dev, unsigned long flags) 45static int dri_library_name(struct drm_device *dev, char *buf)
46{ 46{
47 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", 47 drm_radeon_private_t *dev_priv = dev->dev_private;
48 DRIVER_NAME, 48 int family = dev_priv->flags & CHIP_FAMILY_MASK;
49 DRIVER_MAJOR,
50 DRIVER_MINOR,
51 DRIVER_PATCHLEVEL,
52 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
53 );
54 return 0;
55}
56
57static int version(drm_version_t * version)
58{
59 int len;
60 49
61 version->version_major = DRIVER_MAJOR; 50 return snprintf(buf, PAGE_SIZE, "%s\n",
62 version->version_minor = DRIVER_MINOR; 51 (family < CHIP_R200) ? "radeon" :
63 version->version_patchlevel = DRIVER_PATCHLEVEL; 52 ((family < CHIP_R300) ? "r200" :
64 DRM_COPY(version->name, DRIVER_NAME); 53 "r300"));
65 DRM_COPY(version->date, DRIVER_DATE);
66 DRM_COPY(version->desc, DRIVER_DESC);
67 return 0;
68} 54}
69 55
70static struct pci_device_id pciidlist[] = { 56static struct pci_device_id pciidlist[] = {
@@ -77,23 +63,22 @@ static struct drm_driver driver = {
77 DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | 63 DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED |
78 DRIVER_IRQ_VBL, 64 DRIVER_IRQ_VBL,
79 .dev_priv_size = sizeof(drm_radeon_buf_priv_t), 65 .dev_priv_size = sizeof(drm_radeon_buf_priv_t),
80 .preinit = radeon_driver_preinit, 66 .load = radeon_driver_load,
81 .presetup = radeon_presetup, 67 .firstopen = radeon_driver_firstopen,
82 .postcleanup = radeon_driver_postcleanup, 68 .open = radeon_driver_open,
83 .prerelease = radeon_driver_prerelease, 69 .preclose = radeon_driver_preclose,
84 .pretakedown = radeon_driver_pretakedown, 70 .postclose = radeon_driver_postclose,
85 .open_helper = radeon_driver_open_helper, 71 .lastclose = radeon_driver_lastclose,
72 .unload = radeon_driver_unload,
86 .vblank_wait = radeon_driver_vblank_wait, 73 .vblank_wait = radeon_driver_vblank_wait,
74 .dri_library_name = dri_library_name,
87 .irq_preinstall = radeon_driver_irq_preinstall, 75 .irq_preinstall = radeon_driver_irq_preinstall,
88 .irq_postinstall = radeon_driver_irq_postinstall, 76 .irq_postinstall = radeon_driver_irq_postinstall,
89 .irq_uninstall = radeon_driver_irq_uninstall, 77 .irq_uninstall = radeon_driver_irq_uninstall,
90 .irq_handler = radeon_driver_irq_handler, 78 .irq_handler = radeon_driver_irq_handler,
91 .free_filp_priv = radeon_driver_free_filp_priv,
92 .reclaim_buffers = drm_core_reclaim_buffers, 79 .reclaim_buffers = drm_core_reclaim_buffers,
93 .get_map_ofs = drm_core_get_map_ofs, 80 .get_map_ofs = drm_core_get_map_ofs,
94 .get_reg_ofs = drm_core_get_reg_ofs, 81 .get_reg_ofs = drm_core_get_reg_ofs,
95 .postinit = postinit,
96 .version = version,
97 .ioctls = radeon_ioctls, 82 .ioctls = radeon_ioctls,
98 .dma_ioctl = radeon_cp_buffers, 83 .dma_ioctl = radeon_cp_buffers,
99 .fops = { 84 .fops = {
@@ -107,12 +92,19 @@ static struct drm_driver driver = {
107#ifdef CONFIG_COMPAT 92#ifdef CONFIG_COMPAT
108 .compat_ioctl = radeon_compat_ioctl, 93 .compat_ioctl = radeon_compat_ioctl,
109#endif 94#endif
110 } 95 },
111 , 96
112 .pci_driver = { 97 .pci_driver = {
113 .name = DRIVER_NAME, 98 .name = DRIVER_NAME,
114 .id_table = pciidlist, 99 .id_table = pciidlist,
115 } 100 },
101
102 .name = DRIVER_NAME,
103 .desc = DRIVER_DESC,
104 .date = DRIVER_DATE,
105 .major = DRIVER_MAJOR,
106 .minor = DRIVER_MINOR,
107 .patchlevel = DRIVER_PATCHLEVEL,
116}; 108};
117 109
118static int __init radeon_init(void) 110static int __init radeon_init(void)
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index d92ccee3e54c..498b19b1d641 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -38,7 +38,7 @@
38 38
39#define DRIVER_NAME "radeon" 39#define DRIVER_NAME "radeon"
40#define DRIVER_DESC "ATI Radeon" 40#define DRIVER_DESC "ATI Radeon"
41#define DRIVER_DATE "20050911" 41#define DRIVER_DATE "20051229"
42 42
43/* Interface history: 43/* Interface history:
44 * 44 *
@@ -73,7 +73,7 @@
73 * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color 73 * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
74 * and GL_EXT_blend_[func|equation]_separate on r200 74 * and GL_EXT_blend_[func|equation]_separate on r200
75 * 1.12- Add R300 CP microcode support - this just loads the CP on r300 75 * 1.12- Add R300 CP microcode support - this just loads the CP on r300
76 * (No 3D support yet - just microcode loading) 76 * (No 3D support yet - just microcode loading).
77 * 1.13- Add packet R200_EMIT_TCL_POINT_SPRITE_CNTL for ARB_point_parameters 77 * 1.13- Add packet R200_EMIT_TCL_POINT_SPRITE_CNTL for ARB_point_parameters
78 * - Add hyperz support, add hyperz flags to clear ioctl. 78 * - Add hyperz support, add hyperz flags to clear ioctl.
79 * 1.14- Add support for color tiling 79 * 1.14- Add support for color tiling
@@ -88,14 +88,13 @@
88 * R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR 88 * R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR
89 * (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6) 89 * (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6)
90 * 1.19- Add support for gart table in FB memory and PCIE r300 90 * 1.19- Add support for gart table in FB memory and PCIE r300
91 * 1.20- Add support for r300 texrect
92 * 1.21- Add support for card type getparam
91 */ 93 */
92#define DRIVER_MAJOR 1 94#define DRIVER_MAJOR 1
93#define DRIVER_MINOR 19 95#define DRIVER_MINOR 21
94#define DRIVER_PATCHLEVEL 0 96#define DRIVER_PATCHLEVEL 0
95 97
96#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 )
97#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
98
99/* 98/*
100 * Radeon chip families 99 * Radeon chip families
101 */ 100 */
@@ -103,8 +102,8 @@ enum radeon_family {
103 CHIP_R100, 102 CHIP_R100,
104 CHIP_RS100, 103 CHIP_RS100,
105 CHIP_RV100, 104 CHIP_RV100,
106 CHIP_R200,
107 CHIP_RV200, 105 CHIP_RV200,
106 CHIP_R200,
108 CHIP_RS200, 107 CHIP_RS200,
109 CHIP_R250, 108 CHIP_R250,
110 CHIP_RS250, 109 CHIP_RS250,
@@ -138,6 +137,9 @@ enum radeon_chip_flags {
138 CHIP_IS_PCIE = 0x00200000UL, 137 CHIP_IS_PCIE = 0x00200000UL,
139}; 138};
140 139
140#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 )
141#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
142
141typedef struct drm_radeon_freelist { 143typedef struct drm_radeon_freelist {
142 unsigned int age; 144 unsigned int age;
143 drm_buf_t *buf; 145 drm_buf_t *buf;
@@ -245,8 +247,6 @@ typedef struct drm_radeon_private {
245 247
246 drm_radeon_depth_clear_t depth_clear; 248 drm_radeon_depth_clear_t depth_clear;
247 249
248 unsigned long fb_offset;
249 unsigned long mmio_offset;
250 unsigned long ring_offset; 250 unsigned long ring_offset;
251 unsigned long ring_rptr_offset; 251 unsigned long ring_rptr_offset;
252 unsigned long buffers_offset; 252 unsigned long buffers_offset;
@@ -273,7 +273,6 @@ typedef struct drm_radeon_private {
273 273
274 /* starting from here on, data is preserved accross an open */ 274 /* starting from here on, data is preserved accross an open */
275 uint32_t flags; /* see radeon_chip_flags */ 275 uint32_t flags; /* see radeon_chip_flags */
276 int is_pci;
277} drm_radeon_private_t; 276} drm_radeon_private_t;
278 277
279typedef struct drm_radeon_buf_priv { 278typedef struct drm_radeon_buf_priv {
@@ -330,17 +329,14 @@ extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
330extern void radeon_driver_irq_preinstall(drm_device_t * dev); 329extern void radeon_driver_irq_preinstall(drm_device_t * dev);
331extern void radeon_driver_irq_postinstall(drm_device_t * dev); 330extern void radeon_driver_irq_postinstall(drm_device_t * dev);
332extern void radeon_driver_irq_uninstall(drm_device_t * dev); 331extern void radeon_driver_irq_uninstall(drm_device_t * dev);
333extern void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp);
334extern void radeon_driver_pretakedown(drm_device_t * dev);
335extern int radeon_driver_open_helper(drm_device_t * dev,
336 drm_file_t * filp_priv);
337extern void radeon_driver_free_filp_priv(drm_device_t * dev,
338 drm_file_t * filp_priv);
339
340extern int radeon_preinit(struct drm_device *dev, unsigned long flags);
341extern int radeon_postinit(struct drm_device *dev, unsigned long flags);
342extern int radeon_postcleanup(struct drm_device *dev);
343 332
333extern int radeon_driver_load(struct drm_device *dev, unsigned long flags);
334extern int radeon_driver_unload(struct drm_device *dev);
335extern int radeon_driver_firstopen(struct drm_device *dev);
336extern void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp);
337extern void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp);
338extern void radeon_driver_lastclose(drm_device_t * dev);
339extern int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv);
344extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, 340extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
345 unsigned long arg); 341 unsigned long arg);
346 342
@@ -364,6 +360,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
364 */ 360 */
365 361
366#define RADEON_AGP_COMMAND 0x0f60 362#define RADEON_AGP_COMMAND 0x0f60
363#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */
364# define RADEON_AGP_ENABLE (1<<8)
367#define RADEON_AUX_SCISSOR_CNTL 0x26f0 365#define RADEON_AUX_SCISSOR_CNTL 0x26f0
368# define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24) 366# define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24)
369# define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25) 367# define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25)
@@ -651,6 +649,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
651 649
652#define RADEON_WAIT_UNTIL 0x1720 650#define RADEON_WAIT_UNTIL 0x1720
653# define RADEON_WAIT_CRTC_PFLIP (1 << 0) 651# define RADEON_WAIT_CRTC_PFLIP (1 << 0)
652# define RADEON_WAIT_2D_IDLE (1 << 14)
653# define RADEON_WAIT_3D_IDLE (1 << 15)
654# define RADEON_WAIT_2D_IDLECLEAN (1 << 16) 654# define RADEON_WAIT_2D_IDLECLEAN (1 << 16)
655# define RADEON_WAIT_3D_IDLECLEAN (1 << 17) 655# define RADEON_WAIT_3D_IDLECLEAN (1 << 17)
656# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18) 656# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18)
@@ -1105,7 +1105,6 @@ do { \
1105 write = 0; \ 1105 write = 0; \
1106 _tab += _i; \ 1106 _tab += _i; \
1107 } \ 1107 } \
1108 \
1109 while (_size > 0) { \ 1108 while (_size > 0) { \
1110 *(ring + write) = *_tab++; \ 1109 *(ring + write) = *_tab++; \
1111 write++; \ 1110 write++; \
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 231ac1438c69..7bc27516d425 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -1,5 +1,5 @@
1/* radeon_state.c -- State support for Radeon -*- linux-c -*- 1/* radeon_state.c -- State support for Radeon -*- linux-c -*- */
2 * 2/*
3 * Copyright 2000 VA Linux Systems, Inc., Fremont, California. 3 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
4 * All Rights Reserved. 4 * All Rights Reserved.
5 * 5 *
@@ -72,10 +72,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
72 72
73 case RADEON_EMIT_PP_MISC: 73 case RADEON_EMIT_PP_MISC:
74 if (radeon_check_and_fixup_offset(dev_priv, filp_priv, 74 if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
75 &data[(RADEON_RB3D_DEPTHOFFSET 75 &data[(RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4])) {
76 -
77 RADEON_PP_MISC) /
78 4])) {
79 DRM_ERROR("Invalid depth buffer offset\n"); 76 DRM_ERROR("Invalid depth buffer offset\n");
80 return DRM_ERR(EINVAL); 77 return DRM_ERR(EINVAL);
81 } 78 }
@@ -83,10 +80,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
83 80
84 case RADEON_EMIT_PP_CNTL: 81 case RADEON_EMIT_PP_CNTL:
85 if (radeon_check_and_fixup_offset(dev_priv, filp_priv, 82 if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
86 &data[(RADEON_RB3D_COLOROFFSET 83 &data[(RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4])) {
87 -
88 RADEON_PP_CNTL) /
89 4])) {
90 DRM_ERROR("Invalid colour buffer offset\n"); 84 DRM_ERROR("Invalid colour buffer offset\n");
91 return DRM_ERR(EINVAL); 85 return DRM_ERR(EINVAL);
92 } 86 }
@@ -109,10 +103,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
109 case RADEON_EMIT_PP_TXFILTER_1: 103 case RADEON_EMIT_PP_TXFILTER_1:
110 case RADEON_EMIT_PP_TXFILTER_2: 104 case RADEON_EMIT_PP_TXFILTER_2:
111 if (radeon_check_and_fixup_offset(dev_priv, filp_priv, 105 if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
112 &data[(RADEON_PP_TXOFFSET_0 106 &data[(RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4])) {
113 -
114 RADEON_PP_TXFILTER_0) /
115 4])) {
116 DRM_ERROR("Invalid R100 texture offset\n"); 107 DRM_ERROR("Invalid R100 texture offset\n");
117 return DRM_ERR(EINVAL); 108 return DRM_ERR(EINVAL);
118 } 109 }
@@ -126,8 +117,9 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
126 case R200_EMIT_PP_CUBIC_OFFSETS_5:{ 117 case R200_EMIT_PP_CUBIC_OFFSETS_5:{
127 int i; 118 int i;
128 for (i = 0; i < 5; i++) { 119 for (i = 0; i < 5; i++) {
129 if (radeon_check_and_fixup_offset 120 if (radeon_check_and_fixup_offset(dev_priv,
130 (dev_priv, filp_priv, &data[i])) { 121 filp_priv,
122 &data[i])) {
131 DRM_ERROR 123 DRM_ERROR
132 ("Invalid R200 cubic texture offset\n"); 124 ("Invalid R200 cubic texture offset\n");
133 return DRM_ERR(EINVAL); 125 return DRM_ERR(EINVAL);
@@ -239,8 +231,9 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
239 231
240static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * 232static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
241 dev_priv, 233 dev_priv,
242 drm_file_t * filp_priv, 234 drm_file_t *filp_priv,
243 drm_radeon_kcmd_buffer_t *cmdbuf, 235 drm_radeon_kcmd_buffer_t *
236 cmdbuf,
244 unsigned int *cmdsz) 237 unsigned int *cmdsz)
245{ 238{
246 u32 *cmd = (u32 *) cmdbuf->buf; 239 u32 *cmd = (u32 *) cmdbuf->buf;
@@ -555,7 +548,8 @@ static struct {
555 {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"}, 548 {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"},
556 {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"}, 549 {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"},
557 {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"}, 550 {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"},
558 {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"}, 551 {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1,
552 "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"},
559 {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"}, 553 {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"},
560 {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"}, 554 {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"},
561 {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"}, 555 {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"},
@@ -569,7 +563,7 @@ static struct {
569 {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, 563 {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4,
570 "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"}, 564 "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"},
571 {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */ 565 {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */
572 {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */ 566 {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */
573 {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"}, 567 {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"},
574 {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"}, 568 {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"},
575 {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"}, 569 {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"},
@@ -592,7 +586,7 @@ static struct {
592 {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"}, 586 {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"},
593 {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"}, 587 {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},
594 {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"}, 588 {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"},
595 {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */ 589 {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */
596 {R200_PP_AFS_1, 32, "R200_PP_AFS_1"}, 590 {R200_PP_AFS_1, 32, "R200_PP_AFS_1"},
597 {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"}, 591 {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"},
598 {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"}, 592 {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"},
@@ -985,8 +979,8 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev,
985 * rendering a quad into just those buffers. Thus, we have to 979 * rendering a quad into just those buffers. Thus, we have to
986 * make sure the 3D engine is configured correctly. 980 * make sure the 3D engine is configured correctly.
987 */ 981 */
988 if ((dev_priv->microcode_version == UCODE_R200) && 982 else if ((dev_priv->microcode_version == UCODE_R200) &&
989 (flags & (RADEON_DEPTH | RADEON_STENCIL))) { 983 (flags & (RADEON_DEPTH | RADEON_STENCIL))) {
990 984
991 int tempPP_CNTL; 985 int tempPP_CNTL;
992 int tempRE_CNTL; 986 int tempRE_CNTL;
@@ -1637,6 +1631,14 @@ static int radeon_cp_dispatch_texture(DRMFILE filp,
1637 (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); 1631 (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
1638 dwords = size / 4; 1632 dwords = size / 4;
1639 1633
1634#define RADEON_COPY_MT(_buf, _data, _width) \
1635 do { \
1636 if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\
1637 DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \
1638 return DRM_ERR(EFAULT); \
1639 } \
1640 } while(0)
1641
1640 if (microtile) { 1642 if (microtile) {
1641 /* texture micro tiling in use, minimum texture width is thus 16 bytes. 1643 /* texture micro tiling in use, minimum texture width is thus 16 bytes.
1642 however, we cannot use blitter directly for texture width < 64 bytes, 1644 however, we cannot use blitter directly for texture width < 64 bytes,
@@ -1648,46 +1650,19 @@ static int radeon_cp_dispatch_texture(DRMFILE filp,
1648 from user space. */ 1650 from user space. */
1649 if (tex->height == 1) { 1651 if (tex->height == 1) {
1650 if (tex_width >= 64 || tex_width <= 16) { 1652 if (tex_width >= 64 || tex_width <= 16) {
1651 if (DRM_COPY_FROM_USER(buffer, data, 1653 RADEON_COPY_MT(buffer, data,
1652 tex_width * 1654 (int)(tex_width * sizeof(u32)));
1653 sizeof(u32))) {
1654 DRM_ERROR
1655 ("EFAULT on pad, %d bytes\n",
1656 tex_width);
1657 return DRM_ERR(EFAULT);
1658 }
1659 } else if (tex_width == 32) { 1655 } else if (tex_width == 32) {
1660 if (DRM_COPY_FROM_USER 1656 RADEON_COPY_MT(buffer, data, 16);
1661 (buffer, data, 16)) { 1657 RADEON_COPY_MT(buffer + 8,
1662 DRM_ERROR 1658 data + 16, 16);
1663 ("EFAULT on pad, %d bytes\n",
1664 tex_width);
1665 return DRM_ERR(EFAULT);
1666 }
1667 if (DRM_COPY_FROM_USER
1668 (buffer + 8, data + 16, 16)) {
1669 DRM_ERROR
1670 ("EFAULT on pad, %d bytes\n",
1671 tex_width);
1672 return DRM_ERR(EFAULT);
1673 }
1674 } 1659 }
1675 } else if (tex_width >= 64 || tex_width == 16) { 1660 } else if (tex_width >= 64 || tex_width == 16) {
1676 if (DRM_COPY_FROM_USER(buffer, data, 1661 RADEON_COPY_MT(buffer, data,
1677 dwords * sizeof(u32))) { 1662 (int)(dwords * sizeof(u32)));
1678 DRM_ERROR("EFAULT on data, %d dwords\n",
1679 dwords);
1680 return DRM_ERR(EFAULT);
1681 }
1682 } else if (tex_width < 16) { 1663 } else if (tex_width < 16) {
1683 for (i = 0; i < tex->height; i++) { 1664 for (i = 0; i < tex->height; i++) {
1684 if (DRM_COPY_FROM_USER 1665 RADEON_COPY_MT(buffer, data, tex_width);
1685 (buffer, data, tex_width)) {
1686 DRM_ERROR
1687 ("EFAULT on pad, %d bytes\n",
1688 tex_width);
1689 return DRM_ERR(EFAULT);
1690 }
1691 buffer += 4; 1666 buffer += 4;
1692 data += tex_width; 1667 data += tex_width;
1693 } 1668 }
@@ -1695,37 +1670,13 @@ static int radeon_cp_dispatch_texture(DRMFILE filp,
1695 /* TODO: make sure this works when not fitting in one buffer 1670 /* TODO: make sure this works when not fitting in one buffer
1696 (i.e. 32bytes x 2048...) */ 1671 (i.e. 32bytes x 2048...) */
1697 for (i = 0; i < tex->height; i += 2) { 1672 for (i = 0; i < tex->height; i += 2) {
1698 if (DRM_COPY_FROM_USER 1673 RADEON_COPY_MT(buffer, data, 16);
1699 (buffer, data, 16)) {
1700 DRM_ERROR
1701 ("EFAULT on pad, %d bytes\n",
1702 tex_width);
1703 return DRM_ERR(EFAULT);
1704 }
1705 data += 16; 1674 data += 16;
1706 if (DRM_COPY_FROM_USER 1675 RADEON_COPY_MT(buffer + 8, data, 16);
1707 (buffer + 8, data, 16)) {
1708 DRM_ERROR
1709 ("EFAULT on pad, %d bytes\n",
1710 tex_width);
1711 return DRM_ERR(EFAULT);
1712 }
1713 data += 16; 1676 data += 16;
1714 if (DRM_COPY_FROM_USER 1677 RADEON_COPY_MT(buffer + 4, data, 16);
1715 (buffer + 4, data, 16)) {
1716 DRM_ERROR
1717 ("EFAULT on pad, %d bytes\n",
1718 tex_width);
1719 return DRM_ERR(EFAULT);
1720 }
1721 data += 16; 1678 data += 16;
1722 if (DRM_COPY_FROM_USER 1679 RADEON_COPY_MT(buffer + 12, data, 16);
1723 (buffer + 12, data, 16)) {
1724 DRM_ERROR
1725 ("EFAULT on pad, %d bytes\n",
1726 tex_width);
1727 return DRM_ERR(EFAULT);
1728 }
1729 data += 16; 1680 data += 16;
1730 buffer += 16; 1681 buffer += 16;
1731 } 1682 }
@@ -1735,31 +1686,22 @@ static int radeon_cp_dispatch_texture(DRMFILE filp,
1735 /* Texture image width is larger than the minimum, so we 1686 /* Texture image width is larger than the minimum, so we
1736 * can upload it directly. 1687 * can upload it directly.
1737 */ 1688 */
1738 if (DRM_COPY_FROM_USER(buffer, data, 1689 RADEON_COPY_MT(buffer, data,
1739 dwords * sizeof(u32))) { 1690 (int)(dwords * sizeof(u32)));
1740 DRM_ERROR("EFAULT on data, %d dwords\n",
1741 dwords);
1742 return DRM_ERR(EFAULT);
1743 }
1744 } else { 1691 } else {
1745 /* Texture image width is less than the minimum, so we 1692 /* Texture image width is less than the minimum, so we
1746 * need to pad out each image scanline to the minimum 1693 * need to pad out each image scanline to the minimum
1747 * width. 1694 * width.
1748 */ 1695 */
1749 for (i = 0; i < tex->height; i++) { 1696 for (i = 0; i < tex->height; i++) {
1750 if (DRM_COPY_FROM_USER 1697 RADEON_COPY_MT(buffer, data, tex_width);
1751 (buffer, data, tex_width)) {
1752 DRM_ERROR
1753 ("EFAULT on pad, %d bytes\n",
1754 tex_width);
1755 return DRM_ERR(EFAULT);
1756 }
1757 buffer += 8; 1698 buffer += 8;
1758 data += tex_width; 1699 data += tex_width;
1759 } 1700 }
1760 } 1701 }
1761 } 1702 }
1762 1703
1704#undef RADEON_COPY_MT
1763 buf->filp = filp; 1705 buf->filp = filp;
1764 buf->used = size; 1706 buf->used = size;
1765 offset = dev_priv->gart_buffers_offset + buf->offset; 1707 offset = dev_priv->gart_buffers_offset + buf->offset;
@@ -1821,7 +1763,7 @@ static void radeon_cp_dispatch_stipple(drm_device_t * dev, u32 * stipple)
1821} 1763}
1822 1764
1823static void radeon_apply_surface_regs(int surf_index, 1765static void radeon_apply_surface_regs(int surf_index,
1824 drm_radeon_private_t * dev_priv) 1766 drm_radeon_private_t *dev_priv)
1825{ 1767{
1826 if (!dev_priv->mmio) 1768 if (!dev_priv->mmio)
1827 return; 1769 return;
@@ -1847,8 +1789,8 @@ static void radeon_apply_surface_regs(int surf_index,
1847 * freed, we suddenly need two surfaces to store A and C, which might 1789 * freed, we suddenly need two surfaces to store A and C, which might
1848 * not always be available. 1790 * not always be available.
1849 */ 1791 */
1850static int alloc_surface(drm_radeon_surface_alloc_t * new, 1792static int alloc_surface(drm_radeon_surface_alloc_t *new,
1851 drm_radeon_private_t * dev_priv, DRMFILE filp) 1793 drm_radeon_private_t *dev_priv, DRMFILE filp)
1852{ 1794{
1853 struct radeon_virt_surface *s; 1795 struct radeon_virt_surface *s;
1854 int i; 1796 int i;
@@ -2158,6 +2100,11 @@ static int radeon_cp_vertex(DRM_IOCTL_ARGS)
2158 2100
2159 LOCK_TEST_WITH_RETURN(dev, filp); 2101 LOCK_TEST_WITH_RETURN(dev, filp);
2160 2102
2103 if (!dev_priv) {
2104 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2105 return DRM_ERR(EINVAL);
2106 }
2107
2161 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2108 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2162 2109
2163 DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data, 2110 DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data,
@@ -2596,9 +2543,9 @@ static int radeon_emit_packets(drm_radeon_private_t * dev_priv,
2596 return 0; 2543 return 0;
2597} 2544}
2598 2545
2599static __inline__ int radeon_emit_scalars(drm_radeon_private_t * dev_priv, 2546static __inline__ int radeon_emit_scalars(drm_radeon_private_t *dev_priv,
2600 drm_radeon_cmd_header_t header, 2547 drm_radeon_cmd_header_t header,
2601 drm_radeon_kcmd_buffer_t * cmdbuf) 2548 drm_radeon_kcmd_buffer_t *cmdbuf)
2602{ 2549{
2603 int sz = header.scalars.count; 2550 int sz = header.scalars.count;
2604 int start = header.scalars.offset; 2551 int start = header.scalars.offset;
@@ -2618,9 +2565,9 @@ static __inline__ int radeon_emit_scalars(drm_radeon_private_t * dev_priv,
2618 2565
2619/* God this is ugly 2566/* God this is ugly
2620 */ 2567 */
2621static __inline__ int radeon_emit_scalars2(drm_radeon_private_t * dev_priv, 2568static __inline__ int radeon_emit_scalars2(drm_radeon_private_t *dev_priv,
2622 drm_radeon_cmd_header_t header, 2569 drm_radeon_cmd_header_t header,
2623 drm_radeon_kcmd_buffer_t * cmdbuf) 2570 drm_radeon_kcmd_buffer_t *cmdbuf)
2624{ 2571{
2625 int sz = header.scalars.count; 2572 int sz = header.scalars.count;
2626 int start = ((unsigned int)header.scalars.offset) + 0x100; 2573 int start = ((unsigned int)header.scalars.offset) + 0x100;
@@ -2638,9 +2585,9 @@ static __inline__ int radeon_emit_scalars2(drm_radeon_private_t * dev_priv,
2638 return 0; 2585 return 0;
2639} 2586}
2640 2587
2641static __inline__ int radeon_emit_vectors(drm_radeon_private_t * dev_priv, 2588static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv,
2642 drm_radeon_cmd_header_t header, 2589 drm_radeon_cmd_header_t header,
2643 drm_radeon_kcmd_buffer_t * cmdbuf) 2590 drm_radeon_kcmd_buffer_t *cmdbuf)
2644{ 2591{
2645 int sz = header.vectors.count; 2592 int sz = header.vectors.count;
2646 int start = header.vectors.offset; 2593 int start = header.vectors.offset;
@@ -2685,8 +2632,8 @@ static int radeon_emit_packet3(drm_device_t * dev,
2685 return 0; 2632 return 0;
2686} 2633}
2687 2634
2688static int radeon_emit_packet3_cliprect(drm_device_t * dev, 2635static int radeon_emit_packet3_cliprect(drm_device_t *dev,
2689 drm_file_t * filp_priv, 2636 drm_file_t *filp_priv,
2690 drm_radeon_kcmd_buffer_t *cmdbuf, 2637 drm_radeon_kcmd_buffer_t *cmdbuf,
2691 int orig_nbox) 2638 int orig_nbox)
2692{ 2639{
@@ -2818,7 +2765,8 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS)
2818 kbuf = drm_alloc(cmdbuf.bufsz, DRM_MEM_DRIVER); 2765 kbuf = drm_alloc(cmdbuf.bufsz, DRM_MEM_DRIVER);
2819 if (kbuf == NULL) 2766 if (kbuf == NULL)
2820 return DRM_ERR(ENOMEM); 2767 return DRM_ERR(ENOMEM);
2821 if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf.buf, cmdbuf.bufsz)) { 2768 if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf.buf,
2769 cmdbuf.bufsz)) {
2822 drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); 2770 drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
2823 return DRM_ERR(EFAULT); 2771 return DRM_ERR(EFAULT);
2824 } 2772 }
@@ -2981,7 +2929,7 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS)
2981 value = dev_priv->gart_vm_start; 2929 value = dev_priv->gart_vm_start;
2982 break; 2930 break;
2983 case RADEON_PARAM_REGISTER_HANDLE: 2931 case RADEON_PARAM_REGISTER_HANDLE:
2984 value = dev_priv->mmio_offset; 2932 value = dev_priv->mmio->offset;
2985 break; 2933 break;
2986 case RADEON_PARAM_STATUS_HANDLE: 2934 case RADEON_PARAM_STATUS_HANDLE:
2987 value = dev_priv->ring_rptr_offset; 2935 value = dev_priv->ring_rptr_offset;
@@ -3004,6 +2952,15 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS)
3004 case RADEON_PARAM_GART_TEX_HANDLE: 2952 case RADEON_PARAM_GART_TEX_HANDLE:
3005 value = dev_priv->gart_textures_offset; 2953 value = dev_priv->gart_textures_offset;
3006 break; 2954 break;
2955
2956 case RADEON_PARAM_CARD_TYPE:
2957 if (dev_priv->flags & CHIP_IS_PCIE)
2958 value = RADEON_CARD_PCIE;
2959 else if (dev_priv->flags & CHIP_IS_AGP)
2960 value = RADEON_CARD_AGP;
2961 else
2962 value = RADEON_CARD_PCI;
2963 break;
3007 default: 2964 default:
3008 return DRM_ERR(EINVAL); 2965 return DRM_ERR(EINVAL);
3009 } 2966 }
@@ -3066,10 +3023,11 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS)
3066/* When a client dies: 3023/* When a client dies:
3067 * - Check for and clean up flipped page state 3024 * - Check for and clean up flipped page state
3068 * - Free any alloced GART memory. 3025 * - Free any alloced GART memory.
3026 * - Free any alloced radeon surfaces.
3069 * 3027 *
3070 * DRM infrastructure takes care of reclaiming dma buffers. 3028 * DRM infrastructure takes care of reclaiming dma buffers.
3071 */ 3029 */
3072void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp) 3030void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp)
3073{ 3031{
3074 if (dev->dev_private) { 3032 if (dev->dev_private) {
3075 drm_radeon_private_t *dev_priv = dev->dev_private; 3033 drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -3082,16 +3040,17 @@ void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp)
3082 } 3040 }
3083} 3041}
3084 3042
3085void radeon_driver_pretakedown(drm_device_t * dev) 3043void radeon_driver_lastclose(drm_device_t * dev)
3086{ 3044{
3087 radeon_do_release(dev); 3045 radeon_do_release(dev);
3088} 3046}
3089 3047
3090int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv) 3048int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv)
3091{ 3049{
3092 drm_radeon_private_t *dev_priv = dev->dev_private; 3050 drm_radeon_private_t *dev_priv = dev->dev_private;
3093 struct drm_radeon_driver_file_fields *radeon_priv; 3051 struct drm_radeon_driver_file_fields *radeon_priv;
3094 3052
3053 DRM_DEBUG("\n");
3095 radeon_priv = 3054 radeon_priv =
3096 (struct drm_radeon_driver_file_fields *) 3055 (struct drm_radeon_driver_file_fields *)
3097 drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES); 3056 drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES);
@@ -3100,6 +3059,7 @@ int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv)
3100 return -ENOMEM; 3059 return -ENOMEM;
3101 3060
3102 filp_priv->driver_priv = radeon_priv; 3061 filp_priv->driver_priv = radeon_priv;
3062
3103 if (dev_priv) 3063 if (dev_priv)
3104 radeon_priv->radeon_fb_delta = dev_priv->fb_location; 3064 radeon_priv->radeon_fb_delta = dev_priv->fb_location;
3105 else 3065 else
@@ -3107,7 +3067,7 @@ int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv)
3107 return 0; 3067 return 0;
3108} 3068}
3109 3069
3110void radeon_driver_free_filp_priv(drm_device_t * dev, drm_file_t * filp_priv) 3070void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp_priv)
3111{ 3071{
3112 struct drm_radeon_driver_file_fields *radeon_priv = 3072 struct drm_radeon_driver_file_fields *radeon_priv =
3113 filp_priv->driver_priv; 3073 filp_priv->driver_priv;
@@ -3116,33 +3076,33 @@ void radeon_driver_free_filp_priv(drm_device_t * dev, drm_file_t * filp_priv)
3116} 3076}
3117 3077
3118drm_ioctl_desc_t radeon_ioctls[] = { 3078drm_ioctl_desc_t radeon_ioctls[] = {
3119 [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, 1, 1}, 3079 [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
3120 [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, 1, 1}, 3080 [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
3121 [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, 1, 1}, 3081 [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
3122 [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, 1, 1}, 3082 [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
3123 [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, 1, 0}, 3083 [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, DRM_AUTH},
3124 [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, 1, 0}, 3084 [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, DRM_AUTH},
3125 [DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, 1, 0}, 3085 [DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, DRM_AUTH},
3126 [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, 1, 0}, 3086 [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, DRM_AUTH},
3127 [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, 1, 0}, 3087 [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, DRM_AUTH},
3128 [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, 1, 0}, 3088 [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, DRM_AUTH},
3129 [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, 1, 0}, 3089 [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, DRM_AUTH},
3130 [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, 1, 0}, 3090 [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, DRM_AUTH},
3131 [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, 1, 0}, 3091 [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, DRM_AUTH},
3132 [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, 1, 0}, 3092 [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, DRM_AUTH},
3133 [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, 1, 1}, 3093 [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
3134 [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, 1, 0}, 3094 [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, DRM_AUTH},
3135 [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, 1, 0}, 3095 [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, DRM_AUTH},
3136 [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, 1, 0}, 3096 [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, DRM_AUTH},
3137 [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, 1, 0}, 3097 [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, DRM_AUTH},
3138 [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, 1, 0}, 3098 [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, DRM_AUTH},
3139 [DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, 1, 0}, 3099 [DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, DRM_AUTH},
3140 [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, 1, 1}, 3100 [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
3141 [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, 1, 0}, 3101 [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, DRM_AUTH},
3142 [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, 1, 0}, 3102 [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, DRM_AUTH},
3143 [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, 1, 0}, 3103 [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, DRM_AUTH},
3144 [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, 1, 0}, 3104 [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, DRM_AUTH},
3145 [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = {radeon_surface_free, 1, 0} 3105 [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = {radeon_surface_free, DRM_AUTH}
3146}; 3106};
3147 3107
3148int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); 3108int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);
diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c
index 6d10515795cc..0d426deeefec 100644
--- a/drivers/char/drm/savage_bci.c
+++ b/drivers/char/drm/savage_bci.c
@@ -533,16 +533,32 @@ static void savage_fake_dma_flush(drm_savage_private_t * dev_priv)
533 dev_priv->first_dma_page = dev_priv->current_dma_page = 0; 533 dev_priv->first_dma_page = dev_priv->current_dma_page = 0;
534} 534}
535 535
536int savage_driver_load(drm_device_t *dev, unsigned long chipset)
537{
538 drm_savage_private_t *dev_priv;
539
540 dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER);
541 if (dev_priv == NULL)
542 return DRM_ERR(ENOMEM);
543
544 memset(dev_priv, 0, sizeof(drm_savage_private_t));
545 dev->dev_private = (void *)dev_priv;
546
547 dev_priv->chipset = (enum savage_family)chipset;
548
549 return 0;
550}
551
552
536/* 553/*
537 * Initalize mappings. On Savage4 and SavageIX the alignment 554 * Initalize mappings. On Savage4 and SavageIX the alignment
538 * and size of the aperture is not suitable for automatic MTRR setup 555 * and size of the aperture is not suitable for automatic MTRR setup
539 * in drm_addmap. Therefore we do it manually before the maps are 556 * in drm_addmap. Therefore we add them manually before the maps are
540 * initialized. We also need to take care of deleting the MTRRs in 557 * initialized, and tear them down on last close.
541 * postcleanup.
542 */ 558 */
543int savage_preinit(drm_device_t * dev, unsigned long chipset) 559int savage_driver_firstopen(drm_device_t *dev)
544{ 560{
545 drm_savage_private_t *dev_priv; 561 drm_savage_private_t *dev_priv = dev->dev_private;
546 unsigned long mmio_base, fb_base, fb_size, aperture_base; 562 unsigned long mmio_base, fb_base, fb_size, aperture_base;
547 /* fb_rsrc and aper_rsrc aren't really used currently, but still exist 563 /* fb_rsrc and aper_rsrc aren't really used currently, but still exist
548 * in case we decide we need information on the BAR for BSD in the 564 * in case we decide we need information on the BAR for BSD in the
@@ -551,14 +567,6 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset)
551 unsigned int fb_rsrc, aper_rsrc; 567 unsigned int fb_rsrc, aper_rsrc;
552 int ret = 0; 568 int ret = 0;
553 569
554 dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER);
555 if (dev_priv == NULL)
556 return DRM_ERR(ENOMEM);
557
558 memset(dev_priv, 0, sizeof(drm_savage_private_t));
559 dev->dev_private = (void *)dev_priv;
560 dev_priv->chipset = (enum savage_family)chipset;
561
562 dev_priv->mtrr[0].handle = -1; 570 dev_priv->mtrr[0].handle = -1;
563 dev_priv->mtrr[1].handle = -1; 571 dev_priv->mtrr[1].handle = -1;
564 dev_priv->mtrr[2].handle = -1; 572 dev_priv->mtrr[2].handle = -1;
@@ -576,26 +584,24 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset)
576 dev_priv->mtrr[0].base = fb_base; 584 dev_priv->mtrr[0].base = fb_base;
577 dev_priv->mtrr[0].size = 0x01000000; 585 dev_priv->mtrr[0].size = 0x01000000;
578 dev_priv->mtrr[0].handle = 586 dev_priv->mtrr[0].handle =
579 mtrr_add(dev_priv->mtrr[0].base, 587 drm_mtrr_add(dev_priv->mtrr[0].base,
580 dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB, 588 dev_priv->mtrr[0].size, DRM_MTRR_WC);
581 1);
582 dev_priv->mtrr[1].base = fb_base + 0x02000000; 589 dev_priv->mtrr[1].base = fb_base + 0x02000000;
583 dev_priv->mtrr[1].size = 0x02000000; 590 dev_priv->mtrr[1].size = 0x02000000;
584 dev_priv->mtrr[1].handle = 591 dev_priv->mtrr[1].handle =
585 mtrr_add(dev_priv->mtrr[1].base, 592 drm_mtrr_add(dev_priv->mtrr[1].base,
586 dev_priv->mtrr[1].size, MTRR_TYPE_WRCOMB, 593 dev_priv->mtrr[1].size, DRM_MTRR_WC);
587 1);
588 dev_priv->mtrr[2].base = fb_base + 0x04000000; 594 dev_priv->mtrr[2].base = fb_base + 0x04000000;
589 dev_priv->mtrr[2].size = 0x04000000; 595 dev_priv->mtrr[2].size = 0x04000000;
590 dev_priv->mtrr[2].handle = 596 dev_priv->mtrr[2].handle =
591 mtrr_add(dev_priv->mtrr[2].base, 597 drm_mtrr_add(dev_priv->mtrr[2].base,
592 dev_priv->mtrr[2].size, MTRR_TYPE_WRCOMB, 598 dev_priv->mtrr[2].size, DRM_MTRR_WC);
593 1);
594 } else { 599 } else {
595 DRM_ERROR("strange pci_resource_len %08lx\n", 600 DRM_ERROR("strange pci_resource_len %08lx\n",
596 drm_get_resource_len(dev, 0)); 601 drm_get_resource_len(dev, 0));
597 } 602 }
598 } else if (chipset != S3_SUPERSAVAGE && chipset != S3_SAVAGE2000) { 603 } else if (dev_priv->chipset != S3_SUPERSAVAGE &&
604 dev_priv->chipset != S3_SAVAGE2000) {
599 mmio_base = drm_get_resource_start(dev, 0); 605 mmio_base = drm_get_resource_start(dev, 0);
600 fb_rsrc = 1; 606 fb_rsrc = 1;
601 fb_base = drm_get_resource_start(dev, 1); 607 fb_base = drm_get_resource_start(dev, 1);
@@ -609,9 +615,8 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset)
609 dev_priv->mtrr[0].base = fb_base; 615 dev_priv->mtrr[0].base = fb_base;
610 dev_priv->mtrr[0].size = 0x08000000; 616 dev_priv->mtrr[0].size = 0x08000000;
611 dev_priv->mtrr[0].handle = 617 dev_priv->mtrr[0].handle =
612 mtrr_add(dev_priv->mtrr[0].base, 618 drm_mtrr_add(dev_priv->mtrr[0].base,
613 dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB, 619 dev_priv->mtrr[0].size, DRM_MTRR_WC);
614 1);
615 } else { 620 } else {
616 DRM_ERROR("strange pci_resource_len %08lx\n", 621 DRM_ERROR("strange pci_resource_len %08lx\n",
617 drm_get_resource_len(dev, 1)); 622 drm_get_resource_len(dev, 1));
@@ -648,16 +653,21 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset)
648/* 653/*
649 * Delete MTRRs and free device-private data. 654 * Delete MTRRs and free device-private data.
650 */ 655 */
651int savage_postcleanup(drm_device_t * dev) 656void savage_driver_lastclose(drm_device_t *dev)
652{ 657{
653 drm_savage_private_t *dev_priv = dev->dev_private; 658 drm_savage_private_t *dev_priv = dev->dev_private;
654 int i; 659 int i;
655 660
656 for (i = 0; i < 3; ++i) 661 for (i = 0; i < 3; ++i)
657 if (dev_priv->mtrr[i].handle >= 0) 662 if (dev_priv->mtrr[i].handle >= 0)
658 mtrr_del(dev_priv->mtrr[i].handle, 663 drm_mtrr_del(dev_priv->mtrr[i].handle,
659 dev_priv->mtrr[i].base, 664 dev_priv->mtrr[i].base,
660 dev_priv->mtrr[i].size); 665 dev_priv->mtrr[i].size, DRM_MTRR_WC);
666}
667
668int savage_driver_unload(drm_device_t *dev)
669{
670 drm_savage_private_t *dev_priv = dev->dev_private;
661 671
662 drm_free(dev_priv, sizeof(drm_savage_private_t), DRM_MEM_DRIVER); 672 drm_free(dev_priv, sizeof(drm_savage_private_t), DRM_MEM_DRIVER);
663 673
@@ -994,8 +1004,7 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS)
994 * DMA buffer management 1004 * DMA buffer management
995 */ 1005 */
996 1006
997static int savage_bci_get_buffers(DRMFILE filp, drm_device_t * dev, 1007static int savage_bci_get_buffers(DRMFILE filp, drm_device_t *dev, drm_dma_t *d)
998 drm_dma_t * d)
999{ 1008{
1000 drm_buf_t *buf; 1009 drm_buf_t *buf;
1001 int i; 1010 int i;
@@ -1057,7 +1066,7 @@ int savage_bci_buffers(DRM_IOCTL_ARGS)
1057 return ret; 1066 return ret;
1058} 1067}
1059 1068
1060void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp) 1069void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp)
1061{ 1070{
1062 drm_device_dma_t *dma = dev->dma; 1071 drm_device_dma_t *dma = dev->dma;
1063 drm_savage_private_t *dev_priv = dev->dev_private; 1072 drm_savage_private_t *dev_priv = dev->dev_private;
@@ -1090,10 +1099,10 @@ void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp)
1090} 1099}
1091 1100
1092drm_ioctl_desc_t savage_ioctls[] = { 1101drm_ioctl_desc_t savage_ioctls[] = {
1093 [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, 1, 1}, 1102 [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1094 [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, 1, 0}, 1103 [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, DRM_AUTH},
1095 [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, 1, 0}, 1104 [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, DRM_AUTH},
1096 [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, 1, 0}, 1105 [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, DRM_AUTH},
1097}; 1106};
1098 1107
1099int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); 1108int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls);
diff --git a/drivers/char/drm/savage_drv.c b/drivers/char/drm/savage_drv.c
index 22d799cde41c..aa6c0d1a82f8 100644
--- a/drivers/char/drm/savage_drv.c
+++ b/drivers/char/drm/savage_drv.c
@@ -30,31 +30,6 @@
30 30
31#include "drm_pciids.h" 31#include "drm_pciids.h"
32 32
33static int postinit(struct drm_device *dev, unsigned long flags)
34{
35 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
36 DRIVER_NAME,
37 DRIVER_MAJOR,
38 DRIVER_MINOR,
39 DRIVER_PATCHLEVEL,
40 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
41 );
42 return 0;
43}
44
45static int version(drm_version_t * version)
46{
47 int len;
48
49 version->version_major = DRIVER_MAJOR;
50 version->version_minor = DRIVER_MINOR;
51 version->version_patchlevel = DRIVER_PATCHLEVEL;
52 DRM_COPY(version->name, DRIVER_NAME);
53 DRM_COPY(version->date, DRIVER_DATE);
54 DRM_COPY(version->desc, DRIVER_DESC);
55 return 0;
56}
57
58static struct pci_device_id pciidlist[] = { 33static struct pci_device_id pciidlist[] = {
59 savage_PCI_IDS 34 savage_PCI_IDS
60}; 35};
@@ -63,13 +38,13 @@ static struct drm_driver driver = {
63 .driver_features = 38 .driver_features =
64 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA, 39 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA,
65 .dev_priv_size = sizeof(drm_savage_buf_priv_t), 40 .dev_priv_size = sizeof(drm_savage_buf_priv_t),
66 .preinit = savage_preinit, 41 .load = savage_driver_load,
67 .postinit = postinit, 42 .firstopen = savage_driver_firstopen,
68 .postcleanup = savage_postcleanup, 43 .lastclose = savage_driver_lastclose,
44 .unload = savage_driver_unload,
69 .reclaim_buffers = savage_reclaim_buffers, 45 .reclaim_buffers = savage_reclaim_buffers,
70 .get_map_ofs = drm_core_get_map_ofs, 46 .get_map_ofs = drm_core_get_map_ofs,
71 .get_reg_ofs = drm_core_get_reg_ofs, 47 .get_reg_ofs = drm_core_get_reg_ofs,
72 .version = version,
73 .ioctls = savage_ioctls, 48 .ioctls = savage_ioctls,
74 .dma_ioctl = savage_bci_buffers, 49 .dma_ioctl = savage_bci_buffers,
75 .fops = { 50 .fops = {
@@ -80,12 +55,19 @@ static struct drm_driver driver = {
80 .mmap = drm_mmap, 55 .mmap = drm_mmap,
81 .poll = drm_poll, 56 .poll = drm_poll,
82 .fasync = drm_fasync, 57 .fasync = drm_fasync,
83 } 58 },
84 , 59
85 .pci_driver = { 60 .pci_driver = {
86 .name = DRIVER_NAME, 61 .name = DRIVER_NAME,
87 .id_table = pciidlist, 62 .id_table = pciidlist,
88 } 63 },
64
65 .name = DRIVER_NAME,
66 .desc = DRIVER_DESC,
67 .date = DRIVER_DATE,
68 .major = DRIVER_MAJOR,
69 .minor = DRIVER_MINOR,
70 .patchlevel = DRIVER_PATCHLEVEL,
89}; 71};
90 72
91static int __init savage_init(void) 73static int __init savage_init(void)
diff --git a/drivers/char/drm/savage_drv.h b/drivers/char/drm/savage_drv.h
index a4b0fa998a95..dd46cb85439c 100644
--- a/drivers/char/drm/savage_drv.h
+++ b/drivers/char/drm/savage_drv.h
@@ -1,5 +1,5 @@
1/* savage_drv.h -- Private header for the savage driver 1/* savage_drv.h -- Private header for the savage driver */
2 * 2/*
3 * Copyright 2004 Felix Kuehling 3 * Copyright 2004 Felix Kuehling
4 * All Rights Reserved. 4 * All Rights Reserved.
5 * 5 *
@@ -192,7 +192,7 @@ typedef struct drm_savage_private {
192 /* Err, there is a macro wait_event in include/linux/wait.h. 192 /* Err, there is a macro wait_event in include/linux/wait.h.
193 * Avoid unwanted macro expansion. */ 193 * Avoid unwanted macro expansion. */
194 void (*emit_clip_rect) (struct drm_savage_private * dev_priv, 194 void (*emit_clip_rect) (struct drm_savage_private * dev_priv,
195 drm_clip_rect_t * pbox); 195 const drm_clip_rect_t * pbox);
196 void (*dma_flush) (struct drm_savage_private * dev_priv); 196 void (*dma_flush) (struct drm_savage_private * dev_priv);
197} drm_savage_private_t; 197} drm_savage_private_t;
198 198
@@ -208,16 +208,18 @@ extern void savage_dma_reset(drm_savage_private_t * dev_priv);
208extern void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page); 208extern void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page);
209extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, 209extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv,
210 unsigned int n); 210 unsigned int n);
211extern int savage_preinit(drm_device_t * dev, unsigned long chipset); 211extern int savage_driver_load(drm_device_t *dev, unsigned long chipset);
212extern int savage_postcleanup(drm_device_t * dev); 212extern int savage_driver_firstopen(drm_device_t *dev);
213extern void savage_driver_lastclose(drm_device_t *dev);
214extern int savage_driver_unload(drm_device_t *dev);
213extern int savage_do_cleanup_bci(drm_device_t * dev); 215extern int savage_do_cleanup_bci(drm_device_t * dev);
214extern void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp); 216extern void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp);
215 217
216/* state functions */ 218/* state functions */
217extern void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, 219extern void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
218 drm_clip_rect_t * pbox); 220 const drm_clip_rect_t * pbox);
219extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, 221extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
220 drm_clip_rect_t * pbox); 222 const drm_clip_rect_t * pbox);
221 223
222#define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */ 224#define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */
223#define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */ 225#define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */
@@ -500,15 +502,6 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
500 502
501#define BCI_WRITE( val ) *bci_ptr++ = (uint32_t)(val) 503#define BCI_WRITE( val ) *bci_ptr++ = (uint32_t)(val)
502 504
503#define BCI_COPY_FROM_USER(src,n) do { \
504 unsigned int i; \
505 for (i = 0; i < n; ++i) { \
506 uint32_t val; \
507 DRM_GET_USER_UNCHECKED(val, &((uint32_t*)(src))[i]); \
508 BCI_WRITE(val); \
509 } \
510} while(0)
511
512/* 505/*
513 * command DMA support 506 * command DMA support
514 */ 507 */
@@ -534,8 +527,8 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
534 527
535#define DMA_WRITE( val ) *dma_ptr++ = (uint32_t)(val) 528#define DMA_WRITE( val ) *dma_ptr++ = (uint32_t)(val)
536 529
537#define DMA_COPY_FROM_USER(src,n) do { \ 530#define DMA_COPY(src, n) do { \
538 DRM_COPY_FROM_USER_UNCHECKED(dma_ptr, (src), (n)*4); \ 531 memcpy(dma_ptr, (src), (n)*4); \
539 dma_ptr += n; \ 532 dma_ptr += n; \
540} while(0) 533} while(0)
541 534
diff --git a/drivers/char/drm/savage_state.c b/drivers/char/drm/savage_state.c
index e87a5d59b99c..ef2581d16146 100644
--- a/drivers/char/drm/savage_state.c
+++ b/drivers/char/drm/savage_state.c
@@ -27,7 +27,7 @@
27#include "savage_drv.h" 27#include "savage_drv.h"
28 28
29void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, 29void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
30 drm_clip_rect_t * pbox) 30 const drm_clip_rect_t * pbox)
31{ 31{
32 uint32_t scstart = dev_priv->state.s3d.new_scstart; 32 uint32_t scstart = dev_priv->state.s3d.new_scstart;
33 uint32_t scend = dev_priv->state.s3d.new_scend; 33 uint32_t scend = dev_priv->state.s3d.new_scend;
@@ -53,7 +53,7 @@ void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
53} 53}
54 54
55void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, 55void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
56 drm_clip_rect_t * pbox) 56 const drm_clip_rect_t * pbox)
57{ 57{
58 uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0; 58 uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0;
59 uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1; 59 uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1;
@@ -115,18 +115,19 @@ static int savage_verify_texaddr(drm_savage_private_t * dev_priv, int unit,
115 115
116#define SAVE_STATE(reg,where) \ 116#define SAVE_STATE(reg,where) \
117 if(start <= reg && start+count > reg) \ 117 if(start <= reg && start+count > reg) \
118 DRM_GET_USER_UNCHECKED(dev_priv->state.where, &regs[reg-start]) 118 dev_priv->state.where = regs[reg - start]
119#define SAVE_STATE_MASK(reg,where,mask) do { \ 119#define SAVE_STATE_MASK(reg,where,mask) do { \
120 if(start <= reg && start+count > reg) { \ 120 if(start <= reg && start+count > reg) { \
121 uint32_t tmp; \ 121 uint32_t tmp; \
122 DRM_GET_USER_UNCHECKED(tmp, &regs[reg-start]); \ 122 tmp = regs[reg - start]; \
123 dev_priv->state.where = (tmp & (mask)) | \ 123 dev_priv->state.where = (tmp & (mask)) | \
124 (dev_priv->state.where & ~(mask)); \ 124 (dev_priv->state.where & ~(mask)); \
125 } \ 125 } \
126} while (0) 126} while (0)
127
127static int savage_verify_state_s3d(drm_savage_private_t * dev_priv, 128static int savage_verify_state_s3d(drm_savage_private_t * dev_priv,
128 unsigned int start, unsigned int count, 129 unsigned int start, unsigned int count,
129 const uint32_t __user * regs) 130 const uint32_t *regs)
130{ 131{
131 if (start < SAVAGE_TEXPALADDR_S3D || 132 if (start < SAVAGE_TEXPALADDR_S3D ||
132 start + count - 1 > SAVAGE_DESTTEXRWWATERMARK_S3D) { 133 start + count - 1 > SAVAGE_DESTTEXRWWATERMARK_S3D) {
@@ -148,8 +149,7 @@ static int savage_verify_state_s3d(drm_savage_private_t * dev_priv,
148 SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr); 149 SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr);
149 if (dev_priv->state.s3d.texctrl & SAVAGE_TEXCTRL_TEXEN_MASK) 150 if (dev_priv->state.s3d.texctrl & SAVAGE_TEXCTRL_TEXEN_MASK)
150 return savage_verify_texaddr(dev_priv, 0, 151 return savage_verify_texaddr(dev_priv, 0,
151 dev_priv->state.s3d. 152 dev_priv->state.s3d.texaddr);
152 texaddr);
153 } 153 }
154 154
155 return 0; 155 return 0;
@@ -157,7 +157,7 @@ static int savage_verify_state_s3d(drm_savage_private_t * dev_priv,
157 157
158static int savage_verify_state_s4(drm_savage_private_t * dev_priv, 158static int savage_verify_state_s4(drm_savage_private_t * dev_priv,
159 unsigned int start, unsigned int count, 159 unsigned int start, unsigned int count,
160 const uint32_t __user * regs) 160 const uint32_t *regs)
161{ 161{
162 int ret = 0; 162 int ret = 0;
163 163
@@ -174,19 +174,18 @@ static int savage_verify_state_s4(drm_savage_private_t * dev_priv,
174 ~SAVAGE_SCISSOR_MASK_S4); 174 ~SAVAGE_SCISSOR_MASK_S4);
175 175
176 /* if any texture regs were changed ... */ 176 /* if any texture regs were changed ... */
177 if (start <= SAVAGE_TEXDESCR_S4 && start + count > SAVAGE_TEXPALADDR_S4) { 177 if (start <= SAVAGE_TEXDESCR_S4 &&
178 start + count > SAVAGE_TEXPALADDR_S4) {
178 /* ... check texture state */ 179 /* ... check texture state */
179 SAVE_STATE(SAVAGE_TEXDESCR_S4, s4.texdescr); 180 SAVE_STATE(SAVAGE_TEXDESCR_S4, s4.texdescr);
180 SAVE_STATE(SAVAGE_TEXADDR0_S4, s4.texaddr0); 181 SAVE_STATE(SAVAGE_TEXADDR0_S4, s4.texaddr0);
181 SAVE_STATE(SAVAGE_TEXADDR1_S4, s4.texaddr1); 182 SAVE_STATE(SAVAGE_TEXADDR1_S4, s4.texaddr1);
182 if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX0EN_MASK) 183 if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX0EN_MASK)
183 ret |= 184 ret |= savage_verify_texaddr(dev_priv, 0,
184 savage_verify_texaddr(dev_priv, 0, 185 dev_priv->state.s4.texaddr0);
185 dev_priv->state.s4.texaddr0);
186 if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX1EN_MASK) 186 if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX1EN_MASK)
187 ret |= 187 ret |= savage_verify_texaddr(dev_priv, 1,
188 savage_verify_texaddr(dev_priv, 1, 188 dev_priv->state.s4.texaddr1);
189 dev_priv->state.s4.texaddr1);
190 } 189 }
191 190
192 return ret; 191 return ret;
@@ -197,7 +196,7 @@ static int savage_verify_state_s4(drm_savage_private_t * dev_priv,
197 196
198static int savage_dispatch_state(drm_savage_private_t * dev_priv, 197static int savage_dispatch_state(drm_savage_private_t * dev_priv,
199 const drm_savage_cmd_header_t * cmd_header, 198 const drm_savage_cmd_header_t * cmd_header,
200 const uint32_t __user * regs) 199 const uint32_t *regs)
201{ 200{
202 unsigned int count = cmd_header->state.count; 201 unsigned int count = cmd_header->state.count;
203 unsigned int start = cmd_header->state.start; 202 unsigned int start = cmd_header->state.start;
@@ -209,9 +208,6 @@ static int savage_dispatch_state(drm_savage_private_t * dev_priv,
209 if (!count) 208 if (!count)
210 return 0; 209 return 0;
211 210
212 if (DRM_VERIFYAREA_READ(regs, count * 4))
213 return DRM_ERR(EFAULT);
214
215 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { 211 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
216 ret = savage_verify_state_s3d(dev_priv, start, count, regs); 212 ret = savage_verify_state_s3d(dev_priv, start, count, regs);
217 if (ret != 0) 213 if (ret != 0)
@@ -236,8 +232,8 @@ static int savage_dispatch_state(drm_savage_private_t * dev_priv,
236 /* scissor regs are emitted in savage_dispatch_draw */ 232 /* scissor regs are emitted in savage_dispatch_draw */
237 if (start < SAVAGE_DRAWCTRL0_S4) { 233 if (start < SAVAGE_DRAWCTRL0_S4) {
238 if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) 234 if (start + count > SAVAGE_DRAWCTRL1_S4 + 1)
239 count2 = 235 count2 = count -
240 count - (SAVAGE_DRAWCTRL1_S4 + 1 - start); 236 (SAVAGE_DRAWCTRL1_S4 + 1 - start);
241 if (start + count > SAVAGE_DRAWCTRL0_S4) 237 if (start + count > SAVAGE_DRAWCTRL0_S4)
242 count = SAVAGE_DRAWCTRL0_S4 - start; 238 count = SAVAGE_DRAWCTRL0_S4 - start;
243 } else if (start <= SAVAGE_DRAWCTRL1_S4) { 239 } else if (start <= SAVAGE_DRAWCTRL1_S4) {
@@ -263,7 +259,7 @@ static int savage_dispatch_state(drm_savage_private_t * dev_priv,
263 while (count > 0) { 259 while (count > 0) {
264 unsigned int n = count < 255 ? count : 255; 260 unsigned int n = count < 255 ? count : 255;
265 DMA_SET_REGISTERS(start, n); 261 DMA_SET_REGISTERS(start, n);
266 DMA_COPY_FROM_USER(regs, n); 262 DMA_COPY(regs, n);
267 count -= n; 263 count -= n;
268 start += n; 264 start += n;
269 regs += n; 265 regs += n;
@@ -421,8 +417,8 @@ static int savage_dispatch_dma_prim(drm_savage_private_t * dev_priv,
421 417
422static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv, 418static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv,
423 const drm_savage_cmd_header_t * cmd_header, 419 const drm_savage_cmd_header_t * cmd_header,
424 const uint32_t __user * vtxbuf, 420 const uint32_t *vtxbuf, unsigned int vb_size,
425 unsigned int vb_size, unsigned int vb_stride) 421 unsigned int vb_stride)
426{ 422{
427 unsigned char reorder = 0; 423 unsigned char reorder = 0;
428 unsigned int prim = cmd_header->prim.prim; 424 unsigned int prim = cmd_header->prim.prim;
@@ -507,8 +503,7 @@ static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv,
507 503
508 for (i = start; i < start + count; ++i) { 504 for (i = start; i < start + count; ++i) {
509 unsigned int j = i + reorder[i % 3]; 505 unsigned int j = i + reorder[i % 3];
510 DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j], 506 DMA_COPY(&vtxbuf[vb_stride * j], vtx_size);
511 vtx_size);
512 } 507 }
513 508
514 DMA_COMMIT(); 509 DMA_COMMIT();
@@ -517,13 +512,12 @@ static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv,
517 DMA_DRAW_PRIMITIVE(count, prim, skip); 512 DMA_DRAW_PRIMITIVE(count, prim, skip);
518 513
519 if (vb_stride == vtx_size) { 514 if (vb_stride == vtx_size) {
520 DMA_COPY_FROM_USER(&vtxbuf[vb_stride * start], 515 DMA_COPY(&vtxbuf[vb_stride * start],
521 vtx_size * count); 516 vtx_size * count);
522 } else { 517 } else {
523 for (i = start; i < start + count; ++i) { 518 for (i = start; i < start + count; ++i) {
524 DMA_COPY_FROM_USER(&vtxbuf 519 DMA_COPY(&vtxbuf [vb_stride * i],
525 [vb_stride * i], 520 vtx_size);
526 vtx_size);
527 } 521 }
528 } 522 }
529 523
@@ -541,7 +535,7 @@ static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv,
541 535
542static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, 536static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,
543 const drm_savage_cmd_header_t * cmd_header, 537 const drm_savage_cmd_header_t * cmd_header,
544 const uint16_t __user * usr_idx, 538 const uint16_t *idx,
545 const drm_buf_t * dmabuf) 539 const drm_buf_t * dmabuf)
546{ 540{
547 unsigned char reorder = 0; 541 unsigned char reorder = 0;
@@ -628,11 +622,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,
628 while (n != 0) { 622 while (n != 0) {
629 /* Can emit up to 255 indices (85 triangles) at once. */ 623 /* Can emit up to 255 indices (85 triangles) at once. */
630 unsigned int count = n > 255 ? 255 : n; 624 unsigned int count = n > 255 ? 255 : n;
631 /* Is it ok to allocate 510 bytes on the stack in an ioctl? */
632 uint16_t idx[255];
633 625
634 /* Copy and check indices */ 626 /* check indices */
635 DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2);
636 for (i = 0; i < count; ++i) { 627 for (i = 0; i < count; ++i) {
637 if (idx[i] > dmabuf->total / 32) { 628 if (idx[i] > dmabuf->total / 32) {
638 DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", 629 DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
@@ -652,8 +643,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,
652 643
653 for (i = 1; i + 1 < count; i += 2) 644 for (i = 1; i + 1 < count; i += 2)
654 BCI_WRITE(idx[i + reorder[i % 3]] | 645 BCI_WRITE(idx[i + reorder[i % 3]] |
655 (idx[i + 1 + reorder[(i + 1) % 3]] << 646 (idx[i + 1 +
656 16)); 647 reorder[(i + 1) % 3]] << 16));
657 if (i < count) 648 if (i < count)
658 BCI_WRITE(idx[i + reorder[i % 3]]); 649 BCI_WRITE(idx[i + reorder[i % 3]]);
659 } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { 650 } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
@@ -674,7 +665,7 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,
674 BCI_WRITE(idx[i]); 665 BCI_WRITE(idx[i]);
675 } 666 }
676 667
677 usr_idx += count; 668 idx += count;
678 n -= count; 669 n -= count;
679 670
680 prim |= BCI_CMD_DRAW_CONT; 671 prim |= BCI_CMD_DRAW_CONT;
@@ -685,8 +676,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,
685 676
686static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, 677static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,
687 const drm_savage_cmd_header_t * cmd_header, 678 const drm_savage_cmd_header_t * cmd_header,
688 const uint16_t __user * usr_idx, 679 const uint16_t *idx,
689 const uint32_t __user * vtxbuf, 680 const uint32_t *vtxbuf,
690 unsigned int vb_size, unsigned int vb_stride) 681 unsigned int vb_size, unsigned int vb_stride)
691{ 682{
692 unsigned char reorder = 0; 683 unsigned char reorder = 0;
@@ -751,11 +742,8 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,
751 while (n != 0) { 742 while (n != 0) {
752 /* Can emit up to 255 vertices (85 triangles) at once. */ 743 /* Can emit up to 255 vertices (85 triangles) at once. */
753 unsigned int count = n > 255 ? 255 : n; 744 unsigned int count = n > 255 ? 255 : n;
754 /* Is it ok to allocate 510 bytes on the stack in an ioctl? */ 745
755 uint16_t idx[255]; 746 /* Check indices */
756
757 /* Copy and check indices */
758 DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2);
759 for (i = 0; i < count; ++i) { 747 for (i = 0; i < count; ++i) {
760 if (idx[i] > vb_size / (vb_stride * 4)) { 748 if (idx[i] > vb_size / (vb_stride * 4)) {
761 DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", 749 DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
@@ -775,8 +763,7 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,
775 763
776 for (i = 0; i < count; ++i) { 764 for (i = 0; i < count; ++i) {
777 unsigned int j = idx[i + reorder[i % 3]]; 765 unsigned int j = idx[i + reorder[i % 3]];
778 DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j], 766 DMA_COPY(&vtxbuf[vb_stride * j], vtx_size);
779 vtx_size);
780 } 767 }
781 768
782 DMA_COMMIT(); 769 DMA_COMMIT();
@@ -786,14 +773,13 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,
786 773
787 for (i = 0; i < count; ++i) { 774 for (i = 0; i < count; ++i) {
788 unsigned int j = idx[i]; 775 unsigned int j = idx[i];
789 DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j], 776 DMA_COPY(&vtxbuf[vb_stride * j], vtx_size);
790 vtx_size);
791 } 777 }
792 778
793 DMA_COMMIT(); 779 DMA_COMMIT();
794 } 780 }
795 781
796 usr_idx += count; 782 idx += count;
797 n -= count; 783 n -= count;
798 784
799 prim |= BCI_CMD_DRAW_CONT; 785 prim |= BCI_CMD_DRAW_CONT;
@@ -804,11 +790,11 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,
804 790
805static int savage_dispatch_clear(drm_savage_private_t * dev_priv, 791static int savage_dispatch_clear(drm_savage_private_t * dev_priv,
806 const drm_savage_cmd_header_t * cmd_header, 792 const drm_savage_cmd_header_t * cmd_header,
807 const drm_savage_cmd_header_t __user * data, 793 const drm_savage_cmd_header_t *data,
808 unsigned int nbox, 794 unsigned int nbox,
809 const drm_clip_rect_t __user * usr_boxes) 795 const drm_clip_rect_t *boxes)
810{ 796{
811 unsigned int flags = cmd_header->clear0.flags, mask, value; 797 unsigned int flags = cmd_header->clear0.flags;
812 unsigned int clear_cmd; 798 unsigned int clear_cmd;
813 unsigned int i, nbufs; 799 unsigned int i, nbufs;
814 DMA_LOCALS; 800 DMA_LOCALS;
@@ -816,9 +802,6 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv,
816 if (nbox == 0) 802 if (nbox == 0)
817 return 0; 803 return 0;
818 804
819 DRM_GET_USER_UNCHECKED(mask, &data->clear1.mask);
820 DRM_GET_USER_UNCHECKED(value, &data->clear1.value);
821
822 clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | 805 clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
823 BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW; 806 BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW;
824 BCI_CMD_SET_ROP(clear_cmd, 0xCC); 807 BCI_CMD_SET_ROP(clear_cmd, 0xCC);
@@ -828,21 +811,19 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv,
828 if (nbufs == 0) 811 if (nbufs == 0)
829 return 0; 812 return 0;
830 813
831 if (mask != 0xffffffff) { 814 if (data->clear1.mask != 0xffffffff) {
832 /* set mask */ 815 /* set mask */
833 BEGIN_DMA(2); 816 BEGIN_DMA(2);
834 DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1); 817 DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1);
835 DMA_WRITE(mask); 818 DMA_WRITE(data->clear1.mask);
836 DMA_COMMIT(); 819 DMA_COMMIT();
837 } 820 }
838 for (i = 0; i < nbox; ++i) { 821 for (i = 0; i < nbox; ++i) {
839 drm_clip_rect_t box;
840 unsigned int x, y, w, h; 822 unsigned int x, y, w, h;
841 unsigned int buf; 823 unsigned int buf;
842 DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box)); 824 x = boxes[i].x1, y = boxes[i].y1;
843 x = box.x1, y = box.y1; 825 w = boxes[i].x2 - boxes[i].x1;
844 w = box.x2 - box.x1; 826 h = boxes[i].y2 - boxes[i].y1;
845 h = box.y2 - box.y1;
846 BEGIN_DMA(nbufs * 6); 827 BEGIN_DMA(nbufs * 6);
847 for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) { 828 for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) {
848 if (!(flags & buf)) 829 if (!(flags & buf))
@@ -862,13 +843,13 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv,
862 DMA_WRITE(dev_priv->depth_bd); 843 DMA_WRITE(dev_priv->depth_bd);
863 break; 844 break;
864 } 845 }
865 DMA_WRITE(value); 846 DMA_WRITE(data->clear1.value);
866 DMA_WRITE(BCI_X_Y(x, y)); 847 DMA_WRITE(BCI_X_Y(x, y));
867 DMA_WRITE(BCI_W_H(w, h)); 848 DMA_WRITE(BCI_W_H(w, h));
868 } 849 }
869 DMA_COMMIT(); 850 DMA_COMMIT();
870 } 851 }
871 if (mask != 0xffffffff) { 852 if (data->clear1.mask != 0xffffffff) {
872 /* reset mask */ 853 /* reset mask */
873 BEGIN_DMA(2); 854 BEGIN_DMA(2);
874 DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1); 855 DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1);
@@ -880,8 +861,7 @@ static int savage_dispatch_clear(drm_savage_private_t * dev_priv,
880} 861}
881 862
882static int savage_dispatch_swap(drm_savage_private_t * dev_priv, 863static int savage_dispatch_swap(drm_savage_private_t * dev_priv,
883 unsigned int nbox, 864 unsigned int nbox, const drm_clip_rect_t *boxes)
884 const drm_clip_rect_t __user * usr_boxes)
885{ 865{
886 unsigned int swap_cmd; 866 unsigned int swap_cmd;
887 unsigned int i; 867 unsigned int i;
@@ -895,16 +875,14 @@ static int savage_dispatch_swap(drm_savage_private_t * dev_priv,
895 BCI_CMD_SET_ROP(swap_cmd, 0xCC); 875 BCI_CMD_SET_ROP(swap_cmd, 0xCC);
896 876
897 for (i = 0; i < nbox; ++i) { 877 for (i = 0; i < nbox; ++i) {
898 drm_clip_rect_t box;
899 DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box));
900
901 BEGIN_DMA(6); 878 BEGIN_DMA(6);
902 DMA_WRITE(swap_cmd); 879 DMA_WRITE(swap_cmd);
903 DMA_WRITE(dev_priv->back_offset); 880 DMA_WRITE(dev_priv->back_offset);
904 DMA_WRITE(dev_priv->back_bd); 881 DMA_WRITE(dev_priv->back_bd);
905 DMA_WRITE(BCI_X_Y(box.x1, box.y1)); 882 DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1));
906 DMA_WRITE(BCI_X_Y(box.x1, box.y1)); 883 DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1));
907 DMA_WRITE(BCI_W_H(box.x2 - box.x1, box.y2 - box.y1)); 884 DMA_WRITE(BCI_W_H(boxes[i].x2 - boxes[i].x1,
885 boxes[i].y2 - boxes[i].y1));
908 DMA_COMMIT(); 886 DMA_COMMIT();
909 } 887 }
910 888
@@ -912,68 +890,52 @@ static int savage_dispatch_swap(drm_savage_private_t * dev_priv,
912} 890}
913 891
914static int savage_dispatch_draw(drm_savage_private_t * dev_priv, 892static int savage_dispatch_draw(drm_savage_private_t * dev_priv,
915 const drm_savage_cmd_header_t __user * start, 893 const drm_savage_cmd_header_t *start,
916 const drm_savage_cmd_header_t __user * end, 894 const drm_savage_cmd_header_t *end,
917 const drm_buf_t * dmabuf, 895 const drm_buf_t * dmabuf,
918 const unsigned int __user * usr_vtxbuf, 896 const unsigned int *vtxbuf,
919 unsigned int vb_size, unsigned int vb_stride, 897 unsigned int vb_size, unsigned int vb_stride,
920 unsigned int nbox, 898 unsigned int nbox,
921 const drm_clip_rect_t __user * usr_boxes) 899 const drm_clip_rect_t *boxes)
922{ 900{
923 unsigned int i, j; 901 unsigned int i, j;
924 int ret; 902 int ret;
925 903
926 for (i = 0; i < nbox; ++i) { 904 for (i = 0; i < nbox; ++i) {
927 drm_clip_rect_t box; 905 const drm_savage_cmd_header_t *cmdbuf;
928 const drm_savage_cmd_header_t __user *usr_cmdbuf; 906 dev_priv->emit_clip_rect(dev_priv, &boxes[i]);
929 DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box));
930 dev_priv->emit_clip_rect(dev_priv, &box);
931 907
932 usr_cmdbuf = start; 908 cmdbuf = start;
933 while (usr_cmdbuf < end) { 909 while (cmdbuf < end) {
934 drm_savage_cmd_header_t cmd_header; 910 drm_savage_cmd_header_t cmd_header;
935 DRM_COPY_FROM_USER_UNCHECKED(&cmd_header, usr_cmdbuf, 911 cmd_header = *cmdbuf;
936 sizeof(cmd_header)); 912 cmdbuf++;
937 usr_cmdbuf++;
938 switch (cmd_header.cmd.cmd) { 913 switch (cmd_header.cmd.cmd) {
939 case SAVAGE_CMD_DMA_PRIM: 914 case SAVAGE_CMD_DMA_PRIM:
940 ret = 915 ret = savage_dispatch_dma_prim(
941 savage_dispatch_dma_prim(dev_priv, 916 dev_priv, &cmd_header, dmabuf);
942 &cmd_header,
943 dmabuf);
944 break; 917 break;
945 case SAVAGE_CMD_VB_PRIM: 918 case SAVAGE_CMD_VB_PRIM:
946 ret = 919 ret = savage_dispatch_vb_prim(
947 savage_dispatch_vb_prim(dev_priv, 920 dev_priv, &cmd_header,
948 &cmd_header, 921 vtxbuf, vb_size, vb_stride);
949 (const uint32_t
950 __user *)
951 usr_vtxbuf, vb_size,
952 vb_stride);
953 break; 922 break;
954 case SAVAGE_CMD_DMA_IDX: 923 case SAVAGE_CMD_DMA_IDX:
955 j = (cmd_header.idx.count + 3) / 4; 924 j = (cmd_header.idx.count + 3) / 4;
956 /* j was check in savage_bci_cmdbuf */ 925 /* j was check in savage_bci_cmdbuf */
957 ret = 926 ret = savage_dispatch_dma_idx(dev_priv,
958 savage_dispatch_dma_idx(dev_priv, 927 &cmd_header, (const uint16_t *)cmdbuf,
959 &cmd_header, 928 dmabuf);
960 (const uint16_t 929 cmdbuf += j;
961 __user *)
962 usr_cmdbuf, dmabuf);
963 usr_cmdbuf += j;
964 break; 930 break;
965 case SAVAGE_CMD_VB_IDX: 931 case SAVAGE_CMD_VB_IDX:
966 j = (cmd_header.idx.count + 3) / 4; 932 j = (cmd_header.idx.count + 3) / 4;
967 /* j was check in savage_bci_cmdbuf */ 933 /* j was check in savage_bci_cmdbuf */
968 ret = 934 ret = savage_dispatch_vb_idx(dev_priv,
969 savage_dispatch_vb_idx(dev_priv, 935 &cmd_header, (const uint16_t *)cmdbuf,
970 &cmd_header, 936 (const uint32_t *)vtxbuf, vb_size,
971 (const uint16_t 937 vb_stride);
972 __user *)usr_cmdbuf, 938 cmdbuf += j;
973 (const uint32_t
974 __user *)usr_vtxbuf,
975 vb_size, vb_stride);
976 usr_cmdbuf += j;
977 break; 939 break;
978 default: 940 default:
979 /* What's the best return code? EFAULT? */ 941 /* What's the best return code? EFAULT? */
@@ -998,10 +960,10 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
998 drm_device_dma_t *dma = dev->dma; 960 drm_device_dma_t *dma = dev->dma;
999 drm_buf_t *dmabuf; 961 drm_buf_t *dmabuf;
1000 drm_savage_cmdbuf_t cmdbuf; 962 drm_savage_cmdbuf_t cmdbuf;
1001 drm_savage_cmd_header_t __user *usr_cmdbuf; 963 drm_savage_cmd_header_t *kcmd_addr = NULL;
1002 drm_savage_cmd_header_t __user *first_draw_cmd; 964 drm_savage_cmd_header_t *first_draw_cmd;
1003 unsigned int __user *usr_vtxbuf; 965 unsigned int *kvb_addr = NULL;
1004 drm_clip_rect_t __user *usr_boxes; 966 drm_clip_rect_t *kbox_addr = NULL;
1005 unsigned int i, j; 967 unsigned int i, j;
1006 int ret = 0; 968 int ret = 0;
1007 969
@@ -1024,15 +986,53 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
1024 dmabuf = NULL; 986 dmabuf = NULL;
1025 } 987 }
1026 988
1027 usr_cmdbuf = (drm_savage_cmd_header_t __user *) cmdbuf.cmd_addr; 989 /* Copy the user buffers into kernel temporary areas. This hasn't been
1028 usr_vtxbuf = (unsigned int __user *)cmdbuf.vb_addr; 990 * a performance loss compared to VERIFYAREA_READ/
1029 usr_boxes = (drm_clip_rect_t __user *) cmdbuf.box_addr; 991 * COPY_FROM_USER_UNCHECKED when done in other drivers, and is correct
1030 if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size * 8)) || 992 * for locking on FreeBSD.
1031 (cmdbuf.vb_size && DRM_VERIFYAREA_READ(usr_vtxbuf, cmdbuf.vb_size)) 993 */
1032 || (cmdbuf.nbox 994 if (cmdbuf.size) {
1033 && DRM_VERIFYAREA_READ(usr_boxes, 995 kcmd_addr = drm_alloc(cmdbuf.size * 8, DRM_MEM_DRIVER);
1034 cmdbuf.nbox * sizeof(drm_clip_rect_t)))) 996 if (kcmd_addr == NULL)
1035 return DRM_ERR(EFAULT); 997 return ENOMEM;
998
999 if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf.cmd_addr,
1000 cmdbuf.size * 8))
1001 {
1002 drm_free(kcmd_addr, cmdbuf.size * 8, DRM_MEM_DRIVER);
1003 return DRM_ERR(EFAULT);
1004 }
1005 cmdbuf.cmd_addr = kcmd_addr;
1006 }
1007 if (cmdbuf.vb_size) {
1008 kvb_addr = drm_alloc(cmdbuf.vb_size, DRM_MEM_DRIVER);
1009 if (kvb_addr == NULL) {
1010 ret = DRM_ERR(ENOMEM);
1011 goto done;
1012 }
1013
1014 if (DRM_COPY_FROM_USER(kvb_addr, cmdbuf.vb_addr,
1015 cmdbuf.vb_size)) {
1016 ret = DRM_ERR(EFAULT);
1017 goto done;
1018 }
1019 cmdbuf.vb_addr = kvb_addr;
1020 }
1021 if (cmdbuf.nbox) {
1022 kbox_addr = drm_alloc(cmdbuf.nbox * sizeof(drm_clip_rect_t),
1023 DRM_MEM_DRIVER);
1024 if (kbox_addr == NULL) {
1025 ret = DRM_ERR(ENOMEM);
1026 goto done;
1027 }
1028
1029 if (DRM_COPY_FROM_USER(kbox_addr, cmdbuf.box_addr,
1030 cmdbuf.nbox * sizeof(drm_clip_rect_t))) {
1031 ret = DRM_ERR(EFAULT);
1032 goto done;
1033 }
1034 cmdbuf.box_addr = kbox_addr;
1035 }
1036 1036
1037 /* Make sure writes to DMA buffers are finished before sending 1037 /* Make sure writes to DMA buffers are finished before sending
1038 * DMA commands to the graphics hardware. */ 1038 * DMA commands to the graphics hardware. */
@@ -1046,9 +1046,8 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
1046 first_draw_cmd = NULL; 1046 first_draw_cmd = NULL;
1047 while (i < cmdbuf.size) { 1047 while (i < cmdbuf.size) {
1048 drm_savage_cmd_header_t cmd_header; 1048 drm_savage_cmd_header_t cmd_header;
1049 DRM_COPY_FROM_USER_UNCHECKED(&cmd_header, usr_cmdbuf, 1049 cmd_header = *(drm_savage_cmd_header_t *)cmdbuf.cmd_addr;
1050 sizeof(cmd_header)); 1050 cmdbuf.cmd_addr++;
1051 usr_cmdbuf++;
1052 i++; 1051 i++;
1053 1052
1054 /* Group drawing commands with same state to minimize 1053 /* Group drawing commands with same state to minimize
@@ -1068,21 +1067,18 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
1068 case SAVAGE_CMD_DMA_PRIM: 1067 case SAVAGE_CMD_DMA_PRIM:
1069 case SAVAGE_CMD_VB_PRIM: 1068 case SAVAGE_CMD_VB_PRIM:
1070 if (!first_draw_cmd) 1069 if (!first_draw_cmd)
1071 first_draw_cmd = usr_cmdbuf - 1; 1070 first_draw_cmd = cmdbuf.cmd_addr - 1;
1072 usr_cmdbuf += j; 1071 cmdbuf.cmd_addr += j;
1073 i += j; 1072 i += j;
1074 break; 1073 break;
1075 default: 1074 default:
1076 if (first_draw_cmd) { 1075 if (first_draw_cmd) {
1077 ret = 1076 ret = savage_dispatch_draw(
1078 savage_dispatch_draw(dev_priv, 1077 dev_priv, first_draw_cmd,
1079 first_draw_cmd, 1078 cmdbuf.cmd_addr - 1,
1080 usr_cmdbuf - 1, dmabuf, 1079 dmabuf, cmdbuf.vb_addr, cmdbuf.vb_size,
1081 usr_vtxbuf, 1080 cmdbuf.vb_stride,
1082 cmdbuf.vb_size, 1081 cmdbuf.nbox, cmdbuf.box_addr);
1083 cmdbuf.vb_stride,
1084 cmdbuf.nbox,
1085 usr_boxes);
1086 if (ret != 0) 1082 if (ret != 0)
1087 return ret; 1083 return ret;
1088 first_draw_cmd = NULL; 1084 first_draw_cmd = NULL;
@@ -1098,12 +1094,12 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
1098 DRM_ERROR("command SAVAGE_CMD_STATE extends " 1094 DRM_ERROR("command SAVAGE_CMD_STATE extends "
1099 "beyond end of command buffer\n"); 1095 "beyond end of command buffer\n");
1100 DMA_FLUSH(); 1096 DMA_FLUSH();
1101 return DRM_ERR(EINVAL); 1097 ret = DRM_ERR(EINVAL);
1098 goto done;
1102 } 1099 }
1103 ret = savage_dispatch_state(dev_priv, &cmd_header, 1100 ret = savage_dispatch_state(dev_priv, &cmd_header,
1104 (uint32_t __user *) 1101 (const uint32_t *)cmdbuf.cmd_addr);
1105 usr_cmdbuf); 1102 cmdbuf.cmd_addr += j;
1106 usr_cmdbuf += j;
1107 i += j; 1103 i += j;
1108 break; 1104 break;
1109 case SAVAGE_CMD_CLEAR: 1105 case SAVAGE_CMD_CLEAR:
@@ -1111,39 +1107,40 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
1111 DRM_ERROR("command SAVAGE_CMD_CLEAR extends " 1107 DRM_ERROR("command SAVAGE_CMD_CLEAR extends "
1112 "beyond end of command buffer\n"); 1108 "beyond end of command buffer\n");
1113 DMA_FLUSH(); 1109 DMA_FLUSH();
1114 return DRM_ERR(EINVAL); 1110 ret = DRM_ERR(EINVAL);
1111 goto done;
1115 } 1112 }
1116 ret = savage_dispatch_clear(dev_priv, &cmd_header, 1113 ret = savage_dispatch_clear(dev_priv, &cmd_header,
1117 usr_cmdbuf, 1114 cmdbuf.cmd_addr,
1118 cmdbuf.nbox, usr_boxes); 1115 cmdbuf.nbox, cmdbuf.box_addr);
1119 usr_cmdbuf++; 1116 cmdbuf.cmd_addr++;
1120 i++; 1117 i++;
1121 break; 1118 break;
1122 case SAVAGE_CMD_SWAP: 1119 case SAVAGE_CMD_SWAP:
1123 ret = savage_dispatch_swap(dev_priv, 1120 ret = savage_dispatch_swap(dev_priv, cmdbuf.nbox,
1124 cmdbuf.nbox, usr_boxes); 1121 cmdbuf.box_addr);
1125 break; 1122 break;
1126 default: 1123 default:
1127 DRM_ERROR("invalid command 0x%x\n", cmd_header.cmd.cmd); 1124 DRM_ERROR("invalid command 0x%x\n", cmd_header.cmd.cmd);
1128 DMA_FLUSH(); 1125 DMA_FLUSH();
1129 return DRM_ERR(EINVAL); 1126 ret = DRM_ERR(EINVAL);
1127 goto done;
1130 } 1128 }
1131 1129
1132 if (ret != 0) { 1130 if (ret != 0) {
1133 DMA_FLUSH(); 1131 DMA_FLUSH();
1134 return ret; 1132 goto done;
1135 } 1133 }
1136 } 1134 }
1137 1135
1138 if (first_draw_cmd) { 1136 if (first_draw_cmd) {
1139 ret = 1137 ret = savage_dispatch_draw (
1140 savage_dispatch_draw(dev_priv, first_draw_cmd, usr_cmdbuf, 1138 dev_priv, first_draw_cmd, cmdbuf.cmd_addr, dmabuf,
1141 dmabuf, usr_vtxbuf, cmdbuf.vb_size, 1139 cmdbuf.vb_addr, cmdbuf.vb_size, cmdbuf.vb_stride,
1142 cmdbuf.vb_stride, cmdbuf.nbox, 1140 cmdbuf.nbox, cmdbuf.box_addr);
1143 usr_boxes);
1144 if (ret != 0) { 1141 if (ret != 0) {
1145 DMA_FLUSH(); 1142 DMA_FLUSH();
1146 return ret; 1143 goto done;
1147 } 1144 }
1148 } 1145 }
1149 1146
@@ -1157,5 +1154,12 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
1157 savage_freelist_put(dev, dmabuf); 1154 savage_freelist_put(dev, dmabuf);
1158 } 1155 }
1159 1156
1160 return 0; 1157done:
1158 /* If we didn't need to allocate them, these'll be NULL */
1159 drm_free(kcmd_addr, cmdbuf.size * 8, DRM_MEM_DRIVER);
1160 drm_free(kvb_addr, cmdbuf.vb_size, DRM_MEM_DRIVER);
1161 drm_free(kbox_addr, cmdbuf.nbox * sizeof(drm_clip_rect_t),
1162 DRM_MEM_DRIVER);
1163
1164 return ret;
1161} 1165}
diff --git a/drivers/char/drm/sis_drm.h b/drivers/char/drm/sis_drm.h
index 8f273da76ddb..30f7b3827466 100644
--- a/drivers/char/drm/sis_drm.h
+++ b/drivers/char/drm/sis_drm.h
@@ -1,3 +1,28 @@
1/* sis_drv.h -- Private header for sis driver -*- linux-c -*- */
2/*
3 * Copyright 2005 Eric Anholt
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 */
1 26
2#ifndef __SIS_DRM_H__ 27#ifndef __SIS_DRM_H__
3#define __SIS_DRM_H__ 28#define __SIS_DRM_H__
diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c
index 3cef10643a8f..6f6d7d613ede 100644
--- a/drivers/char/drm/sis_drv.c
+++ b/drivers/char/drm/sis_drv.c
@@ -32,31 +32,6 @@
32 32
33#include "drm_pciids.h" 33#include "drm_pciids.h"
34 34
35static int postinit(struct drm_device *dev, unsigned long flags)
36{
37 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
38 DRIVER_NAME,
39 DRIVER_MAJOR,
40 DRIVER_MINOR,
41 DRIVER_PATCHLEVEL,
42 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
43 );
44 return 0;
45}
46
47static int version(drm_version_t * version)
48{
49 int len;
50
51 version->version_major = DRIVER_MAJOR;
52 version->version_minor = DRIVER_MINOR;
53 version->version_patchlevel = DRIVER_PATCHLEVEL;
54 DRM_COPY(version->name, DRIVER_NAME);
55 DRM_COPY(version->date, DRIVER_DATE);
56 DRM_COPY(version->desc, DRIVER_DESC);
57 return 0;
58}
59
60static struct pci_device_id pciidlist[] = { 35static struct pci_device_id pciidlist[] = {
61 sisdrv_PCI_IDS 36 sisdrv_PCI_IDS
62}; 37};
@@ -68,8 +43,6 @@ static struct drm_driver driver = {
68 .reclaim_buffers = drm_core_reclaim_buffers, 43 .reclaim_buffers = drm_core_reclaim_buffers,
69 .get_map_ofs = drm_core_get_map_ofs, 44 .get_map_ofs = drm_core_get_map_ofs,
70 .get_reg_ofs = drm_core_get_reg_ofs, 45 .get_reg_ofs = drm_core_get_reg_ofs,
71 .postinit = postinit,
72 .version = version,
73 .ioctls = sis_ioctls, 46 .ioctls = sis_ioctls,
74 .fops = { 47 .fops = {
75 .owner = THIS_MODULE, 48 .owner = THIS_MODULE,
@@ -79,11 +52,18 @@ static struct drm_driver driver = {
79 .mmap = drm_mmap, 52 .mmap = drm_mmap,
80 .poll = drm_poll, 53 .poll = drm_poll,
81 .fasync = drm_fasync, 54 .fasync = drm_fasync,
82 }, 55 },
83 .pci_driver = { 56 .pci_driver = {
84 .name = DRIVER_NAME, 57 .name = DRIVER_NAME,
85 .id_table = pciidlist, 58 .id_table = pciidlist,
86 } 59 },
60
61 .name = DRIVER_NAME,
62 .desc = DRIVER_DESC,
63 .date = DRIVER_DATE,
64 .major = DRIVER_MAJOR,
65 .minor = DRIVER_MINOR,
66 .patchlevel = DRIVER_PATCHLEVEL,
87}; 67};
88 68
89static int __init sis_init(void) 69static int __init sis_init(void)
diff --git a/drivers/char/drm/sis_drv.h b/drivers/char/drm/sis_drv.h
index b1fddad83a93..e218e5269503 100644
--- a/drivers/char/drm/sis_drv.h
+++ b/drivers/char/drm/sis_drv.h
@@ -1,5 +1,5 @@
1/* sis_drv.h -- Private header for sis driver -*- linux-c -*- 1/* sis_drv.h -- Private header for sis driver -*- linux-c -*- */
2 * 2/*
3 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. 3 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
4 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 4 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
5 * All rights reserved. 5 * All rights reserved.
diff --git a/drivers/char/drm/sis_ds.h b/drivers/char/drm/sis_ds.h
index da850b4f5440..94f2b4728b63 100644
--- a/drivers/char/drm/sis_ds.h
+++ b/drivers/char/drm/sis_ds.h
@@ -1,6 +1,7 @@
1/* sis_ds.h -- Private header for Direct Rendering Manager -*- linux-c -*- 1/* sis_ds.h -- Private header for Direct Rendering Manager -*- linux-c -*-
2 * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw 2 * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw
3 * 3 */
4/*
4 * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. 5 * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
5 * All rights reserved. 6 * All rights reserved.
6 * 7 *
@@ -35,7 +36,7 @@
35 36
36#define SET_SIZE 5000 37#define SET_SIZE 5000
37 38
38typedef unsigned int ITEM_TYPE; 39typedef unsigned long ITEM_TYPE;
39 40
40typedef struct { 41typedef struct {
41 ITEM_TYPE val; 42 ITEM_TYPE val;
diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c
index a8529728fa63..6774d2fe3452 100644
--- a/drivers/char/drm/sis_mm.c
+++ b/drivers/char/drm/sis_mm.c
@@ -86,7 +86,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS)
86{ 86{
87 drm_sis_mem_t fb; 87 drm_sis_mem_t fb;
88 struct sis_memreq req; 88 struct sis_memreq req;
89 drm_sis_mem_t __user *argp = (void __user *)data; 89 drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data;
90 int retval = 0; 90 int retval = 0;
91 91
92 DRM_COPY_FROM_USER_IOCTL(fb, argp, sizeof(fb)); 92 DRM_COPY_FROM_USER_IOCTL(fb, argp, sizeof(fb));
@@ -110,7 +110,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS)
110 110
111 DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb)); 111 DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb));
112 112
113 DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, req.offset); 113 DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset);
114 114
115 return retval; 115 return retval;
116} 116}
@@ -127,9 +127,9 @@ static int sis_fb_free(DRM_IOCTL_ARGS)
127 127
128 if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free)) 128 if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
129 retval = DRM_ERR(EINVAL); 129 retval = DRM_ERR(EINVAL);
130 sis_free((u32) fb.free); 130 sis_free(fb.free);
131 131
132 DRM_DEBUG("free fb, offset = %lu\n", fb.free); 132 DRM_DEBUG("free fb, offset = 0x%lx\n", fb.free);
133 133
134 return retval; 134 return retval;
135} 135}
@@ -176,7 +176,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS)
176{ 176{
177 DRM_DEVICE; 177 DRM_DEVICE;
178 drm_sis_private_t *dev_priv = dev->dev_private; 178 drm_sis_private_t *dev_priv = dev->dev_private;
179 drm_sis_mem_t __user *argp = (void __user *)data; 179 drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data;
180 drm_sis_mem_t fb; 180 drm_sis_mem_t fb;
181 PMemBlock block; 181 PMemBlock block;
182 int retval = 0; 182 int retval = 0;
@@ -267,7 +267,7 @@ static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS)
267{ 267{
268 DRM_DEVICE; 268 DRM_DEVICE;
269 drm_sis_private_t *dev_priv = dev->dev_private; 269 drm_sis_private_t *dev_priv = dev->dev_private;
270 drm_sis_mem_t __user *argp = (void __user *)data; 270 drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data;
271 drm_sis_mem_t agp; 271 drm_sis_mem_t agp;
272 PMemBlock block; 272 PMemBlock block;
273 int retval = 0; 273 int retval = 0;
@@ -367,7 +367,7 @@ int sis_final_context(struct drm_device *dev, int context)
367 367
368 if (i < MAX_CONTEXT) { 368 if (i < MAX_CONTEXT) {
369 set_t *set; 369 set_t *set;
370 unsigned int item; 370 ITEM_TYPE item;
371 int retval; 371 int retval;
372 372
373 DRM_DEBUG("find socket %d, context = %d\n", i, context); 373 DRM_DEBUG("find socket %d, context = %d\n", i, context);
@@ -376,7 +376,7 @@ int sis_final_context(struct drm_device *dev, int context)
376 set = global_ppriv[i].sets[0]; 376 set = global_ppriv[i].sets[0];
377 retval = setFirst(set, &item); 377 retval = setFirst(set, &item);
378 while (retval) { 378 while (retval) {
379 DRM_DEBUG("free video memory 0x%x\n", item); 379 DRM_DEBUG("free video memory 0x%lx\n", item);
380#if defined(__linux__) && defined(CONFIG_FB_SIS) 380#if defined(__linux__) && defined(CONFIG_FB_SIS)
381 sis_free(item); 381 sis_free(item);
382#else 382#else
@@ -390,7 +390,7 @@ int sis_final_context(struct drm_device *dev, int context)
390 set = global_ppriv[i].sets[1]; 390 set = global_ppriv[i].sets[1];
391 retval = setFirst(set, &item); 391 retval = setFirst(set, &item);
392 while (retval) { 392 while (retval) {
393 DRM_DEBUG("free agp memory 0x%x\n", item); 393 DRM_DEBUG("free agp memory 0x%lx\n", item);
394 mmFreeMem((PMemBlock) item); 394 mmFreeMem((PMemBlock) item);
395 retval = setNext(set, &item); 395 retval = setNext(set, &item);
396 } 396 }
@@ -403,12 +403,12 @@ int sis_final_context(struct drm_device *dev, int context)
403} 403}
404 404
405drm_ioctl_desc_t sis_ioctls[] = { 405drm_ioctl_desc_t sis_ioctls[] = {
406 [DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, 1, 0}, 406 [DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, DRM_AUTH},
407 [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, 1, 0}, 407 [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, DRM_AUTH},
408 [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, 1, 1}, 408 [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
409 [DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, 1, 0}, 409 [DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, DRM_AUTH},
410 [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, 1, 0}, 410 [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, DRM_AUTH},
411 [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = {sis_fb_init, 1, 1} 411 [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = {sis_fb_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}
412}; 412};
413 413
414int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls); 414int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls);
diff --git a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c
index c275cbb6e9ce..baa4416032a8 100644
--- a/drivers/char/drm/tdfx_drv.c
+++ b/drivers/char/drm/tdfx_drv.c
@@ -36,31 +36,6 @@
36 36
37#include "drm_pciids.h" 37#include "drm_pciids.h"
38 38
39static int postinit(struct drm_device *dev, unsigned long flags)
40{
41 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
42 DRIVER_NAME,
43 DRIVER_MAJOR,
44 DRIVER_MINOR,
45 DRIVER_PATCHLEVEL,
46 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
47 );
48 return 0;
49}
50
51static int version(drm_version_t * version)
52{
53 int len;
54
55 version->version_major = DRIVER_MAJOR;
56 version->version_minor = DRIVER_MINOR;
57 version->version_patchlevel = DRIVER_PATCHLEVEL;
58 DRM_COPY(version->name, DRIVER_NAME);
59 DRM_COPY(version->date, DRIVER_DATE);
60 DRM_COPY(version->desc, DRIVER_DESC);
61 return 0;
62}
63
64static struct pci_device_id pciidlist[] = { 39static struct pci_device_id pciidlist[] = {
65 tdfx_PCI_IDS 40 tdfx_PCI_IDS
66}; 41};
@@ -70,8 +45,6 @@ static struct drm_driver driver = {
70 .reclaim_buffers = drm_core_reclaim_buffers, 45 .reclaim_buffers = drm_core_reclaim_buffers,
71 .get_map_ofs = drm_core_get_map_ofs, 46 .get_map_ofs = drm_core_get_map_ofs,
72 .get_reg_ofs = drm_core_get_reg_ofs, 47 .get_reg_ofs = drm_core_get_reg_ofs,
73 .postinit = postinit,
74 .version = version,
75 .fops = { 48 .fops = {
76 .owner = THIS_MODULE, 49 .owner = THIS_MODULE,
77 .open = drm_open, 50 .open = drm_open,
@@ -80,11 +53,18 @@ static struct drm_driver driver = {
80 .mmap = drm_mmap, 53 .mmap = drm_mmap,
81 .poll = drm_poll, 54 .poll = drm_poll,
82 .fasync = drm_fasync, 55 .fasync = drm_fasync,
83 }, 56 },
84 .pci_driver = { 57 .pci_driver = {
85 .name = DRIVER_NAME, 58 .name = DRIVER_NAME,
86 .id_table = pciidlist, 59 .id_table = pciidlist,
87 } 60 },
61
62 .name = DRIVER_NAME,
63 .desc = DRIVER_DESC,
64 .date = DRIVER_DATE,
65 .major = DRIVER_MAJOR,
66 .minor = DRIVER_MINOR,
67 .patchlevel = DRIVER_PATCHLEVEL,
88}; 68};
89 69
90static int __init tdfx_init(void) 70static int __init tdfx_init(void)
diff --git a/drivers/char/drm/tdfx_drv.h b/drivers/char/drm/tdfx_drv.h
index a582a3db4c75..84204ec1b046 100644
--- a/drivers/char/drm/tdfx_drv.h
+++ b/drivers/char/drm/tdfx_drv.h
@@ -1,6 +1,7 @@
1/* tdfx.h -- 3dfx DRM template customization -*- linux-c -*- 1/* tdfx.h -- 3dfx DRM template customization -*- linux-c -*-
2 * Created: Wed Feb 14 12:32:32 2001 by gareth@valinux.com 2 * Created: Wed Feb 14 12:32:32 2001 by gareth@valinux.com
3 * 3 */
4/*
4 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
5 * All Rights Reserved. 6 * All Rights Reserved.
6 * 7 *
@@ -30,10 +31,6 @@
30#ifndef __TDFX_H__ 31#ifndef __TDFX_H__
31#define __TDFX_H__ 32#define __TDFX_H__
32 33
33/* This remains constant for all DRM template files.
34 */
35#define DRM(x) tdfx_##x
36
37/* General customization: 34/* General customization:
38 */ 35 */
39 36
diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c
index d4b1766608b0..593c0b8f650a 100644
--- a/drivers/char/drm/via_dma.c
+++ b/drivers/char/drm/via_dma.c
@@ -213,7 +213,9 @@ static int via_initialize(drm_device_t * dev,
213 dev_priv->dma_wrap = init->size; 213 dev_priv->dma_wrap = init->size;
214 dev_priv->dma_offset = init->offset; 214 dev_priv->dma_offset = init->offset;
215 dev_priv->last_pause_ptr = NULL; 215 dev_priv->last_pause_ptr = NULL;
216 dev_priv->hw_addr_ptr = dev_priv->mmio->handle + init->reg_pause_addr; 216 dev_priv->hw_addr_ptr =
217 (volatile uint32_t *)((char *)dev_priv->mmio->handle +
218 init->reg_pause_addr);
217 219
218 via_cmdbuf_start(dev_priv); 220 via_cmdbuf_start(dev_priv);
219 221
@@ -232,13 +234,13 @@ int via_dma_init(DRM_IOCTL_ARGS)
232 234
233 switch (init.func) { 235 switch (init.func) {
234 case VIA_INIT_DMA: 236 case VIA_INIT_DMA:
235 if (!capable(CAP_SYS_ADMIN)) 237 if (!DRM_SUSER(DRM_CURPROC))
236 retcode = DRM_ERR(EPERM); 238 retcode = DRM_ERR(EPERM);
237 else 239 else
238 retcode = via_initialize(dev, dev_priv, &init); 240 retcode = via_initialize(dev, dev_priv, &init);
239 break; 241 break;
240 case VIA_CLEANUP_DMA: 242 case VIA_CLEANUP_DMA:
241 if (!capable(CAP_SYS_ADMIN)) 243 if (!DRM_SUSER(DRM_CURPROC))
242 retcode = DRM_ERR(EPERM); 244 retcode = DRM_ERR(EPERM);
243 else 245 else
244 retcode = via_dma_cleanup(dev); 246 retcode = via_dma_cleanup(dev);
@@ -349,9 +351,6 @@ int via_cmdbuffer(DRM_IOCTL_ARGS)
349 return 0; 351 return 0;
350} 352}
351 353
352extern int
353via_parse_command_stream(drm_device_t * dev, const uint32_t * buf,
354 unsigned int size);
355static int via_dispatch_pci_cmdbuffer(drm_device_t * dev, 354static int via_dispatch_pci_cmdbuffer(drm_device_t * dev,
356 drm_via_cmdbuffer_t * cmd) 355 drm_via_cmdbuffer_t * cmd)
357{ 356{
@@ -450,9 +449,9 @@ static int via_hook_segment(drm_via_private_t * dev_priv,
450 if ((count <= 8) && (count >= 0)) { 449 if ((count <= 8) && (count >= 0)) {
451 uint32_t rgtr, ptr; 450 uint32_t rgtr, ptr;
452 rgtr = *(dev_priv->hw_addr_ptr); 451 rgtr = *(dev_priv->hw_addr_ptr);
453 ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) + 452 ptr = ((volatile char *)dev_priv->last_pause_ptr -
454 dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 - 453 dev_priv->dma_ptr) + dev_priv->dma_offset +
455 CMDBUF_ALIGNMENT_SIZE; 454 (uint32_t) dev_priv->agpAddr + 4 - CMDBUF_ALIGNMENT_SIZE;
456 if (rgtr <= ptr) { 455 if (rgtr <= ptr) {
457 DRM_ERROR 456 DRM_ERROR
458 ("Command regulator\npaused at count %d, address %x, " 457 ("Command regulator\npaused at count %d, address %x, "
@@ -472,7 +471,7 @@ static int via_hook_segment(drm_via_private_t * dev_priv,
472 && count--) ; 471 && count--) ;
473 472
474 rgtr = *(dev_priv->hw_addr_ptr); 473 rgtr = *(dev_priv->hw_addr_ptr);
475 ptr = ((char *)paused_at - dev_priv->dma_ptr) + 474 ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) +
476 dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; 475 dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
477 476
478 ptr_low = (ptr > 3 * CMDBUF_ALIGNMENT_SIZE) ? 477 ptr_low = (ptr > 3 * CMDBUF_ALIGNMENT_SIZE) ?
@@ -724,3 +723,22 @@ int via_cmdbuf_size(DRM_IOCTL_ARGS)
724 sizeof(d_siz)); 723 sizeof(d_siz));
725 return ret; 724 return ret;
726} 725}
726
727drm_ioctl_desc_t via_ioctls[] = {
728 [DRM_IOCTL_NR(DRM_VIA_ALLOCMEM)] = {via_mem_alloc, DRM_AUTH},
729 [DRM_IOCTL_NR(DRM_VIA_FREEMEM)] = {via_mem_free, DRM_AUTH},
730 [DRM_IOCTL_NR(DRM_VIA_AGP_INIT)] = {via_agp_init, DRM_AUTH|DRM_MASTER},
731 [DRM_IOCTL_NR(DRM_VIA_FB_INIT)] = {via_fb_init, DRM_AUTH|DRM_MASTER},
732 [DRM_IOCTL_NR(DRM_VIA_MAP_INIT)] = {via_map_init, DRM_AUTH|DRM_MASTER},
733 [DRM_IOCTL_NR(DRM_VIA_DEC_FUTEX)] = {via_decoder_futex, DRM_AUTH},
734 [DRM_IOCTL_NR(DRM_VIA_DMA_INIT)] = {via_dma_init, DRM_AUTH},
735 [DRM_IOCTL_NR(DRM_VIA_CMDBUFFER)] = {via_cmdbuffer, DRM_AUTH},
736 [DRM_IOCTL_NR(DRM_VIA_FLUSH)] = {via_flush_ioctl, DRM_AUTH},
737 [DRM_IOCTL_NR(DRM_VIA_PCICMD)] = {via_pci_cmdbuffer, DRM_AUTH},
738 [DRM_IOCTL_NR(DRM_VIA_CMDBUF_SIZE)] = {via_cmdbuf_size, DRM_AUTH},
739 [DRM_IOCTL_NR(DRM_VIA_WAIT_IRQ)] = {via_wait_irq, DRM_AUTH},
740 [DRM_IOCTL_NR(DRM_VIA_DMA_BLIT)] = {via_dma_blit, DRM_AUTH},
741 [DRM_IOCTL_NR(DRM_VIA_BLIT_SYNC)] = {via_dma_blit_sync, DRM_AUTH}
742};
743
744int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls);
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c
new file mode 100644
index 000000000000..9d5e027dae0e
--- /dev/null
+++ b/drivers/char/drm/via_dmablit.c
@@ -0,0 +1,805 @@
1/* via_dmablit.c -- PCI DMA BitBlt support for the VIA Unichrome/Pro
2 *
3 * Copyright (C) 2005 Thomas Hellstrom, All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Thomas Hellstrom.
26 * Partially based on code obtained from Digeo Inc.
27 */
28
29
30/*
31 * Unmaps the DMA mappings.
32 * FIXME: Is this a NoOp on x86? Also
33 * FIXME: What happens if this one is called and a pending blit has previously done
34 * the same DMA mappings?
35 */
36
37#include "drmP.h"
38#include "via_drm.h"
39#include "via_drv.h"
40#include "via_dmablit.h"
41
42#include <linux/pagemap.h>
43
44#define VIA_PGDN(x) (((unsigned long)(x)) & PAGE_MASK)
45#define VIA_PGOFF(x) (((unsigned long)(x)) & ~PAGE_MASK)
46#define VIA_PFN(x) ((unsigned long)(x) >> PAGE_SHIFT)
47
48typedef struct _drm_via_descriptor {
49 uint32_t mem_addr;
50 uint32_t dev_addr;
51 uint32_t size;
52 uint32_t next;
53} drm_via_descriptor_t;
54
55
56/*
57 * Unmap a DMA mapping.
58 */
59
60
61
62static void
63via_unmap_blit_from_device(struct pci_dev *pdev, drm_via_sg_info_t *vsg)
64{
65 int num_desc = vsg->num_desc;
66 unsigned cur_descriptor_page = num_desc / vsg->descriptors_per_page;
67 unsigned descriptor_this_page = num_desc % vsg->descriptors_per_page;
68 drm_via_descriptor_t *desc_ptr = vsg->desc_pages[cur_descriptor_page] +
69 descriptor_this_page;
70 dma_addr_t next = vsg->chain_start;
71
72 while(num_desc--) {
73 if (descriptor_this_page-- == 0) {
74 cur_descriptor_page--;
75 descriptor_this_page = vsg->descriptors_per_page - 1;
76 desc_ptr = vsg->desc_pages[cur_descriptor_page] +
77 descriptor_this_page;
78 }
79 dma_unmap_single(&pdev->dev, next, sizeof(*desc_ptr), DMA_TO_DEVICE);
80 dma_unmap_page(&pdev->dev, desc_ptr->mem_addr, desc_ptr->size, vsg->direction);
81 next = (dma_addr_t) desc_ptr->next;
82 desc_ptr--;
83 }
84}
85
86/*
87 * If mode = 0, count how many descriptors are needed.
88 * If mode = 1, Map the DMA pages for the device, put together and map also the descriptors.
89 * Descriptors are run in reverse order by the hardware because we are not allowed to update the
90 * 'next' field without syncing calls when the descriptor is already mapped.
91 */
92
93static void
94via_map_blit_for_device(struct pci_dev *pdev,
95 const drm_via_dmablit_t *xfer,
96 drm_via_sg_info_t *vsg,
97 int mode)
98{
99 unsigned cur_descriptor_page = 0;
100 unsigned num_descriptors_this_page = 0;
101 unsigned char *mem_addr = xfer->mem_addr;
102 unsigned char *cur_mem;
103 unsigned char *first_addr = (unsigned char *)VIA_PGDN(mem_addr);
104 uint32_t fb_addr = xfer->fb_addr;
105 uint32_t cur_fb;
106 unsigned long line_len;
107 unsigned remaining_len;
108 int num_desc = 0;
109 int cur_line;
110 dma_addr_t next = 0 | VIA_DMA_DPR_EC;
111 drm_via_descriptor_t *desc_ptr = 0;
112
113 if (mode == 1)
114 desc_ptr = vsg->desc_pages[cur_descriptor_page];
115
116 for (cur_line = 0; cur_line < xfer->num_lines; ++cur_line) {
117
118 line_len = xfer->line_length;
119 cur_fb = fb_addr;
120 cur_mem = mem_addr;
121
122 while (line_len > 0) {
123
124 remaining_len = min(PAGE_SIZE-VIA_PGOFF(cur_mem), line_len);
125 line_len -= remaining_len;
126
127 if (mode == 1) {
128 desc_ptr->mem_addr =
129 dma_map_page(&pdev->dev,
130 vsg->pages[VIA_PFN(cur_mem) -
131 VIA_PFN(first_addr)],
132 VIA_PGOFF(cur_mem), remaining_len,
133 vsg->direction);
134 desc_ptr->dev_addr = cur_fb;
135
136 desc_ptr->size = remaining_len;
137 desc_ptr->next = (uint32_t) next;
138 next = dma_map_single(&pdev->dev, desc_ptr, sizeof(*desc_ptr),
139 DMA_TO_DEVICE);
140 desc_ptr++;
141 if (++num_descriptors_this_page >= vsg->descriptors_per_page) {
142 num_descriptors_this_page = 0;
143 desc_ptr = vsg->desc_pages[++cur_descriptor_page];
144 }
145 }
146
147 num_desc++;
148 cur_mem += remaining_len;
149 cur_fb += remaining_len;
150 }
151
152 mem_addr += xfer->mem_stride;
153 fb_addr += xfer->fb_stride;
154 }
155
156 if (mode == 1) {
157 vsg->chain_start = next;
158 vsg->state = dr_via_device_mapped;
159 }
160 vsg->num_desc = num_desc;
161}
162
163/*
164 * Function that frees up all resources for a blit. It is usable even if the
165 * blit info has only be partially built as long as the status enum is consistent
166 * with the actual status of the used resources.
167 */
168
169
170void
171via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg)
172{
173 struct page *page;
174 int i;
175
176 switch(vsg->state) {
177 case dr_via_device_mapped:
178 via_unmap_blit_from_device(pdev, vsg);
179 case dr_via_desc_pages_alloc:
180 for (i=0; i<vsg->num_desc_pages; ++i) {
181 if (vsg->desc_pages[i] != NULL)
182 free_page((unsigned long)vsg->desc_pages[i]);
183 }
184 kfree(vsg->desc_pages);
185 case dr_via_pages_locked:
186 for (i=0; i<vsg->num_pages; ++i) {
187 if ( NULL != (page = vsg->pages[i])) {
188 if (! PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction))
189 SetPageDirty(page);
190 page_cache_release(page);
191 }
192 }
193 case dr_via_pages_alloc:
194 vfree(vsg->pages);
195 default:
196 vsg->state = dr_via_sg_init;
197 }
198 if (vsg->bounce_buffer) {
199 vfree(vsg->bounce_buffer);
200 vsg->bounce_buffer = NULL;
201 }
202 vsg->free_on_sequence = 0;
203}
204
205/*
206 * Fire a blit engine.
207 */
208
209static void
210via_fire_dmablit(drm_device_t *dev, drm_via_sg_info_t *vsg, int engine)
211{
212 drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
213
214 VIA_WRITE(VIA_PCI_DMA_MAR0 + engine*0x10, 0);
215 VIA_WRITE(VIA_PCI_DMA_DAR0 + engine*0x10, 0);
216 VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DD | VIA_DMA_CSR_TD |
217 VIA_DMA_CSR_DE);
218 VIA_WRITE(VIA_PCI_DMA_MR0 + engine*0x04, VIA_DMA_MR_CM | VIA_DMA_MR_TDIE);
219 VIA_WRITE(VIA_PCI_DMA_BCR0 + engine*0x10, 0);
220 VIA_WRITE(VIA_PCI_DMA_DPR0 + engine*0x10, vsg->chain_start);
221 VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DE | VIA_DMA_CSR_TS);
222}
223
224/*
225 * Obtain a page pointer array and lock all pages into system memory. A segmentation violation will
226 * occur here if the calling user does not have access to the submitted address.
227 */
228
229static int
230via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer)
231{
232 int ret;
233 unsigned long first_pfn = VIA_PFN(xfer->mem_addr);
234 vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride -1)) -
235 first_pfn + 1;
236
237 if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages)))
238 return DRM_ERR(ENOMEM);
239 memset(vsg->pages, 0, sizeof(struct page *) * vsg->num_pages);
240 down_read(&current->mm->mmap_sem);
241 ret = get_user_pages(current, current->mm, (unsigned long) xfer->mem_addr,
242 vsg->num_pages, vsg->direction, 0, vsg->pages, NULL);
243
244 up_read(&current->mm->mmap_sem);
245 if (ret != vsg->num_pages) {
246 if (ret < 0)
247 return ret;
248 vsg->state = dr_via_pages_locked;
249 return DRM_ERR(EINVAL);
250 }
251 vsg->state = dr_via_pages_locked;
252 DRM_DEBUG("DMA pages locked\n");
253 return 0;
254}
255
256/*
257 * Allocate DMA capable memory for the blit descriptor chain, and an array that keeps track of the
258 * pages we allocate. We don't want to use kmalloc for the descriptor chain because it may be
259 * quite large for some blits, and pages don't need to be contingous.
260 */
261
262static int
263via_alloc_desc_pages(drm_via_sg_info_t *vsg)
264{
265 int i;
266
267 vsg->descriptors_per_page = PAGE_SIZE / sizeof( drm_via_descriptor_t);
268 vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) /
269 vsg->descriptors_per_page;
270
271 if (NULL == (vsg->desc_pages = kmalloc(sizeof(void *) * vsg->num_desc_pages, GFP_KERNEL)))
272 return DRM_ERR(ENOMEM);
273
274 memset(vsg->desc_pages, 0, sizeof(void *) * vsg->num_desc_pages);
275 vsg->state = dr_via_desc_pages_alloc;
276 for (i=0; i<vsg->num_desc_pages; ++i) {
277 if (NULL == (vsg->desc_pages[i] =
278 (drm_via_descriptor_t *) __get_free_page(GFP_KERNEL)))
279 return DRM_ERR(ENOMEM);
280 }
281 DRM_DEBUG("Allocated %d pages for %d descriptors.\n", vsg->num_desc_pages,
282 vsg->num_desc);
283 return 0;
284}
285
286static void
287via_abort_dmablit(drm_device_t *dev, int engine)
288{
289 drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
290
291 VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TA);
292}
293
294static void
295via_dmablit_engine_off(drm_device_t *dev, int engine)
296{
297 drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
298
299 VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TD | VIA_DMA_CSR_DD);
300}
301
302
303
304/*
305 * The dmablit part of the IRQ handler. Trying to do only reasonably fast things here.
306 * The rest, like unmapping and freeing memory for done blits is done in a separate workqueue
307 * task. Basically the task of the interrupt handler is to submit a new blit to the engine, while
308 * the workqueue task takes care of processing associated with the old blit.
309 */
310
311void
312via_dmablit_handler(drm_device_t *dev, int engine, int from_irq)
313{
314 drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
315 drm_via_blitq_t *blitq = dev_priv->blit_queues + engine;
316 int cur;
317 int done_transfer;
318 unsigned long irqsave=0;
319 uint32_t status = 0;
320
321 DRM_DEBUG("DMA blit handler called. engine = %d, from_irq = %d, blitq = 0x%lx\n",
322 engine, from_irq, (unsigned long) blitq);
323
324 if (from_irq) {
325 spin_lock(&blitq->blit_lock);
326 } else {
327 spin_lock_irqsave(&blitq->blit_lock, irqsave);
328 }
329
330 done_transfer = blitq->is_active &&
331 (( status = VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04)) & VIA_DMA_CSR_TD);
332 done_transfer = done_transfer || ( blitq->aborting && !(status & VIA_DMA_CSR_DE));
333
334 cur = blitq->cur;
335 if (done_transfer) {
336
337 blitq->blits[cur]->aborted = blitq->aborting;
338 blitq->done_blit_handle++;
339 DRM_WAKEUP(blitq->blit_queue + cur);
340
341 cur++;
342 if (cur >= VIA_NUM_BLIT_SLOTS)
343 cur = 0;
344 blitq->cur = cur;
345
346 /*
347 * Clear transfer done flag.
348 */
349
350 VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TD);
351
352 blitq->is_active = 0;
353 blitq->aborting = 0;
354 schedule_work(&blitq->wq);
355
356 } else if (blitq->is_active && time_after_eq(jiffies, blitq->end)) {
357
358 /*
359 * Abort transfer after one second.
360 */
361
362 via_abort_dmablit(dev, engine);
363 blitq->aborting = 1;
364 blitq->end = jiffies + DRM_HZ;
365 }
366
367 if (!blitq->is_active) {
368 if (blitq->num_outstanding) {
369 via_fire_dmablit(dev, blitq->blits[cur], engine);
370 blitq->is_active = 1;
371 blitq->cur = cur;
372 blitq->num_outstanding--;
373 blitq->end = jiffies + DRM_HZ;
374 if (!timer_pending(&blitq->poll_timer)) {
375 blitq->poll_timer.expires = jiffies+1;
376 add_timer(&blitq->poll_timer);
377 }
378 } else {
379 if (timer_pending(&blitq->poll_timer)) {
380 del_timer(&blitq->poll_timer);
381 }
382 via_dmablit_engine_off(dev, engine);
383 }
384 }
385
386 if (from_irq) {
387 spin_unlock(&blitq->blit_lock);
388 } else {
389 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
390 }
391}
392
393
394
395/*
396 * Check whether this blit is still active, performing necessary locking.
397 */
398
399static int
400via_dmablit_active(drm_via_blitq_t *blitq, int engine, uint32_t handle, wait_queue_head_t **queue)
401{
402 unsigned long irqsave;
403 uint32_t slot;
404 int active;
405
406 spin_lock_irqsave(&blitq->blit_lock, irqsave);
407
408 /*
409 * Allow for handle wraparounds.
410 */
411
412 active = ((blitq->done_blit_handle - handle) > (1 << 23)) &&
413 ((blitq->cur_blit_handle - handle) <= (1 << 23));
414
415 if (queue && active) {
416 slot = handle - blitq->done_blit_handle + blitq->cur -1;
417 if (slot >= VIA_NUM_BLIT_SLOTS) {
418 slot -= VIA_NUM_BLIT_SLOTS;
419 }
420 *queue = blitq->blit_queue + slot;
421 }
422
423 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
424
425 return active;
426}
427
428/*
429 * Sync. Wait for at least three seconds for the blit to be performed.
430 */
431
432static int
433via_dmablit_sync(drm_device_t *dev, uint32_t handle, int engine)
434{
435
436 drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
437 drm_via_blitq_t *blitq = dev_priv->blit_queues + engine;
438 wait_queue_head_t *queue;
439 int ret = 0;
440
441 if (via_dmablit_active(blitq, engine, handle, &queue)) {
442 DRM_WAIT_ON(ret, *queue, 3 * DRM_HZ,
443 !via_dmablit_active(blitq, engine, handle, NULL));
444 }
445 DRM_DEBUG("DMA blit sync handle 0x%x engine %d returned %d\n",
446 handle, engine, ret);
447
448 return ret;
449}
450
451
452/*
453 * A timer that regularly polls the blit engine in cases where we don't have interrupts:
454 * a) Broken hardware (typically those that don't have any video capture facility).
455 * b) Blit abort. The hardware doesn't send an interrupt when a blit is aborted.
456 * The timer and hardware IRQ's can and do work in parallel. If the hardware has
457 * irqs, it will shorten the latency somewhat.
458 */
459
460
461
462static void
463via_dmablit_timer(unsigned long data)
464{
465 drm_via_blitq_t *blitq = (drm_via_blitq_t *) data;
466 drm_device_t *dev = blitq->dev;
467 int engine = (int)
468 (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues);
469
470 DRM_DEBUG("Polling timer called for engine %d, jiffies %lu\n", engine,
471 (unsigned long) jiffies);
472
473 via_dmablit_handler(dev, engine, 0);
474
475 if (!timer_pending(&blitq->poll_timer)) {
476 blitq->poll_timer.expires = jiffies+1;
477 add_timer(&blitq->poll_timer);
478 }
479 via_dmablit_handler(dev, engine, 0);
480
481}
482
483
484
485
486/*
487 * Workqueue task that frees data and mappings associated with a blit.
488 * Also wakes up waiting processes. Each of these tasks handles one
489 * blit engine only and may not be called on each interrupt.
490 */
491
492
493static void
494via_dmablit_workqueue(void *data)
495{
496 drm_via_blitq_t *blitq = (drm_via_blitq_t *) data;
497 drm_device_t *dev = blitq->dev;
498 unsigned long irqsave;
499 drm_via_sg_info_t *cur_sg;
500 int cur_released;
501
502
503 DRM_DEBUG("Workqueue task called for blit engine %ld\n",(unsigned long)
504 (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues));
505
506 spin_lock_irqsave(&blitq->blit_lock, irqsave);
507
508 while(blitq->serviced != blitq->cur) {
509
510 cur_released = blitq->serviced++;
511
512 DRM_DEBUG("Releasing blit slot %d\n", cur_released);
513
514 if (blitq->serviced >= VIA_NUM_BLIT_SLOTS)
515 blitq->serviced = 0;
516
517 cur_sg = blitq->blits[cur_released];
518 blitq->num_free++;
519
520 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
521
522 DRM_WAKEUP(&blitq->busy_queue);
523
524 via_free_sg_info(dev->pdev, cur_sg);
525 kfree(cur_sg);
526
527 spin_lock_irqsave(&blitq->blit_lock, irqsave);
528 }
529
530 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
531}
532
533
534/*
535 * Init all blit engines. Currently we use two, but some hardware have 4.
536 */
537
538
539void
540via_init_dmablit(drm_device_t *dev)
541{
542 int i,j;
543 drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
544 drm_via_blitq_t *blitq;
545
546 pci_set_master(dev->pdev);
547
548 for (i=0; i< VIA_NUM_BLIT_ENGINES; ++i) {
549 blitq = dev_priv->blit_queues + i;
550 blitq->dev = dev;
551 blitq->cur_blit_handle = 0;
552 blitq->done_blit_handle = 0;
553 blitq->head = 0;
554 blitq->cur = 0;
555 blitq->serviced = 0;
556 blitq->num_free = VIA_NUM_BLIT_SLOTS;
557 blitq->num_outstanding = 0;
558 blitq->is_active = 0;
559 blitq->aborting = 0;
560 blitq->blit_lock = SPIN_LOCK_UNLOCKED;
561 for (j=0; j<VIA_NUM_BLIT_SLOTS; ++j) {
562 DRM_INIT_WAITQUEUE(blitq->blit_queue + j);
563 }
564 DRM_INIT_WAITQUEUE(&blitq->busy_queue);
565 INIT_WORK(&blitq->wq, via_dmablit_workqueue, blitq);
566 init_timer(&blitq->poll_timer);
567 blitq->poll_timer.function = &via_dmablit_timer;
568 blitq->poll_timer.data = (unsigned long) blitq;
569 }
570}
571
572/*
573 * Build all info and do all mappings required for a blit.
574 */
575
576
577static int
578via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer)
579{
580 int draw = xfer->to_fb;
581 int ret = 0;
582
583 vsg->direction = (draw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
584 vsg->bounce_buffer = 0;
585
586 vsg->state = dr_via_sg_init;
587
588 if (xfer->num_lines <= 0 || xfer->line_length <= 0) {
589 DRM_ERROR("Zero size bitblt.\n");
590 return DRM_ERR(EINVAL);
591 }
592
593 /*
594 * Below check is a driver limitation, not a hardware one. We
595 * don't want to lock unused pages, and don't want to incoporate the
596 * extra logic of avoiding them. Make sure there are no.
597 * (Not a big limitation anyway.)
598 */
599
600 if (((xfer->mem_stride - xfer->line_length) >= PAGE_SIZE) ||
601 (xfer->mem_stride > 2048*4)) {
602 DRM_ERROR("Too large system memory stride. Stride: %d, "
603 "Length: %d\n", xfer->mem_stride, xfer->line_length);
604 return DRM_ERR(EINVAL);
605 }
606
607 if (xfer->num_lines > 2048) {
608 DRM_ERROR("Too many PCI DMA bitblt lines.\n");
609 return DRM_ERR(EINVAL);
610 }
611
612 /*
613 * we allow a negative fb stride to allow flipping of images in
614 * transfer.
615 */
616
617 if (xfer->mem_stride < xfer->line_length ||
618 abs(xfer->fb_stride) < xfer->line_length) {
619 DRM_ERROR("Invalid frame-buffer / memory stride.\n");
620 return DRM_ERR(EINVAL);
621 }
622
623 /*
624 * A hardware bug seems to be worked around if system memory addresses start on
625 * 16 byte boundaries. This seems a bit restrictive however. VIA is contacted
626 * about this. Meanwhile, impose the following restrictions:
627 */
628
629#ifdef VIA_BUGFREE
630 if ((((unsigned long)xfer->mem_addr & 3) != ((unsigned long)xfer->fb_addr & 3)) ||
631 ((xfer->mem_stride & 3) != (xfer->fb_stride & 3))) {
632 DRM_ERROR("Invalid DRM bitblt alignment.\n");
633 return DRM_ERR(EINVAL);
634 }
635#else
636 if ((((unsigned long)xfer->mem_addr & 15) ||
637 ((unsigned long)xfer->fb_addr & 3)) || (xfer->mem_stride & 15) ||
638 (xfer->fb_stride & 3)) {
639 DRM_ERROR("Invalid DRM bitblt alignment.\n");
640 return DRM_ERR(EINVAL);
641 }
642#endif
643
644 if (0 != (ret = via_lock_all_dma_pages(vsg, xfer))) {
645 DRM_ERROR("Could not lock DMA pages.\n");
646 via_free_sg_info(dev->pdev, vsg);
647 return ret;
648 }
649
650 via_map_blit_for_device(dev->pdev, xfer, vsg, 0);
651 if (0 != (ret = via_alloc_desc_pages(vsg))) {
652 DRM_ERROR("Could not allocate DMA descriptor pages.\n");
653 via_free_sg_info(dev->pdev, vsg);
654 return ret;
655 }
656 via_map_blit_for_device(dev->pdev, xfer, vsg, 1);
657
658 return 0;
659}
660
661
662/*
663 * Reserve one free slot in the blit queue. Will wait for one second for one
664 * to become available. Otherwise -EBUSY is returned.
665 */
666
667static int
668via_dmablit_grab_slot(drm_via_blitq_t *blitq, int engine)
669{
670 int ret=0;
671 unsigned long irqsave;
672
673 DRM_DEBUG("Num free is %d\n", blitq->num_free);
674 spin_lock_irqsave(&blitq->blit_lock, irqsave);
675 while(blitq->num_free == 0) {
676 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
677
678 DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ, blitq->num_free > 0);
679 if (ret) {
680 return (DRM_ERR(EINTR) == ret) ? DRM_ERR(EAGAIN) : ret;
681 }
682
683 spin_lock_irqsave(&blitq->blit_lock, irqsave);
684 }
685
686 blitq->num_free--;
687 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
688
689 return 0;
690}
691
692/*
693 * Hand back a free slot if we changed our mind.
694 */
695
696static void
697via_dmablit_release_slot(drm_via_blitq_t *blitq)
698{
699 unsigned long irqsave;
700
701 spin_lock_irqsave(&blitq->blit_lock, irqsave);
702 blitq->num_free++;
703 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
704 DRM_WAKEUP( &blitq->busy_queue );
705}
706
707/*
708 * Grab a free slot. Build blit info and queue a blit.
709 */
710
711
712static int
713via_dmablit(drm_device_t *dev, drm_via_dmablit_t *xfer)
714{
715 drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
716 drm_via_sg_info_t *vsg;
717 drm_via_blitq_t *blitq;
718 int ret;
719 int engine;
720 unsigned long irqsave;
721
722 if (dev_priv == NULL) {
723 DRM_ERROR("Called without initialization.\n");
724 return DRM_ERR(EINVAL);
725 }
726
727 engine = (xfer->to_fb) ? 0 : 1;
728 blitq = dev_priv->blit_queues + engine;
729 if (0 != (ret = via_dmablit_grab_slot(blitq, engine))) {
730 return ret;
731 }
732 if (NULL == (vsg = kmalloc(sizeof(*vsg), GFP_KERNEL))) {
733 via_dmablit_release_slot(blitq);
734 return DRM_ERR(ENOMEM);
735 }
736 if (0 != (ret = via_build_sg_info(dev, vsg, xfer))) {
737 via_dmablit_release_slot(blitq);
738 kfree(vsg);
739 return ret;
740 }
741 spin_lock_irqsave(&blitq->blit_lock, irqsave);
742
743 blitq->blits[blitq->head++] = vsg;
744 if (blitq->head >= VIA_NUM_BLIT_SLOTS)
745 blitq->head = 0;
746 blitq->num_outstanding++;
747 xfer->sync.sync_handle = ++blitq->cur_blit_handle;
748
749 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
750 xfer->sync.engine = engine;
751
752 via_dmablit_handler(dev, engine, 0);
753
754 return 0;
755}
756
757/*
758 * Sync on a previously submitted blit. Note that the X server use signals extensively, and
759 * that there is a very big proability that this IOCTL will be interrupted by a signal. In that
760 * case it returns with -EAGAIN for the signal to be delivered.
761 * The caller should then reissue the IOCTL. This is similar to what is being done for drmGetLock().
762 */
763
764int
765via_dma_blit_sync( DRM_IOCTL_ARGS )
766{
767 drm_via_blitsync_t sync;
768 int err;
769 DRM_DEVICE;
770
771 DRM_COPY_FROM_USER_IOCTL(sync, (drm_via_blitsync_t *)data, sizeof(sync));
772
773 if (sync.engine >= VIA_NUM_BLIT_ENGINES)
774 return DRM_ERR(EINVAL);
775
776 err = via_dmablit_sync(dev, sync.sync_handle, sync.engine);
777
778 if (DRM_ERR(EINTR) == err)
779 err = DRM_ERR(EAGAIN);
780
781 return err;
782}
783
784
785/*
786 * Queue a blit and hand back a handle to be used for sync. This IOCTL may be interrupted by a signal
787 * while waiting for a free slot in the blit queue. In that case it returns with -EAGAIN and should
788 * be reissued. See the above IOCTL code.
789 */
790
791int
792via_dma_blit( DRM_IOCTL_ARGS )
793{
794 drm_via_dmablit_t xfer;
795 int err;
796 DRM_DEVICE;
797
798 DRM_COPY_FROM_USER_IOCTL(xfer, (drm_via_dmablit_t __user *)data, sizeof(xfer));
799
800 err = via_dmablit(dev, &xfer);
801
802 DRM_COPY_TO_USER_IOCTL((void __user *)data, xfer, sizeof(xfer));
803
804 return err;
805}
diff --git a/drivers/char/drm/via_dmablit.h b/drivers/char/drm/via_dmablit.h
new file mode 100644
index 000000000000..f4036cd5d0e0
--- /dev/null
+++ b/drivers/char/drm/via_dmablit.h
@@ -0,0 +1,140 @@
1/* via_dmablit.h -- PCI DMA BitBlt support for the VIA Unichrome/Pro
2 *
3 * Copyright 2005 Thomas Hellstrom.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Thomas Hellstrom.
27 * Register info from Digeo Inc.
28 */
29
30#ifndef _VIA_DMABLIT_H
31#define _VIA_DMABLIT_H
32
33#include <linux/dma-mapping.h>
34
35#define VIA_NUM_BLIT_ENGINES 2
36#define VIA_NUM_BLIT_SLOTS 8
37
38struct _drm_via_descriptor;
39
40typedef struct _drm_via_sg_info {
41 struct page **pages;
42 unsigned long num_pages;
43 struct _drm_via_descriptor **desc_pages;
44 int num_desc_pages;
45 int num_desc;
46 enum dma_data_direction direction;
47 unsigned char *bounce_buffer;
48 dma_addr_t chain_start;
49 uint32_t free_on_sequence;
50 unsigned int descriptors_per_page;
51 int aborted;
52 enum {
53 dr_via_device_mapped,
54 dr_via_desc_pages_alloc,
55 dr_via_pages_locked,
56 dr_via_pages_alloc,
57 dr_via_sg_init
58 } state;
59} drm_via_sg_info_t;
60
61typedef struct _drm_via_blitq {
62 drm_device_t *dev;
63 uint32_t cur_blit_handle;
64 uint32_t done_blit_handle;
65 unsigned serviced;
66 unsigned head;
67 unsigned cur;
68 unsigned num_free;
69 unsigned num_outstanding;
70 unsigned long end;
71 int aborting;
72 int is_active;
73 drm_via_sg_info_t *blits[VIA_NUM_BLIT_SLOTS];
74 spinlock_t blit_lock;
75 wait_queue_head_t blit_queue[VIA_NUM_BLIT_SLOTS];
76 wait_queue_head_t busy_queue;
77 struct work_struct wq;
78 struct timer_list poll_timer;
79} drm_via_blitq_t;
80
81
82/*
83 * PCI DMA Registers
84 * Channels 2 & 3 don't seem to be implemented in hardware.
85 */
86
87#define VIA_PCI_DMA_MAR0 0xE40 /* Memory Address Register of Channel 0 */
88#define VIA_PCI_DMA_DAR0 0xE44 /* Device Address Register of Channel 0 */
89#define VIA_PCI_DMA_BCR0 0xE48 /* Byte Count Register of Channel 0 */
90#define VIA_PCI_DMA_DPR0 0xE4C /* Descriptor Pointer Register of Channel 0 */
91
92#define VIA_PCI_DMA_MAR1 0xE50 /* Memory Address Register of Channel 1 */
93#define VIA_PCI_DMA_DAR1 0xE54 /* Device Address Register of Channel 1 */
94#define VIA_PCI_DMA_BCR1 0xE58 /* Byte Count Register of Channel 1 */
95#define VIA_PCI_DMA_DPR1 0xE5C /* Descriptor Pointer Register of Channel 1 */
96
97#define VIA_PCI_DMA_MAR2 0xE60 /* Memory Address Register of Channel 2 */
98#define VIA_PCI_DMA_DAR2 0xE64 /* Device Address Register of Channel 2 */
99#define VIA_PCI_DMA_BCR2 0xE68 /* Byte Count Register of Channel 2 */
100#define VIA_PCI_DMA_DPR2 0xE6C /* Descriptor Pointer Register of Channel 2 */
101
102#define VIA_PCI_DMA_MAR3 0xE70 /* Memory Address Register of Channel 3 */
103#define VIA_PCI_DMA_DAR3 0xE74 /* Device Address Register of Channel 3 */
104#define VIA_PCI_DMA_BCR3 0xE78 /* Byte Count Register of Channel 3 */
105#define VIA_PCI_DMA_DPR3 0xE7C /* Descriptor Pointer Register of Channel 3 */
106
107#define VIA_PCI_DMA_MR0 0xE80 /* Mode Register of Channel 0 */
108#define VIA_PCI_DMA_MR1 0xE84 /* Mode Register of Channel 1 */
109#define VIA_PCI_DMA_MR2 0xE88 /* Mode Register of Channel 2 */
110#define VIA_PCI_DMA_MR3 0xE8C /* Mode Register of Channel 3 */
111
112#define VIA_PCI_DMA_CSR0 0xE90 /* Command/Status Register of Channel 0 */
113#define VIA_PCI_DMA_CSR1 0xE94 /* Command/Status Register of Channel 1 */
114#define VIA_PCI_DMA_CSR2 0xE98 /* Command/Status Register of Channel 2 */
115#define VIA_PCI_DMA_CSR3 0xE9C /* Command/Status Register of Channel 3 */
116
117#define VIA_PCI_DMA_PTR 0xEA0 /* Priority Type Register */
118
119/* Define for DMA engine */
120/* DPR */
121#define VIA_DMA_DPR_EC (1<<1) /* end of chain */
122#define VIA_DMA_DPR_DDIE (1<<2) /* descriptor done interrupt enable */
123#define VIA_DMA_DPR_DT (1<<3) /* direction of transfer (RO) */
124
125/* MR */
126#define VIA_DMA_MR_CM (1<<0) /* chaining mode */
127#define VIA_DMA_MR_TDIE (1<<1) /* transfer done interrupt enable */
128#define VIA_DMA_MR_HENDMACMD (1<<7) /* ? */
129
130/* CSR */
131#define VIA_DMA_CSR_DE (1<<0) /* DMA enable */
132#define VIA_DMA_CSR_TS (1<<1) /* transfer start */
133#define VIA_DMA_CSR_TA (1<<2) /* transfer abort */
134#define VIA_DMA_CSR_TD (1<<3) /* transfer done */
135#define VIA_DMA_CSR_DD (1<<4) /* descriptor done */
136#define VIA_DMA_DPR_EC (1<<1) /* end of chain */
137
138
139
140#endif
diff --git a/drivers/char/drm/via_drm.h b/drivers/char/drm/via_drm.h
index ebde9206115e..47f0b5b26379 100644
--- a/drivers/char/drm/via_drm.h
+++ b/drivers/char/drm/via_drm.h
@@ -75,6 +75,8 @@
75#define DRM_VIA_CMDBUF_SIZE 0x0b 75#define DRM_VIA_CMDBUF_SIZE 0x0b
76#define NOT_USED 76#define NOT_USED
77#define DRM_VIA_WAIT_IRQ 0x0d 77#define DRM_VIA_WAIT_IRQ 0x0d
78#define DRM_VIA_DMA_BLIT 0x0e
79#define DRM_VIA_BLIT_SYNC 0x0f
78 80
79#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t) 81#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t)
80#define DRM_IOCTL_VIA_FREEMEM DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t) 82#define DRM_IOCTL_VIA_FREEMEM DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t)
@@ -89,6 +91,8 @@
89#define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, \ 91#define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, \
90 drm_via_cmdbuf_size_t) 92 drm_via_cmdbuf_size_t)
91#define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t) 93#define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t)
94#define DRM_IOCTL_VIA_DMA_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_DMA_BLIT, drm_via_dmablit_t)
95#define DRM_IOCTL_VIA_BLIT_SYNC DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_BLIT_SYNC, drm_via_blitsync_t)
92 96
93/* Indices into buf.Setup where various bits of state are mirrored per 97/* Indices into buf.Setup where various bits of state are mirrored per
94 * context and per buffer. These can be fired at the card as a unit, 98 * context and per buffer. These can be fired at the card as a unit,
@@ -103,8 +107,12 @@
103#define VIA_BACK 0x2 107#define VIA_BACK 0x2
104#define VIA_DEPTH 0x4 108#define VIA_DEPTH 0x4
105#define VIA_STENCIL 0x8 109#define VIA_STENCIL 0x8
106#define VIDEO 0 110#define VIA_MEM_VIDEO 0 /* matches drm constant */
107#define AGP 1 111#define VIA_MEM_AGP 1 /* matches drm constant */
112#define VIA_MEM_SYSTEM 2
113#define VIA_MEM_MIXED 3
114#define VIA_MEM_UNKNOWN 4
115
108typedef struct { 116typedef struct {
109 uint32_t offset; 117 uint32_t offset;
110 uint32_t size; 118 uint32_t size;
@@ -192,6 +200,9 @@ typedef struct _drm_via_sarea {
192 unsigned int XvMCSubPicOn[VIA_NR_XVMC_PORTS]; 200 unsigned int XvMCSubPicOn[VIA_NR_XVMC_PORTS];
193 unsigned int XvMCCtxNoGrabbed; /* Last context to hold decoder */ 201 unsigned int XvMCCtxNoGrabbed; /* Last context to hold decoder */
194 202
203 /* Used by the 3d driver only at this point, for pageflipping:
204 */
205 unsigned int pfCurrentOffset;
195} drm_via_sarea_t; 206} drm_via_sarea_t;
196 207
197typedef struct _drm_via_cmdbuf_size { 208typedef struct _drm_via_cmdbuf_size {
@@ -212,6 +223,16 @@ typedef enum {
212 223
213#define VIA_IRQ_FLAGS_MASK 0xF0000000 224#define VIA_IRQ_FLAGS_MASK 0xF0000000
214 225
226enum drm_via_irqs {
227 drm_via_irq_hqv0 = 0,
228 drm_via_irq_hqv1,
229 drm_via_irq_dma0_dd,
230 drm_via_irq_dma0_td,
231 drm_via_irq_dma1_dd,
232 drm_via_irq_dma1_td,
233 drm_via_irq_num
234};
235
215struct drm_via_wait_irq_request { 236struct drm_via_wait_irq_request {
216 unsigned irq; 237 unsigned irq;
217 via_irq_seq_type_t type; 238 via_irq_seq_type_t type;
@@ -224,20 +245,25 @@ typedef union drm_via_irqwait {
224 struct drm_wait_vblank_reply reply; 245 struct drm_wait_vblank_reply reply;
225} drm_via_irqwait_t; 246} drm_via_irqwait_t;
226 247
227#ifdef __KERNEL__ 248typedef struct drm_via_blitsync {
228 249 uint32_t sync_handle;
229int via_fb_init(DRM_IOCTL_ARGS); 250 unsigned engine;
230int via_mem_alloc(DRM_IOCTL_ARGS); 251} drm_via_blitsync_t;
231int via_mem_free(DRM_IOCTL_ARGS); 252
232int via_agp_init(DRM_IOCTL_ARGS); 253typedef struct drm_via_dmablit {
233int via_map_init(DRM_IOCTL_ARGS); 254 uint32_t num_lines;
234int via_decoder_futex(DRM_IOCTL_ARGS); 255 uint32_t line_length;
235int via_dma_init(DRM_IOCTL_ARGS); 256
236int via_cmdbuffer(DRM_IOCTL_ARGS); 257 uint32_t fb_addr;
237int via_flush_ioctl(DRM_IOCTL_ARGS); 258 uint32_t fb_stride;
238int via_pci_cmdbuffer(DRM_IOCTL_ARGS); 259
239int via_cmdbuf_size(DRM_IOCTL_ARGS); 260 unsigned char *mem_addr;
240int via_wait_irq(DRM_IOCTL_ARGS); 261 uint32_t mem_stride;
262
263 int bounce_buffer;
264 int to_fb;
265
266 drm_via_blitsync_t sync;
267} drm_via_dmablit_t;
241 268
242#endif
243#endif /* _VIA_DRM_H_ */ 269#endif /* _VIA_DRM_H_ */
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c
index 016665e0c69f..3f012255d315 100644
--- a/drivers/char/drm/via_drv.c
+++ b/drivers/char/drm/via_drv.c
@@ -29,54 +29,21 @@
29 29
30#include "drm_pciids.h" 30#include "drm_pciids.h"
31 31
32static int postinit(struct drm_device *dev, unsigned long flags) 32static int dri_library_name(struct drm_device *dev, char *buf)
33{ 33{
34 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n", 34 return snprintf(buf, PAGE_SIZE, "unichrome");
35 DRIVER_NAME,
36 DRIVER_MAJOR,
37 DRIVER_MINOR,
38 DRIVER_PATCHLEVEL,
39 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
40 );
41 return 0;
42}
43
44static int version(drm_version_t * version)
45{
46 int len;
47
48 version->version_major = DRIVER_MAJOR;
49 version->version_minor = DRIVER_MINOR;
50 version->version_patchlevel = DRIVER_PATCHLEVEL;
51 DRM_COPY(version->name, DRIVER_NAME);
52 DRM_COPY(version->date, DRIVER_DATE);
53 DRM_COPY(version->desc, DRIVER_DESC);
54 return 0;
55} 35}
56 36
57static struct pci_device_id pciidlist[] = { 37static struct pci_device_id pciidlist[] = {
58 viadrv_PCI_IDS 38 viadrv_PCI_IDS
59}; 39};
60 40
61static drm_ioctl_desc_t ioctls[] = {
62 [DRM_IOCTL_NR(DRM_VIA_ALLOCMEM)] = {via_mem_alloc, 1, 0},
63 [DRM_IOCTL_NR(DRM_VIA_FREEMEM)] = {via_mem_free, 1, 0},
64 [DRM_IOCTL_NR(DRM_VIA_AGP_INIT)] = {via_agp_init, 1, 0},
65 [DRM_IOCTL_NR(DRM_VIA_FB_INIT)] = {via_fb_init, 1, 0},
66 [DRM_IOCTL_NR(DRM_VIA_MAP_INIT)] = {via_map_init, 1, 0},
67 [DRM_IOCTL_NR(DRM_VIA_DEC_FUTEX)] = {via_decoder_futex, 1, 0},
68 [DRM_IOCTL_NR(DRM_VIA_DMA_INIT)] = {via_dma_init, 1, 0},
69 [DRM_IOCTL_NR(DRM_VIA_CMDBUFFER)] = {via_cmdbuffer, 1, 0},
70 [DRM_IOCTL_NR(DRM_VIA_FLUSH)] = {via_flush_ioctl, 1, 0},
71 [DRM_IOCTL_NR(DRM_VIA_PCICMD)] = {via_pci_cmdbuffer, 1, 0},
72 [DRM_IOCTL_NR(DRM_VIA_CMDBUF_SIZE)] = {via_cmdbuf_size, 1, 0},
73 [DRM_IOCTL_NR(DRM_VIA_WAIT_IRQ)] = {via_wait_irq, 1, 0}
74};
75
76static struct drm_driver driver = { 41static struct drm_driver driver = {
77 .driver_features = 42 .driver_features =
78 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | 43 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ |
79 DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, 44 DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
45 .load = via_driver_load,
46 .unload = via_driver_unload,
80 .context_ctor = via_init_context, 47 .context_ctor = via_init_context,
81 .context_dtor = via_final_context, 48 .context_dtor = via_final_context,
82 .vblank_wait = via_driver_vblank_wait, 49 .vblank_wait = via_driver_vblank_wait,
@@ -85,13 +52,11 @@ static struct drm_driver driver = {
85 .irq_uninstall = via_driver_irq_uninstall, 52 .irq_uninstall = via_driver_irq_uninstall,
86 .irq_handler = via_driver_irq_handler, 53 .irq_handler = via_driver_irq_handler,
87 .dma_quiescent = via_driver_dma_quiescent, 54 .dma_quiescent = via_driver_dma_quiescent,
55 .dri_library_name = dri_library_name,
88 .reclaim_buffers = drm_core_reclaim_buffers, 56 .reclaim_buffers = drm_core_reclaim_buffers,
89 .get_map_ofs = drm_core_get_map_ofs, 57 .get_map_ofs = drm_core_get_map_ofs,
90 .get_reg_ofs = drm_core_get_reg_ofs, 58 .get_reg_ofs = drm_core_get_reg_ofs,
91 .postinit = postinit, 59 .ioctls = via_ioctls,
92 .version = version,
93 .ioctls = ioctls,
94 .num_ioctls = DRM_ARRAY_SIZE(ioctls),
95 .fops = { 60 .fops = {
96 .owner = THIS_MODULE, 61 .owner = THIS_MODULE,
97 .open = drm_open, 62 .open = drm_open,
@@ -100,15 +65,23 @@ static struct drm_driver driver = {
100 .mmap = drm_mmap, 65 .mmap = drm_mmap,
101 .poll = drm_poll, 66 .poll = drm_poll,
102 .fasync = drm_fasync, 67 .fasync = drm_fasync,
103 }, 68 },
104 .pci_driver = { 69 .pci_driver = {
105 .name = DRIVER_NAME, 70 .name = DRIVER_NAME,
106 .id_table = pciidlist, 71 .id_table = pciidlist,
107 } 72 },
73
74 .name = DRIVER_NAME,
75 .desc = DRIVER_DESC,
76 .date = DRIVER_DATE,
77 .major = DRIVER_MAJOR,
78 .minor = DRIVER_MINOR,
79 .patchlevel = DRIVER_PATCHLEVEL,
108}; 80};
109 81
110static int __init via_init(void) 82static int __init via_init(void)
111{ 83{
84 driver.num_ioctls = via_max_ioctl;
112 via_init_command_verifier(); 85 via_init_command_verifier();
113 return drm_init(&driver); 86 return drm_init(&driver);
114} 87}
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h
index 7d5daf43797e..aad4f99f5405 100644
--- a/drivers/char/drm/via_drv.h
+++ b/drivers/char/drm/via_drv.h
@@ -24,24 +24,26 @@
24#ifndef _VIA_DRV_H_ 24#ifndef _VIA_DRV_H_
25#define _VIA_DRV_H_ 25#define _VIA_DRV_H_
26 26
27#define DRIVER_AUTHOR "VIA" 27#define DRIVER_AUTHOR "Various"
28 28
29#define DRIVER_NAME "via" 29#define DRIVER_NAME "via"
30#define DRIVER_DESC "VIA Unichrome / Pro" 30#define DRIVER_DESC "VIA Unichrome / Pro"
31#define DRIVER_DATE "20050523" 31#define DRIVER_DATE "20051116"
32 32
33#define DRIVER_MAJOR 2 33#define DRIVER_MAJOR 2
34#define DRIVER_MINOR 6 34#define DRIVER_MINOR 7
35#define DRIVER_PATCHLEVEL 3 35#define DRIVER_PATCHLEVEL 4
36 36
37#include "via_verifier.h" 37#include "via_verifier.h"
38 38
39#include "via_dmablit.h"
40
39#define VIA_PCI_BUF_SIZE 60000 41#define VIA_PCI_BUF_SIZE 60000
40#define VIA_FIRE_BUF_SIZE 1024 42#define VIA_FIRE_BUF_SIZE 1024
41#define VIA_NUM_IRQS 2 43#define VIA_NUM_IRQS 4
42 44
43typedef struct drm_via_ring_buffer { 45typedef struct drm_via_ring_buffer {
44 drm_map_t map; 46 drm_local_map_t map;
45 char *virtual_start; 47 char *virtual_start;
46} drm_via_ring_buffer_t; 48} drm_via_ring_buffer_t;
47 49
@@ -56,9 +58,9 @@ typedef struct drm_via_irq {
56 58
57typedef struct drm_via_private { 59typedef struct drm_via_private {
58 drm_via_sarea_t *sarea_priv; 60 drm_via_sarea_t *sarea_priv;
59 drm_map_t *sarea; 61 drm_local_map_t *sarea;
60 drm_map_t *fb; 62 drm_local_map_t *fb;
61 drm_map_t *mmio; 63 drm_local_map_t *mmio;
62 unsigned long agpAddr; 64 unsigned long agpAddr;
63 wait_queue_head_t decoder_queue[VIA_NR_XVMC_LOCKS]; 65 wait_queue_head_t decoder_queue[VIA_NR_XVMC_LOCKS];
64 char *dma_ptr; 66 char *dma_ptr;
@@ -82,8 +84,15 @@ typedef struct drm_via_private {
82 maskarray_t *irq_masks; 84 maskarray_t *irq_masks;
83 uint32_t irq_enable_mask; 85 uint32_t irq_enable_mask;
84 uint32_t irq_pending_mask; 86 uint32_t irq_pending_mask;
87 int *irq_map;
88 drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES];
85} drm_via_private_t; 89} drm_via_private_t;
86 90
91enum via_family {
92 VIA_OTHER = 0,
93 VIA_PRO_GROUP_A,
94};
95
87/* VIA MMIO register access */ 96/* VIA MMIO register access */
88#define VIA_BASE ((dev_priv->mmio)) 97#define VIA_BASE ((dev_priv->mmio))
89 98
@@ -92,12 +101,31 @@ typedef struct drm_via_private {
92#define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg) 101#define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg)
93#define VIA_WRITE8(reg,val) DRM_WRITE8(VIA_BASE, reg, val) 102#define VIA_WRITE8(reg,val) DRM_WRITE8(VIA_BASE, reg, val)
94 103
104extern drm_ioctl_desc_t via_ioctls[];
105extern int via_max_ioctl;
106
107extern int via_fb_init(DRM_IOCTL_ARGS);
108extern int via_mem_alloc(DRM_IOCTL_ARGS);
109extern int via_mem_free(DRM_IOCTL_ARGS);
110extern int via_agp_init(DRM_IOCTL_ARGS);
111extern int via_map_init(DRM_IOCTL_ARGS);
112extern int via_decoder_futex(DRM_IOCTL_ARGS);
113extern int via_dma_init(DRM_IOCTL_ARGS);
114extern int via_cmdbuffer(DRM_IOCTL_ARGS);
115extern int via_flush_ioctl(DRM_IOCTL_ARGS);
116extern int via_pci_cmdbuffer(DRM_IOCTL_ARGS);
117extern int via_cmdbuf_size(DRM_IOCTL_ARGS);
118extern int via_wait_irq(DRM_IOCTL_ARGS);
119extern int via_dma_blit_sync( DRM_IOCTL_ARGS );
120extern int via_dma_blit( DRM_IOCTL_ARGS );
121
122extern int via_driver_load(drm_device_t *dev, unsigned long chipset);
123extern int via_driver_unload(drm_device_t *dev);
124
95extern int via_init_context(drm_device_t * dev, int context); 125extern int via_init_context(drm_device_t * dev, int context);
96extern int via_final_context(drm_device_t * dev, int context); 126extern int via_final_context(drm_device_t * dev, int context);
97 127
98extern int via_do_cleanup_map(drm_device_t * dev); 128extern int via_do_cleanup_map(drm_device_t * dev);
99extern int via_map_init(struct inode *inode, struct file *filp,
100 unsigned int cmd, unsigned long arg);
101extern int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence); 129extern int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence);
102 130
103extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); 131extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS);
@@ -111,8 +139,10 @@ extern int via_driver_dma_quiescent(drm_device_t * dev);
111extern void via_init_futex(drm_via_private_t * dev_priv); 139extern void via_init_futex(drm_via_private_t * dev_priv);
112extern void via_cleanup_futex(drm_via_private_t * dev_priv); 140extern void via_cleanup_futex(drm_via_private_t * dev_priv);
113extern void via_release_futex(drm_via_private_t * dev_priv, int context); 141extern void via_release_futex(drm_via_private_t * dev_priv, int context);
142extern int via_driver_irq_wait(drm_device_t * dev, unsigned int irq,
143 int force_sequence, unsigned int *sequence);
114 144
115extern int via_parse_command_stream(drm_device_t * dev, const uint32_t * buf, 145extern void via_dmablit_handler(drm_device_t *dev, int engine, int from_irq);
116 unsigned int size); 146extern void via_init_dmablit(drm_device_t *dev);
117 147
118#endif 148#endif
diff --git a/drivers/char/drm/via_ds.c b/drivers/char/drm/via_ds.c
index 5c71e089246c..9429736b3b96 100644
--- a/drivers/char/drm/via_ds.c
+++ b/drivers/char/drm/via_ds.c
@@ -22,14 +22,7 @@
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE. 23 * DEALINGS IN THE SOFTWARE.
24 */ 24 */
25#include <linux/module.h> 25#include "drmP.h"
26#include <linux/delay.h>
27#include <linux/errno.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30#include <linux/poll.h>
31#include <linux/pci.h>
32#include <asm/io.h>
33 26
34#include "via_ds.h" 27#include "via_ds.h"
35extern unsigned int VIA_DEBUG; 28extern unsigned int VIA_DEBUG;
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c
index d023add1929b..56d7e3daea12 100644
--- a/drivers/char/drm/via_irq.c
+++ b/drivers/char/drm/via_irq.c
@@ -50,6 +50,15 @@
50#define VIA_IRQ_HQV1_ENABLE (1 << 25) 50#define VIA_IRQ_HQV1_ENABLE (1 << 25)
51#define VIA_IRQ_HQV0_PENDING (1 << 9) 51#define VIA_IRQ_HQV0_PENDING (1 << 9)
52#define VIA_IRQ_HQV1_PENDING (1 << 10) 52#define VIA_IRQ_HQV1_PENDING (1 << 10)
53#define VIA_IRQ_DMA0_DD_ENABLE (1 << 20)
54#define VIA_IRQ_DMA0_TD_ENABLE (1 << 21)
55#define VIA_IRQ_DMA1_DD_ENABLE (1 << 22)
56#define VIA_IRQ_DMA1_TD_ENABLE (1 << 23)
57#define VIA_IRQ_DMA0_DD_PENDING (1 << 4)
58#define VIA_IRQ_DMA0_TD_PENDING (1 << 5)
59#define VIA_IRQ_DMA1_DD_PENDING (1 << 6)
60#define VIA_IRQ_DMA1_TD_PENDING (1 << 7)
61
53 62
54/* 63/*
55 * Device-specific IRQs go here. This type might need to be extended with 64 * Device-specific IRQs go here. This type might need to be extended with
@@ -61,13 +70,24 @@ static maskarray_t via_pro_group_a_irqs[] = {
61 {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, 70 {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010,
62 0x00000000}, 71 0x00000000},
63 {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, 72 {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010,
64 0x00000000} 73 0x00000000},
74 {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0,
75 VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
76 {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1,
77 VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
65}; 78};
66static int via_num_pro_group_a = 79static int via_num_pro_group_a =
67 sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t); 80 sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t);
81static int via_irqmap_pro_group_a[] = {0, 1, -1, 2, -1, 3};
68 82
69static maskarray_t via_unichrome_irqs[] = { }; 83static maskarray_t via_unichrome_irqs[] = {
84 {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0,
85 VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
86 {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1,
87 VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}
88};
70static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t); 89static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t);
90static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1};
71 91
72static unsigned time_diff(struct timeval *now, struct timeval *then) 92static unsigned time_diff(struct timeval *now, struct timeval *then)
73{ 93{
@@ -113,6 +133,11 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
113 atomic_inc(&cur_irq->irq_received); 133 atomic_inc(&cur_irq->irq_received);
114 DRM_WAKEUP(&cur_irq->irq_queue); 134 DRM_WAKEUP(&cur_irq->irq_queue);
115 handled = 1; 135 handled = 1;
136 if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) {
137 via_dmablit_handler(dev, 0, 1);
138 } else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i) {
139 via_dmablit_handler(dev, 1, 1);
140 }
116 } 141 }
117 cur_irq++; 142 cur_irq++;
118 } 143 }
@@ -165,7 +190,7 @@ int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
165 return ret; 190 return ret;
166} 191}
167 192
168static int 193int
169via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, 194via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
170 unsigned int *sequence) 195 unsigned int *sequence)
171{ 196{
@@ -174,6 +199,7 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
174 drm_via_irq_t *cur_irq = dev_priv->via_irqs; 199 drm_via_irq_t *cur_irq = dev_priv->via_irqs;
175 int ret = 0; 200 int ret = 0;
176 maskarray_t *masks = dev_priv->irq_masks; 201 maskarray_t *masks = dev_priv->irq_masks;
202 int real_irq;
177 203
178 DRM_DEBUG("%s\n", __FUNCTION__); 204 DRM_DEBUG("%s\n", __FUNCTION__);
179 205
@@ -182,15 +208,23 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
182 return DRM_ERR(EINVAL); 208 return DRM_ERR(EINVAL);
183 } 209 }
184 210
185 if (irq >= dev_priv->num_irqs) { 211 if (irq >= drm_via_irq_num) {
186 DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, 212 DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
187 irq); 213 irq);
188 return DRM_ERR(EINVAL); 214 return DRM_ERR(EINVAL);
189 } 215 }
190 216
191 cur_irq += irq; 217 real_irq = dev_priv->irq_map[irq];
218
219 if (real_irq < 0) {
220 DRM_ERROR("%s Video IRQ %d not available on this hardware.\n",
221 __FUNCTION__, irq);
222 return DRM_ERR(EINVAL);
223 }
224
225 cur_irq += real_irq;
192 226
193 if (masks[irq][2] && !force_sequence) { 227 if (masks[real_irq][2] && !force_sequence) {
194 DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ, 228 DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
195 ((VIA_READ(masks[irq][2]) & masks[irq][3]) == 229 ((VIA_READ(masks[irq][2]) & masks[irq][3]) ==
196 masks[irq][4])); 230 masks[irq][4]));
@@ -226,6 +260,8 @@ void via_driver_irq_preinstall(drm_device_t * dev)
226 via_pro_group_a_irqs : via_unichrome_irqs; 260 via_pro_group_a_irqs : via_unichrome_irqs;
227 dev_priv->num_irqs = (dev_priv->pro_group_a) ? 261 dev_priv->num_irqs = (dev_priv->pro_group_a) ?
228 via_num_pro_group_a : via_num_unichrome; 262 via_num_pro_group_a : via_num_unichrome;
263 dev_priv->irq_map = (dev_priv->pro_group_a) ?
264 via_irqmap_pro_group_a : via_irqmap_unichrome;
229 265
230 for (i = 0; i < dev_priv->num_irqs; ++i) { 266 for (i = 0; i < dev_priv->num_irqs; ++i) {
231 atomic_set(&cur_irq->irq_received, 0); 267 atomic_set(&cur_irq->irq_received, 0);
@@ -241,7 +277,7 @@ void via_driver_irq_preinstall(drm_device_t * dev)
241 277
242 dev_priv->last_vblank_valid = 0; 278 dev_priv->last_vblank_valid = 0;
243 279
244 // Clear VSync interrupt regs 280 /* Clear VSync interrupt regs */
245 status = VIA_READ(VIA_REG_INTERRUPT); 281 status = VIA_READ(VIA_REG_INTERRUPT);
246 VIA_WRITE(VIA_REG_INTERRUPT, status & 282 VIA_WRITE(VIA_REG_INTERRUPT, status &
247 ~(dev_priv->irq_enable_mask)); 283 ~(dev_priv->irq_enable_mask));
@@ -291,8 +327,7 @@ void via_driver_irq_uninstall(drm_device_t * dev)
291 327
292int via_wait_irq(DRM_IOCTL_ARGS) 328int via_wait_irq(DRM_IOCTL_ARGS)
293{ 329{
294 drm_file_t *priv = filp->private_data; 330 DRM_DEVICE;
295 drm_device_t *dev = priv->head->dev;
296 drm_via_irqwait_t __user *argp = (void __user *)data; 331 drm_via_irqwait_t __user *argp = (void __user *)data;
297 drm_via_irqwait_t irqwait; 332 drm_via_irqwait_t irqwait;
298 struct timeval now; 333 struct timeval now;
diff --git a/drivers/char/drm/via_map.c b/drivers/char/drm/via_map.c
index 6bd6ac52ad1b..c6a08e96285b 100644
--- a/drivers/char/drm/via_map.c
+++ b/drivers/char/drm/via_map.c
@@ -27,16 +27,10 @@
27 27
28static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init) 28static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init)
29{ 29{
30 drm_via_private_t *dev_priv; 30 drm_via_private_t *dev_priv = dev->dev_private;
31 31
32 DRM_DEBUG("%s\n", __FUNCTION__); 32 DRM_DEBUG("%s\n", __FUNCTION__);
33 33
34 dev_priv = drm_alloc(sizeof(drm_via_private_t), DRM_MEM_DRIVER);
35 if (dev_priv == NULL)
36 return -ENOMEM;
37
38 memset(dev_priv, 0, sizeof(drm_via_private_t));
39
40 DRM_GETSAREA(); 34 DRM_GETSAREA();
41 if (!dev_priv->sarea) { 35 if (!dev_priv->sarea) {
42 DRM_ERROR("could not find sarea!\n"); 36 DRM_ERROR("could not find sarea!\n");
@@ -67,7 +61,8 @@ static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init)
67 dev_priv->agpAddr = init->agpAddr; 61 dev_priv->agpAddr = init->agpAddr;
68 62
69 via_init_futex(dev_priv); 63 via_init_futex(dev_priv);
70 dev_priv->pro_group_a = (dev->pdev->device == 0x3118); 64
65 via_init_dmablit(dev);
71 66
72 dev->dev_private = (void *)dev_priv; 67 dev->dev_private = (void *)dev_priv;
73 return 0; 68 return 0;
@@ -75,15 +70,7 @@ static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init)
75 70
76int via_do_cleanup_map(drm_device_t * dev) 71int via_do_cleanup_map(drm_device_t * dev)
77{ 72{
78 if (dev->dev_private) { 73 via_dma_cleanup(dev);
79
80 drm_via_private_t *dev_priv = dev->dev_private;
81
82 via_dma_cleanup(dev);
83
84 drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
85 dev->dev_private = NULL;
86 }
87 74
88 return 0; 75 return 0;
89} 76}
@@ -107,3 +94,29 @@ int via_map_init(DRM_IOCTL_ARGS)
107 94
108 return -EINVAL; 95 return -EINVAL;
109} 96}
97
98int via_driver_load(drm_device_t *dev, unsigned long chipset)
99{
100 drm_via_private_t *dev_priv;
101
102 dev_priv = drm_calloc(1, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
103 if (dev_priv == NULL)
104 return DRM_ERR(ENOMEM);
105
106 dev->dev_private = (void *)dev_priv;
107
108 if (chipset == VIA_PRO_GROUP_A)
109 dev_priv->pro_group_a = 1;
110
111 return 0;
112}
113
114int via_driver_unload(drm_device_t *dev)
115{
116 drm_via_private_t *dev_priv = dev->dev_private;
117
118 drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
119
120 return 0;
121}
122
diff --git a/drivers/char/drm/via_mm.c b/drivers/char/drm/via_mm.c
index 3baddacdff26..33e0cb12e4c3 100644
--- a/drivers/char/drm/via_mm.c
+++ b/drivers/char/drm/via_mm.c
@@ -42,7 +42,7 @@ static int via_agp_free(drm_via_mem_t * mem);
42static int via_fb_alloc(drm_via_mem_t * mem); 42static int via_fb_alloc(drm_via_mem_t * mem);
43static int via_fb_free(drm_via_mem_t * mem); 43static int via_fb_free(drm_via_mem_t * mem);
44 44
45static int add_alloc_set(int context, int type, unsigned int val) 45static int add_alloc_set(int context, int type, unsigned long val)
46{ 46{
47 int i, retval = 0; 47 int i, retval = 0;
48 48
@@ -56,7 +56,7 @@ static int add_alloc_set(int context, int type, unsigned int val)
56 return retval; 56 return retval;
57} 57}
58 58
59static int del_alloc_set(int context, int type, unsigned int val) 59static int del_alloc_set(int context, int type, unsigned long val)
60{ 60{
61 int i, retval = 0; 61 int i, retval = 0;
62 62
@@ -199,13 +199,13 @@ int via_mem_alloc(DRM_IOCTL_ARGS)
199 sizeof(mem)); 199 sizeof(mem));
200 200
201 switch (mem.type) { 201 switch (mem.type) {
202 case VIDEO: 202 case VIA_MEM_VIDEO:
203 if (via_fb_alloc(&mem) < 0) 203 if (via_fb_alloc(&mem) < 0)
204 return -EFAULT; 204 return -EFAULT;
205 DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, 205 DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem,
206 sizeof(mem)); 206 sizeof(mem));
207 return 0; 207 return 0;
208 case AGP: 208 case VIA_MEM_AGP:
209 if (via_agp_alloc(&mem) < 0) 209 if (via_agp_alloc(&mem) < 0)
210 return -EFAULT; 210 return -EFAULT;
211 DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, 211 DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem,
@@ -232,7 +232,7 @@ static int via_fb_alloc(drm_via_mem_t * mem)
232 if (block) { 232 if (block) {
233 fb.offset = block->ofs; 233 fb.offset = block->ofs;
234 fb.free = (unsigned long)block; 234 fb.free = (unsigned long)block;
235 if (!add_alloc_set(fb.context, VIDEO, fb.free)) { 235 if (!add_alloc_set(fb.context, VIA_MEM_VIDEO, fb.free)) {
236 DRM_DEBUG("adding to allocation set fails\n"); 236 DRM_DEBUG("adding to allocation set fails\n");
237 via_mmFreeMem((PMemBlock) fb.free); 237 via_mmFreeMem((PMemBlock) fb.free);
238 retval = -1; 238 retval = -1;
@@ -269,7 +269,7 @@ static int via_agp_alloc(drm_via_mem_t * mem)
269 if (block) { 269 if (block) {
270 agp.offset = block->ofs; 270 agp.offset = block->ofs;
271 agp.free = (unsigned long)block; 271 agp.free = (unsigned long)block;
272 if (!add_alloc_set(agp.context, AGP, agp.free)) { 272 if (!add_alloc_set(agp.context, VIA_MEM_AGP, agp.free)) {
273 DRM_DEBUG("adding to allocation set fails\n"); 273 DRM_DEBUG("adding to allocation set fails\n");
274 via_mmFreeMem((PMemBlock) agp.free); 274 via_mmFreeMem((PMemBlock) agp.free);
275 retval = -1; 275 retval = -1;
@@ -297,11 +297,11 @@ int via_mem_free(DRM_IOCTL_ARGS)
297 297
298 switch (mem.type) { 298 switch (mem.type) {
299 299
300 case VIDEO: 300 case VIA_MEM_VIDEO:
301 if (via_fb_free(&mem) == 0) 301 if (via_fb_free(&mem) == 0)
302 return 0; 302 return 0;
303 break; 303 break;
304 case AGP: 304 case VIA_MEM_AGP:
305 if (via_agp_free(&mem) == 0) 305 if (via_agp_free(&mem) == 0)
306 return 0; 306 return 0;
307 break; 307 break;
@@ -329,7 +329,7 @@ static int via_fb_free(drm_via_mem_t * mem)
329 329
330 via_mmFreeMem((PMemBlock) fb.free); 330 via_mmFreeMem((PMemBlock) fb.free);
331 331
332 if (!del_alloc_set(fb.context, VIDEO, fb.free)) { 332 if (!del_alloc_set(fb.context, VIA_MEM_VIDEO, fb.free)) {
333 retval = -1; 333 retval = -1;
334 } 334 }
335 335
@@ -352,7 +352,7 @@ static int via_agp_free(drm_via_mem_t * mem)
352 352
353 via_mmFreeMem((PMemBlock) agp.free); 353 via_mmFreeMem((PMemBlock) agp.free);
354 354
355 if (!del_alloc_set(agp.context, AGP, agp.free)) { 355 if (!del_alloc_set(agp.context, VIA_MEM_AGP, agp.free)) {
356 retval = -1; 356 retval = -1;
357 } 357 }
358 358
diff --git a/drivers/char/drm/via_verifier.c b/drivers/char/drm/via_verifier.c
index 4ac495f297f7..70c897c88766 100644
--- a/drivers/char/drm/via_verifier.c
+++ b/drivers/char/drm/via_verifier.c
@@ -237,7 +237,7 @@ static hazard_t table3[256];
237static __inline__ int 237static __inline__ int
238eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words) 238eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words)
239{ 239{
240 if ((*buf - buf_end) >= num_words) { 240 if ((buf_end - *buf) >= num_words) {
241 *buf += num_words; 241 *buf += num_words;
242 return 0; 242 return 0;
243 } 243 }
@@ -249,14 +249,14 @@ eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words)
249 * Partially stolen from drm_memory.h 249 * Partially stolen from drm_memory.h
250 */ 250 */
251 251
252static __inline__ drm_map_t *via_drm_lookup_agp_map(drm_via_state_t * seq, 252static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t *seq,
253 unsigned long offset, 253 unsigned long offset,
254 unsigned long size, 254 unsigned long size,
255 drm_device_t * dev) 255 drm_device_t * dev)
256{ 256{
257 struct list_head *list; 257 struct list_head *list;
258 drm_map_list_t *r_list; 258 drm_map_list_t *r_list;
259 drm_map_t *map = seq->map_cache; 259 drm_local_map_t *map = seq->map_cache;
260 260
261 if (map && map->offset <= offset 261 if (map && map->offset <= offset
262 && (offset + size) <= (map->offset + map->size)) { 262 && (offset + size) <= (map->offset + map->size)) {
diff --git a/drivers/char/drm/via_verifier.h b/drivers/char/drm/via_verifier.h
index eb4eda344345..256590fcc22a 100644
--- a/drivers/char/drm/via_verifier.h
+++ b/drivers/char/drm/via_verifier.h
@@ -47,7 +47,7 @@ typedef struct {
47 int agp_texture; 47 int agp_texture;
48 int multitex; 48 int multitex;
49 drm_device_t *dev; 49 drm_device_t *dev;
50 drm_map_t *map_cache; 50 drm_local_map_t *map_cache;
51 uint32_t vertex_count; 51 uint32_t vertex_count;
52 int agp; 52 int agp;
53 const uint32_t *buf_start; 53 const uint32_t *buf_start;
@@ -55,5 +55,7 @@ typedef struct {
55 55
56extern int via_verify_command_stream(const uint32_t * buf, unsigned int size, 56extern int via_verify_command_stream(const uint32_t * buf, unsigned int size,
57 drm_device_t * dev, int agp); 57 drm_device_t * dev, int agp);
58extern int via_parse_command_stream(drm_device_t *dev, const uint32_t *buf,
59 unsigned int size);
58 60
59#endif 61#endif
diff --git a/drivers/char/drm/via_video.c b/drivers/char/drm/via_video.c
index 7fab9fbdf424..300ac61b09ed 100644
--- a/drivers/char/drm/via_video.c
+++ b/drivers/char/drm/via_video.c
@@ -50,8 +50,11 @@ void via_release_futex(drm_via_private_t * dev_priv, int context)
50 unsigned int i; 50 unsigned int i;
51 volatile int *lock; 51 volatile int *lock;
52 52
53 if (!dev_priv->sarea_priv)
54 return;
55
53 for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) { 56 for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
54 lock = (int *)XVMCLOCKPTR(dev_priv->sarea_priv, i); 57 lock = (volatile int *)XVMCLOCKPTR(dev_priv->sarea_priv, i);
55 if ((_DRM_LOCKING_CONTEXT(*lock) == context)) { 58 if ((_DRM_LOCKING_CONTEXT(*lock) == context)) {
56 if (_DRM_LOCK_IS_HELD(*lock) 59 if (_DRM_LOCK_IS_HELD(*lock)
57 && (*lock & _DRM_LOCK_CONT)) { 60 && (*lock & _DRM_LOCK_CONT)) {
@@ -79,7 +82,7 @@ int via_decoder_futex(DRM_IOCTL_ARGS)
79 if (fx.lock > VIA_NR_XVMC_LOCKS) 82 if (fx.lock > VIA_NR_XVMC_LOCKS)
80 return -EFAULT; 83 return -EFAULT;
81 84
82 lock = (int *)XVMCLOCKPTR(sAPriv, fx.lock); 85 lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx.lock);
83 86
84 switch (fx.func) { 87 switch (fx.func) {
85 case VIA_FUTEX_WAIT: 88 case VIA_FUTEX_WAIT:
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index 8693835cb2d5..e233cf280bc0 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -165,7 +165,7 @@ static int dsp56k_reset(void)
165 return 0; 165 return 0;
166} 166}
167 167
168static int dsp56k_upload(u_char *bin, int len) 168static int dsp56k_upload(u_char __user *bin, int len)
169{ 169{
170 int i; 170 int i;
171 u_char *p; 171 u_char *p;
@@ -199,7 +199,7 @@ static int dsp56k_upload(u_char *bin, int len)
199 return 0; 199 return 0;
200} 200}
201 201
202static ssize_t dsp56k_read(struct file *file, char *buf, size_t count, 202static ssize_t dsp56k_read(struct file *file, char __user *buf, size_t count,
203 loff_t *ppos) 203 loff_t *ppos)
204{ 204{
205 struct inode *inode = file->f_dentry->d_inode; 205 struct inode *inode = file->f_dentry->d_inode;
@@ -225,10 +225,10 @@ static ssize_t dsp56k_read(struct file *file, char *buf, size_t count,
225 } 225 }
226 case 2: /* 16 bit */ 226 case 2: /* 16 bit */
227 { 227 {
228 short *data; 228 short __user *data;
229 229
230 count /= 2; 230 count /= 2;
231 data = (short*) buf; 231 data = (short __user *) buf;
232 handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, 232 handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE,
233 put_user(dsp56k_host_interface.data.w[1], data+n++)); 233 put_user(dsp56k_host_interface.data.w[1], data+n++));
234 return 2*n; 234 return 2*n;
@@ -244,10 +244,10 @@ static ssize_t dsp56k_read(struct file *file, char *buf, size_t count,
244 } 244 }
245 case 4: /* 32 bit */ 245 case 4: /* 32 bit */
246 { 246 {
247 long *data; 247 long __user *data;
248 248
249 count /= 4; 249 count /= 4;
250 data = (long*) buf; 250 data = (long __user *) buf;
251 handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE, 251 handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_RECEIVE,
252 put_user(dsp56k_host_interface.data.l, data+n++)); 252 put_user(dsp56k_host_interface.data.l, data+n++));
253 return 4*n; 253 return 4*n;
@@ -262,7 +262,7 @@ static ssize_t dsp56k_read(struct file *file, char *buf, size_t count,
262 } 262 }
263} 263}
264 264
265static ssize_t dsp56k_write(struct file *file, const char *buf, size_t count, 265static ssize_t dsp56k_write(struct file *file, const char __user *buf, size_t count,
266 loff_t *ppos) 266 loff_t *ppos)
267{ 267{
268 struct inode *inode = file->f_dentry->d_inode; 268 struct inode *inode = file->f_dentry->d_inode;
@@ -287,10 +287,10 @@ static ssize_t dsp56k_write(struct file *file, const char *buf, size_t count,
287 } 287 }
288 case 2: /* 16 bit */ 288 case 2: /* 16 bit */
289 { 289 {
290 const short *data; 290 const short __user *data;
291 291
292 count /= 2; 292 count /= 2;
293 data = (const short *)buf; 293 data = (const short __user *)buf;
294 handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, 294 handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT,
295 get_user(dsp56k_host_interface.data.w[1], data+n++)); 295 get_user(dsp56k_host_interface.data.w[1], data+n++));
296 return 2*n; 296 return 2*n;
@@ -306,10 +306,10 @@ static ssize_t dsp56k_write(struct file *file, const char *buf, size_t count,
306 } 306 }
307 case 4: /* 32 bit */ 307 case 4: /* 32 bit */
308 { 308 {
309 const long *data; 309 const long __user *data;
310 310
311 count /= 4; 311 count /= 4;
312 data = (const long *)buf; 312 data = (const long __user *)buf;
313 handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT, 313 handshake(count, dsp56k.maxio, dsp56k.timeout, DSP56K_TRANSMIT,
314 get_user(dsp56k_host_interface.data.l, data+n++)); 314 get_user(dsp56k_host_interface.data.l, data+n++));
315 return 4*n; 315 return 4*n;
@@ -328,6 +328,7 @@ static int dsp56k_ioctl(struct inode *inode, struct file *file,
328 unsigned int cmd, unsigned long arg) 328 unsigned int cmd, unsigned long arg)
329{ 329{
330 int dev = iminor(inode) & 0x0f; 330 int dev = iminor(inode) & 0x0f;
331 void __user *argp = (void __user *)arg;
331 332
332 switch(dev) 333 switch(dev)
333 { 334 {
@@ -336,9 +337,9 @@ static int dsp56k_ioctl(struct inode *inode, struct file *file,
336 switch(cmd) { 337 switch(cmd) {
337 case DSP56K_UPLOAD: 338 case DSP56K_UPLOAD:
338 { 339 {
339 char *bin; 340 char __user *bin;
340 int r, len; 341 int r, len;
341 struct dsp56k_upload *binary = (struct dsp56k_upload *) arg; 342 struct dsp56k_upload __user *binary = argp;
342 343
343 if(get_user(len, &binary->len) < 0) 344 if(get_user(len, &binary->len) < 0)
344 return -EFAULT; 345 return -EFAULT;
@@ -372,7 +373,7 @@ static int dsp56k_ioctl(struct inode *inode, struct file *file,
372 case DSP56K_HOST_FLAGS: 373 case DSP56K_HOST_FLAGS:
373 { 374 {
374 int dir, out, status; 375 int dir, out, status;
375 struct dsp56k_host_flags *hf = (struct dsp56k_host_flags*) arg; 376 struct dsp56k_host_flags __user *hf = argp;
376 377
377 if(get_user(dir, &hf->dir) < 0) 378 if(get_user(dir, &hf->dir) < 0)
378 return -EFAULT; 379 return -EFAULT;
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index e469f641c728..dd5dc8fa490d 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -160,7 +160,6 @@ static void rs_wait_until_sent(struct tty_struct *, int);
160 * memory if large numbers of serial ports are open. 160 * memory if large numbers of serial ports are open.
161 */ 161 */
162static unsigned char *tmp_buf; 162static unsigned char *tmp_buf;
163static DECLARE_MUTEX(tmp_buf_sem);
164 163
165static inline int serial_paranoia_check(struct esp_struct *info, 164static inline int serial_paranoia_check(struct esp_struct *info,
166 char *name, const char *routine) 165 char *name, const char *routine)
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 204a7302a4a9..e38a5f0e07bb 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -34,7 +34,6 @@
34#define DEBUG 34#define DEBUG
35 35
36static char * tmp_buf; 36static char * tmp_buf;
37static DECLARE_MUTEX(tmp_buf_sem);
38 37
39static int gs_debug; 38static int gs_debug;
40 39
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 704c3c07f0ab..29c41f4418c0 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -534,7 +534,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf,
534 return virtr + wrote; 534 return virtr + wrote;
535} 535}
536 536
537#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) 537#if defined(CONFIG_ISA) || !defined(__mc68000__)
538static ssize_t read_port(struct file * file, char __user * buf, 538static ssize_t read_port(struct file * file, char __user * buf,
539 size_t count, loff_t *ppos) 539 size_t count, loff_t *ppos)
540{ 540{
@@ -795,7 +795,7 @@ static struct file_operations null_fops = {
795 .write = write_null, 795 .write = write_null,
796}; 796};
797 797
798#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) 798#if defined(CONFIG_ISA) || !defined(__mc68000__)
799static struct file_operations port_fops = { 799static struct file_operations port_fops = {
800 .llseek = memory_lseek, 800 .llseek = memory_lseek,
801 .read = read_port, 801 .read = read_port,
@@ -865,7 +865,7 @@ static int memory_open(struct inode * inode, struct file * filp)
865 case 3: 865 case 3:
866 filp->f_op = &null_fops; 866 filp->f_op = &null_fops;
867 break; 867 break;
868#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) 868#if defined(CONFIG_ISA) || !defined(__mc68000__)
869 case 4: 869 case 4:
870 filp->f_op = &port_fops; 870 filp->f_op = &port_fops;
871 break; 871 break;
@@ -912,7 +912,7 @@ static const struct {
912 {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, 912 {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
913 {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, 913 {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
914 {3, "null", S_IRUGO | S_IWUGO, &null_fops}, 914 {3, "null", S_IRUGO | S_IWUGO, &null_fops},
915#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) 915#if defined(CONFIG_ISA) || !defined(__mc68000__)
916 {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops}, 916 {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
917#endif 917#endif
918 {5, "zero", S_IRUGO | S_IWUGO, &zero_fops}, 918 {5, "zero", S_IRUGO | S_IWUGO, &zero_fops},
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 050e70ee5920..119e629656b7 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -82,7 +82,6 @@
82static struct riscom_board * IRQ_to_board[16]; 82static struct riscom_board * IRQ_to_board[16];
83static struct tty_driver *riscom_driver; 83static struct tty_driver *riscom_driver;
84static unsigned char * tmp_buf; 84static unsigned char * tmp_buf;
85static DECLARE_MUTEX(tmp_buf_sem);
86 85
87static unsigned long baud_table[] = { 86static unsigned long baud_table[] = {
88 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 87 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
diff --git a/drivers/char/scc.h b/drivers/char/scc.h
index 51810f72f1a9..93998f5baff5 100644
--- a/drivers/char/scc.h
+++ b/drivers/char/scc.h
@@ -399,7 +399,7 @@ struct scc_port {
399 __asm__ __volatile__ ( "tstb %0" : : "g" (*_scc_del) : "cc" );\ 399 __asm__ __volatile__ ( "tstb %0" : : "g" (*_scc_del) : "cc" );\
400 } while (0) 400 } while (0)
401 401
402extern unsigned char scc_shadow[2][16]; 402static unsigned char scc_shadow[2][16];
403 403
404/* The following functions should relax the somehow complicated 404/* The following functions should relax the somehow complicated
405 * register access of the SCC. _SCCwrite() stores all written values 405 * register access of the SCC. _SCCwrite() stores all written values
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index f36342ae8e7e..037c940ac71b 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -129,7 +129,6 @@ struct cyclades_port cy_port[] = {
129 * memory if large numbers of serial ports are open. 129 * memory if large numbers of serial ports are open.
130 */ 130 */
131static unsigned char *tmp_buf = 0; 131static unsigned char *tmp_buf = 0;
132DECLARE_MUTEX(tmp_buf_sem);
133 132
134/* 133/*
135 * This is used to look up the divisor speeds and the timeouts 134 * This is used to look up the divisor speeds and the timeouts
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 0a574bdbce36..5343e9fc6ab7 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -184,7 +184,6 @@ static int sx_poll = HZ;
184 184
185static struct tty_driver *specialix_driver; 185static struct tty_driver *specialix_driver;
186static unsigned char * tmp_buf; 186static unsigned char * tmp_buf;
187static DECLARE_MUTEX(tmp_buf_sem);
188 187
189static unsigned long baud_table[] = { 188static unsigned long baud_table[] = {
190 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 189 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
@@ -2556,8 +2555,6 @@ static int __init specialix_init_module(void)
2556 2555
2557 func_enter(); 2556 func_enter();
2558 2557
2559 init_MUTEX(&tmp_buf_sem); /* Init de the semaphore - pvdl */
2560
2561 if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) { 2558 if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2562 for(i = 0; i < SX_NBOARD; i++) { 2559 for(i = 0; i < SX_NBOARD; i++) {
2563 sx_board[i].base = iobase[i]; 2560 sx_board[i].base = iobase[i];
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 9f1b466c4f84..ede688a4e141 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -951,7 +951,6 @@ static void* mgsl_get_text_ptr(void)
951 * memory if large numbers of serial ports are open. 951 * memory if large numbers of serial ports are open.
952 */ 952 */
953static unsigned char *tmp_buf; 953static unsigned char *tmp_buf;
954static DECLARE_MUTEX(tmp_buf_sem);
955 954
956static inline int mgsl_paranoia_check(struct mgsl_struct *info, 955static inline int mgsl_paranoia_check(struct mgsl_struct *info,
957 char *name, const char *routine) 956 char *name, const char *routine)
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index faee5e7acaf7..4e5360388748 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -476,19 +476,19 @@ static struct port_info *get_port_data(struct tty_struct *tty)
476 */ 476 */
477static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp) 477static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp)
478{ 478{
479 struct HvLpEvent *hev = &viochar->event;
480
479 memset(viochar, 0, sizeof(struct viocharlpevent)); 481 memset(viochar, 0, sizeof(struct viocharlpevent));
480 482
481 viochar->event.xFlags.xValid = 1; 483 hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DEFERRED_ACK |
482 viochar->event.xFlags.xFunction = HvLpEvent_Function_Int; 484 HV_LP_EVENT_INT;
483 viochar->event.xFlags.xAckInd = HvLpEvent_AckInd_NoAck; 485 hev->xType = HvLpEvent_Type_VirtualIo;
484 viochar->event.xFlags.xAckType = HvLpEvent_AckType_DeferredAck; 486 hev->xSubtype = viomajorsubtype_chario | viochardata;
485 viochar->event.xType = HvLpEvent_Type_VirtualIo; 487 hev->xSourceLp = HvLpConfig_getLpIndex();
486 viochar->event.xSubtype = viomajorsubtype_chario | viochardata; 488 hev->xTargetLp = lp;
487 viochar->event.xSourceLp = HvLpConfig_getLpIndex(); 489 hev->xSizeMinus1 = sizeof(struct viocharlpevent);
488 viochar->event.xTargetLp = lp; 490 hev->xSourceInstanceId = viopath_sourceinst(lp);
489 viochar->event.xSizeMinus1 = sizeof(struct viocharlpevent); 491 hev->xTargetInstanceId = viopath_targetinst(lp);
490 viochar->event.xSourceInstanceId = viopath_sourceinst(lp);
491 viochar->event.xTargetInstanceId = viopath_targetinst(lp);
492} 492}
493 493
494/* 494/*
@@ -752,7 +752,7 @@ static void vioHandleOpenEvent(struct HvLpEvent *event)
752 struct port_info *pi; 752 struct port_info *pi;
753 int reject = 0; 753 int reject = 0;
754 754
755 if (event->xFlags.xFunction == HvLpEvent_Function_Ack) { 755 if (hvlpevent_is_ack(event)) {
756 if (port >= VTTY_PORTS) 756 if (port >= VTTY_PORTS)
757 return; 757 return;
758 758
@@ -788,7 +788,7 @@ static void vioHandleOpenEvent(struct HvLpEvent *event)
788 } 788 }
789 789
790 /* This had better require an ack, otherwise complain */ 790 /* This had better require an ack, otherwise complain */
791 if (event->xFlags.xAckInd != HvLpEvent_AckInd_DoAck) { 791 if (!hvlpevent_need_ack(event)) {
792 printk(VIOCONS_KERN_WARN "viocharopen without ack bit!\n"); 792 printk(VIOCONS_KERN_WARN "viocharopen without ack bit!\n");
793 return; 793 return;
794 } 794 }
@@ -856,7 +856,7 @@ static void vioHandleCloseEvent(struct HvLpEvent *event)
856 struct viocharlpevent *cevent = (struct viocharlpevent *)event; 856 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
857 u8 port = cevent->virtual_device; 857 u8 port = cevent->virtual_device;
858 858
859 if (event->xFlags.xFunction == HvLpEvent_Function_Int) { 859 if (hvlpevent_is_int(event)) {
860 if (port >= VTTY_PORTS) { 860 if (port >= VTTY_PORTS) {
861 printk(VIOCONS_KERN_WARN 861 printk(VIOCONS_KERN_WARN
862 "close message from invalid virtual device.\n"); 862 "close message from invalid virtual device.\n");
@@ -1056,8 +1056,7 @@ static void vioHandleCharEvent(struct HvLpEvent *event)
1056 vioHandleConfig(event); 1056 vioHandleConfig(event);
1057 break; 1057 break;
1058 default: 1058 default:
1059 if ((event->xFlags.xFunction == HvLpEvent_Function_Int) && 1059 if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) {
1060 (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
1061 event->xRc = HvLpEvent_Rc_InvalidSubtype; 1060 event->xRc = HvLpEvent_Rc_InvalidSubtype;
1062 HvCallEvent_ackLpEvent(event); 1061 HvCallEvent_ackLpEvent(event);
1063 } 1062 }
diff --git a/drivers/dio/dio-driver.c b/drivers/dio/dio-driver.c
index ffe6f44ac76f..ca8e69d2f64d 100644
--- a/drivers/dio/dio-driver.c
+++ b/drivers/dio/dio-driver.c
@@ -83,7 +83,6 @@ int dio_register_driver(struct dio_driver *drv)
83 /* initialize common driver fields */ 83 /* initialize common driver fields */
84 drv->driver.name = drv->name; 84 drv->driver.name = drv->name;
85 drv->driver.bus = &dio_bus_type; 85 drv->driver.bus = &dio_bus_type;
86 drv->driver.probe = dio_device_probe;
87 86
88 /* register with core */ 87 /* register with core */
89 count = driver_register(&drv->driver); 88 count = driver_register(&drv->driver);
@@ -145,7 +144,8 @@ static int dio_bus_match(struct device *dev, struct device_driver *drv)
145 144
146struct bus_type dio_bus_type = { 145struct bus_type dio_bus_type = {
147 .name = "dio", 146 .name = "dio",
148 .match = dio_bus_match 147 .match = dio_bus_match,
148 .probe = dio_device_probe,
149}; 149};
150 150
151 151
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 70f7ab829d36..86e2234faf80 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -899,6 +899,12 @@ static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num
899 struct pxa_i2c *i2c = adap->algo_data; 899 struct pxa_i2c *i2c = adap->algo_data;
900 int ret, i; 900 int ret, i;
901 901
902 /* If the I2C controller is disabled we need to reset it (probably due
903 to a suspend/resume destroying state). We do this here as we can then
904 avoid worrying about resuming the controller before its users. */
905 if (!(ICR & ICR_IUE))
906 i2c_pxa_reset(i2c);
907
902 for (i = adap->retries; i >= 0; i--) { 908 for (i = adap->retries; i >= 0; i--) {
903 ret = i2c_pxa_do_xfer(i2c, msgs, num); 909 ret = i2c_pxa_do_xfer(i2c, msgs, num);
904 if (ret != I2C_RETRY) 910 if (ret != I2C_RETRY)
@@ -939,7 +945,9 @@ static struct pxa_i2c i2c_pxa = {
939static int i2c_pxa_probe(struct platform_device *dev) 945static int i2c_pxa_probe(struct platform_device *dev)
940{ 946{
941 struct pxa_i2c *i2c = &i2c_pxa; 947 struct pxa_i2c *i2c = &i2c_pxa;
948#ifdef CONFIG_I2C_PXA_SLAVE
942 struct i2c_pxa_platform_data *plat = dev->dev.platform_data; 949 struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
950#endif
943 int ret; 951 int ret;
944 952
945#ifdef CONFIG_PXA27x 953#ifdef CONFIG_PXA27x
@@ -1024,5 +1032,7 @@ static void i2c_adap_pxa_exit(void)
1024 return platform_driver_unregister(&i2c_pxa_driver); 1032 return platform_driver_unregister(&i2c_pxa_driver);
1025} 1033}
1026 1034
1035MODULE_LICENSE("GPL");
1036
1027module_init(i2c_adap_pxa_init); 1037module_init(i2c_adap_pxa_init);
1028module_exit(i2c_adap_pxa_exit); 1038module_exit(i2c_adap_pxa_exit);
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 52b77477df57..0ce58b506046 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -63,13 +63,6 @@ static int i2c_bus_resume(struct device * dev)
63 return rc; 63 return rc;
64} 64}
65 65
66struct bus_type i2c_bus_type = {
67 .name = "i2c",
68 .match = i2c_device_match,
69 .suspend = i2c_bus_suspend,
70 .resume = i2c_bus_resume,
71};
72
73static int i2c_device_probe(struct device *dev) 66static int i2c_device_probe(struct device *dev)
74{ 67{
75 return -ENODEV; 68 return -ENODEV;
@@ -80,6 +73,15 @@ static int i2c_device_remove(struct device *dev)
80 return 0; 73 return 0;
81} 74}
82 75
76struct bus_type i2c_bus_type = {
77 .name = "i2c",
78 .match = i2c_device_match,
79 .probe = i2c_device_probe,
80 .remove = i2c_device_remove,
81 .suspend = i2c_bus_suspend,
82 .resume = i2c_bus_resume,
83};
84
83void i2c_adapter_dev_release(struct device *dev) 85void i2c_adapter_dev_release(struct device *dev)
84{ 86{
85 struct i2c_adapter *adap = dev_to_i2c_adapter(dev); 87 struct i2c_adapter *adap = dev_to_i2c_adapter(dev);
@@ -90,8 +92,6 @@ struct device_driver i2c_adapter_driver = {
90 .owner = THIS_MODULE, 92 .owner = THIS_MODULE,
91 .name = "i2c_adapter", 93 .name = "i2c_adapter",
92 .bus = &i2c_bus_type, 94 .bus = &i2c_bus_type,
93 .probe = i2c_device_probe,
94 .remove = i2c_device_remove,
95}; 95};
96 96
97static void i2c_adapter_class_dev_release(struct class_device *dev) 97static void i2c_adapter_class_dev_release(struct class_device *dev)
@@ -294,8 +294,6 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
294 /* add the driver to the list of i2c drivers in the driver core */ 294 /* add the driver to the list of i2c drivers in the driver core */
295 driver->driver.owner = owner; 295 driver->driver.owner = owner;
296 driver->driver.bus = &i2c_bus_type; 296 driver->driver.bus = &i2c_bus_type;
297 driver->driver.probe = i2c_device_probe;
298 driver->driver.remove = i2c_device_remove;
299 297
300 res = driver_register(&driver->driver); 298 res = driver_register(&driver->driver);
301 if (res) 299 if (res)
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 9b2ebd219ad0..ef09a7ef2396 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -3256,9 +3256,8 @@ sector_t ide_cdrom_capacity (ide_drive_t *drive)
3256} 3256}
3257#endif 3257#endif
3258 3258
3259static int ide_cd_remove(struct device *dev) 3259static void ide_cd_remove(ide_drive_t *drive)
3260{ 3260{
3261 ide_drive_t *drive = to_ide_device(dev);
3262 struct cdrom_info *info = drive->driver_data; 3261 struct cdrom_info *info = drive->driver_data;
3263 3262
3264 ide_unregister_subdriver(drive, info->driver); 3263 ide_unregister_subdriver(drive, info->driver);
@@ -3266,8 +3265,6 @@ static int ide_cd_remove(struct device *dev)
3266 del_gendisk(info->disk); 3265 del_gendisk(info->disk);
3267 3266
3268 ide_cd_put(info); 3267 ide_cd_put(info);
3269
3270 return 0;
3271} 3268}
3272 3269
3273static void ide_cd_release(struct kref *kref) 3270static void ide_cd_release(struct kref *kref)
@@ -3291,7 +3288,7 @@ static void ide_cd_release(struct kref *kref)
3291 kfree(info); 3288 kfree(info);
3292} 3289}
3293 3290
3294static int ide_cd_probe(struct device *); 3291static int ide_cd_probe(ide_drive_t *);
3295 3292
3296#ifdef CONFIG_PROC_FS 3293#ifdef CONFIG_PROC_FS
3297static int proc_idecd_read_capacity 3294static int proc_idecd_read_capacity
@@ -3317,9 +3314,9 @@ static ide_driver_t ide_cdrom_driver = {
3317 .owner = THIS_MODULE, 3314 .owner = THIS_MODULE,
3318 .name = "ide-cdrom", 3315 .name = "ide-cdrom",
3319 .bus = &ide_bus_type, 3316 .bus = &ide_bus_type,
3320 .probe = ide_cd_probe,
3321 .remove = ide_cd_remove,
3322 }, 3317 },
3318 .probe = ide_cd_probe,
3319 .remove = ide_cd_remove,
3323 .version = IDECD_VERSION, 3320 .version = IDECD_VERSION,
3324 .media = ide_cdrom, 3321 .media = ide_cdrom,
3325 .supports_dsc_overlap = 1, 3322 .supports_dsc_overlap = 1,
@@ -3413,9 +3410,8 @@ static char *ignore = NULL;
3413module_param(ignore, charp, 0400); 3410module_param(ignore, charp, 0400);
3414MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); 3411MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
3415 3412
3416static int ide_cd_probe(struct device *dev) 3413static int ide_cd_probe(ide_drive_t *drive)
3417{ 3414{
3418 ide_drive_t *drive = to_ide_device(dev);
3419 struct cdrom_info *info; 3415 struct cdrom_info *info;
3420 struct gendisk *g; 3416 struct gendisk *g;
3421 struct request_sense sense; 3417 struct request_sense sense;
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index cab362ea0336..245b508208df 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -997,9 +997,8 @@ static void ide_cacheflush_p(ide_drive_t *drive)
997 printk(KERN_INFO "%s: wcache flush failed!\n", drive->name); 997 printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
998} 998}
999 999
1000static int ide_disk_remove(struct device *dev) 1000static void ide_disk_remove(ide_drive_t *drive)
1001{ 1001{
1002 ide_drive_t *drive = to_ide_device(dev);
1003 struct ide_disk_obj *idkp = drive->driver_data; 1002 struct ide_disk_obj *idkp = drive->driver_data;
1004 struct gendisk *g = idkp->disk; 1003 struct gendisk *g = idkp->disk;
1005 1004
@@ -1010,8 +1009,6 @@ static int ide_disk_remove(struct device *dev)
1010 ide_cacheflush_p(drive); 1009 ide_cacheflush_p(drive);
1011 1010
1012 ide_disk_put(idkp); 1011 ide_disk_put(idkp);
1013
1014 return 0;
1015} 1012}
1016 1013
1017static void ide_disk_release(struct kref *kref) 1014static void ide_disk_release(struct kref *kref)
@@ -1027,12 +1024,10 @@ static void ide_disk_release(struct kref *kref)
1027 kfree(idkp); 1024 kfree(idkp);
1028} 1025}
1029 1026
1030static int ide_disk_probe(struct device *dev); 1027static int ide_disk_probe(ide_drive_t *drive);
1031 1028
1032static void ide_device_shutdown(struct device *dev) 1029static void ide_device_shutdown(ide_drive_t *drive)
1033{ 1030{
1034 ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
1035
1036#ifdef CONFIG_ALPHA 1031#ifdef CONFIG_ALPHA
1037 /* On Alpha, halt(8) doesn't actually turn the machine off, 1032 /* On Alpha, halt(8) doesn't actually turn the machine off,
1038 it puts you into the sort of firmware monitor. Typically, 1033 it puts you into the sort of firmware monitor. Typically,
@@ -1054,7 +1049,7 @@ static void ide_device_shutdown(struct device *dev)
1054 } 1049 }
1055 1050
1056 printk("Shutdown: %s\n", drive->name); 1051 printk("Shutdown: %s\n", drive->name);
1057 dev->bus->suspend(dev, PMSG_SUSPEND); 1052 drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
1058} 1053}
1059 1054
1060static ide_driver_t idedisk_driver = { 1055static ide_driver_t idedisk_driver = {
@@ -1062,10 +1057,10 @@ static ide_driver_t idedisk_driver = {
1062 .owner = THIS_MODULE, 1057 .owner = THIS_MODULE,
1063 .name = "ide-disk", 1058 .name = "ide-disk",
1064 .bus = &ide_bus_type, 1059 .bus = &ide_bus_type,
1065 .probe = ide_disk_probe,
1066 .remove = ide_disk_remove,
1067 .shutdown = ide_device_shutdown,
1068 }, 1060 },
1061 .probe = ide_disk_probe,
1062 .remove = ide_disk_remove,
1063 .shutdown = ide_device_shutdown,
1069 .version = IDEDISK_VERSION, 1064 .version = IDEDISK_VERSION,
1070 .media = ide_disk, 1065 .media = ide_disk,
1071 .supports_dsc_overlap = 0, 1066 .supports_dsc_overlap = 0,
@@ -1182,9 +1177,8 @@ static struct block_device_operations idedisk_ops = {
1182 1177
1183MODULE_DESCRIPTION("ATA DISK Driver"); 1178MODULE_DESCRIPTION("ATA DISK Driver");
1184 1179
1185static int ide_disk_probe(struct device *dev) 1180static int ide_disk_probe(ide_drive_t *drive)
1186{ 1181{
1187 ide_drive_t *drive = to_ide_device(dev);
1188 struct ide_disk_obj *idkp; 1182 struct ide_disk_obj *idkp;
1189 struct gendisk *g; 1183 struct gendisk *g;
1190 1184
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 5945f551aaaa..1f8db9ac05d1 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -1871,9 +1871,8 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
1871 idefloppy_add_settings(drive); 1871 idefloppy_add_settings(drive);
1872} 1872}
1873 1873
1874static int ide_floppy_remove(struct device *dev) 1874static void ide_floppy_remove(ide_drive_t *drive)
1875{ 1875{
1876 ide_drive_t *drive = to_ide_device(dev);
1877 idefloppy_floppy_t *floppy = drive->driver_data; 1876 idefloppy_floppy_t *floppy = drive->driver_data;
1878 struct gendisk *g = floppy->disk; 1877 struct gendisk *g = floppy->disk;
1879 1878
@@ -1882,8 +1881,6 @@ static int ide_floppy_remove(struct device *dev)
1882 del_gendisk(g); 1881 del_gendisk(g);
1883 1882
1884 ide_floppy_put(floppy); 1883 ide_floppy_put(floppy);
1885
1886 return 0;
1887} 1884}
1888 1885
1889static void ide_floppy_release(struct kref *kref) 1886static void ide_floppy_release(struct kref *kref)
@@ -1922,16 +1919,16 @@ static ide_proc_entry_t idefloppy_proc[] = {
1922 1919
1923#endif /* CONFIG_PROC_FS */ 1920#endif /* CONFIG_PROC_FS */
1924 1921
1925static int ide_floppy_probe(struct device *); 1922static int ide_floppy_probe(ide_drive_t *);
1926 1923
1927static ide_driver_t idefloppy_driver = { 1924static ide_driver_t idefloppy_driver = {
1928 .gen_driver = { 1925 .gen_driver = {
1929 .owner = THIS_MODULE, 1926 .owner = THIS_MODULE,
1930 .name = "ide-floppy", 1927 .name = "ide-floppy",
1931 .bus = &ide_bus_type, 1928 .bus = &ide_bus_type,
1932 .probe = ide_floppy_probe,
1933 .remove = ide_floppy_remove,
1934 }, 1929 },
1930 .probe = ide_floppy_probe,
1931 .remove = ide_floppy_remove,
1935 .version = IDEFLOPPY_VERSION, 1932 .version = IDEFLOPPY_VERSION,
1936 .media = ide_floppy, 1933 .media = ide_floppy,
1937 .supports_dsc_overlap = 0, 1934 .supports_dsc_overlap = 0,
@@ -2136,9 +2133,8 @@ static struct block_device_operations idefloppy_ops = {
2136 .revalidate_disk= idefloppy_revalidate_disk 2133 .revalidate_disk= idefloppy_revalidate_disk
2137}; 2134};
2138 2135
2139static int ide_floppy_probe(struct device *dev) 2136static int ide_floppy_probe(ide_drive_t *drive)
2140{ 2137{
2141 ide_drive_t *drive = to_ide_device(dev);
2142 idefloppy_floppy_t *floppy; 2138 idefloppy_floppy_t *floppy;
2143 struct gendisk *g; 2139 struct gendisk *g;
2144 2140
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index bcbaeb50bb93..8d50df4526a4 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -55,22 +55,9 @@
55#include <asm/io.h> 55#include <asm/io.h>
56#include <asm/bitops.h> 56#include <asm/bitops.h>
57 57
58void ide_softirq_done(struct request *rq)
59{
60 request_queue_t *q = rq->q;
61
62 add_disk_randomness(rq->rq_disk);
63 end_that_request_chunk(rq, 1, rq->data_len);
64
65 spin_lock_irq(q->queue_lock);
66 end_that_request_last(rq, 1);
67 spin_unlock_irq(q->queue_lock);
68}
69
70int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, 58int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate,
71 int nr_sectors) 59 int nr_sectors)
72{ 60{
73 unsigned int nbytes;
74 int ret = 1; 61 int ret = 1;
75 62
76 BUG_ON(!(rq->flags & REQ_STARTED)); 63 BUG_ON(!(rq->flags & REQ_STARTED));
@@ -94,27 +81,12 @@ int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate,
94 HWGROUP(drive)->hwif->ide_dma_on(drive); 81 HWGROUP(drive)->hwif->ide_dma_on(drive);
95 } 82 }
96 83
97 /* 84 if (!end_that_request_first(rq, uptodate, nr_sectors)) {
98 * For partial completions (or non fs/pc requests), use the regular 85 add_disk_randomness(rq->rq_disk);
99 * direct completion path. Same thing for requests that failed, to
100 * preserve the ->errors value we use the normal completion path
101 * for those
102 */
103 nbytes = nr_sectors << 9;
104 if (!rq->errors && rq_all_done(rq, nbytes)) {
105 rq->data_len = nbytes;
106 blkdev_dequeue_request(rq); 86 blkdev_dequeue_request(rq);
107 HWGROUP(drive)->rq = NULL; 87 HWGROUP(drive)->rq = NULL;
108 blk_complete_request(rq); 88 end_that_request_last(rq, uptodate);
109 ret = 0; 89 ret = 0;
110 } else {
111 if (!end_that_request_first(rq, uptodate, nr_sectors)) {
112 add_disk_randomness(rq->rq_disk);
113 blkdev_dequeue_request(rq);
114 HWGROUP(drive)->rq = NULL;
115 end_that_request_last(rq, uptodate);
116 ret = 0;
117 }
118 } 90 }
119 91
120 return ret; 92 return ret;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 7cb2d86601db..e7425546b4b1 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1011,8 +1011,6 @@ static int ide_init_queue(ide_drive_t *drive)
1011 blk_queue_max_hw_segments(q, max_sg_entries); 1011 blk_queue_max_hw_segments(q, max_sg_entries);
1012 blk_queue_max_phys_segments(q, max_sg_entries); 1012 blk_queue_max_phys_segments(q, max_sg_entries);
1013 1013
1014 blk_queue_softirq_done(q, ide_softirq_done);
1015
1016 /* assign drive queue */ 1014 /* assign drive queue */
1017 drive->queue = q; 1015 drive->queue = q;
1018 1016
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index fab9b2b02504..0101d0def7c5 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -4682,9 +4682,8 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
4682 idetape_add_settings(drive); 4682 idetape_add_settings(drive);
4683} 4683}
4684 4684
4685static int ide_tape_remove(struct device *dev) 4685static void ide_tape_remove(ide_drive_t *drive)
4686{ 4686{
4687 ide_drive_t *drive = to_ide_device(dev);
4688 idetape_tape_t *tape = drive->driver_data; 4687 idetape_tape_t *tape = drive->driver_data;
4689 4688
4690 ide_unregister_subdriver(drive, tape->driver); 4689 ide_unregister_subdriver(drive, tape->driver);
@@ -4692,8 +4691,6 @@ static int ide_tape_remove(struct device *dev)
4692 ide_unregister_region(tape->disk); 4691 ide_unregister_region(tape->disk);
4693 4692
4694 ide_tape_put(tape); 4693 ide_tape_put(tape);
4695
4696 return 0;
4697} 4694}
4698 4695
4699static void ide_tape_release(struct kref *kref) 4696static void ide_tape_release(struct kref *kref)
@@ -4745,16 +4742,16 @@ static ide_proc_entry_t idetape_proc[] = {
4745 4742
4746#endif 4743#endif
4747 4744
4748static int ide_tape_probe(struct device *); 4745static int ide_tape_probe(ide_drive_t *);
4749 4746
4750static ide_driver_t idetape_driver = { 4747static ide_driver_t idetape_driver = {
4751 .gen_driver = { 4748 .gen_driver = {
4752 .owner = THIS_MODULE, 4749 .owner = THIS_MODULE,
4753 .name = "ide-tape", 4750 .name = "ide-tape",
4754 .bus = &ide_bus_type, 4751 .bus = &ide_bus_type,
4755 .probe = ide_tape_probe,
4756 .remove = ide_tape_remove,
4757 }, 4752 },
4753 .probe = ide_tape_probe,
4754 .remove = ide_tape_remove,
4758 .version = IDETAPE_VERSION, 4755 .version = IDETAPE_VERSION,
4759 .media = ide_tape, 4756 .media = ide_tape,
4760 .supports_dsc_overlap = 1, 4757 .supports_dsc_overlap = 1,
@@ -4825,9 +4822,8 @@ static struct block_device_operations idetape_block_ops = {
4825 .ioctl = idetape_ioctl, 4822 .ioctl = idetape_ioctl,
4826}; 4823};
4827 4824
4828static int ide_tape_probe(struct device *dev) 4825static int ide_tape_probe(ide_drive_t *drive)
4829{ 4826{
4830 ide_drive_t *drive = to_ide_device(dev);
4831 idetape_tape_t *tape; 4827 idetape_tape_t *tape;
4832 struct gendisk *g; 4828 struct gendisk *g;
4833 int minor; 4829 int minor;
@@ -4883,9 +4879,9 @@ static int ide_tape_probe(struct device *dev)
4883 idetape_setup(drive, tape, minor); 4879 idetape_setup(drive, tape, minor);
4884 4880
4885 class_device_create(idetape_sysfs_class, NULL, 4881 class_device_create(idetape_sysfs_class, NULL,
4886 MKDEV(IDETAPE_MAJOR, minor), dev, "%s", tape->name); 4882 MKDEV(IDETAPE_MAJOR, minor), &drive->gendev, "%s", tape->name);
4887 class_device_create(idetape_sysfs_class, NULL, 4883 class_device_create(idetape_sysfs_class, NULL,
4888 MKDEV(IDETAPE_MAJOR, minor + 128), dev, "n%s", tape->name); 4884 MKDEV(IDETAPE_MAJOR, minor + 128), &drive->gendev, "n%s", tape->name);
4889 4885
4890 devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor), 4886 devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor),
4891 S_IFCHR | S_IRUGO | S_IWUGO, 4887 S_IFCHR | S_IRUGO | S_IWUGO,
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index ec5a4cb173b0..afeb02bbb722 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1949,10 +1949,41 @@ static int ide_uevent(struct device *dev, char **envp, int num_envp,
1949 return 0; 1949 return 0;
1950} 1950}
1951 1951
1952static int generic_ide_probe(struct device *dev)
1953{
1954 ide_drive_t *drive = to_ide_device(dev);
1955 ide_driver_t *drv = to_ide_driver(dev->driver);
1956
1957 return drv->probe ? drv->probe(drive) : -ENODEV;
1958}
1959
1960static int generic_ide_remove(struct device *dev)
1961{
1962 ide_drive_t *drive = to_ide_device(dev);
1963 ide_driver_t *drv = to_ide_driver(dev->driver);
1964
1965 if (drv->remove)
1966 drv->remove(drive);
1967
1968 return 0;
1969}
1970
1971static void generic_ide_shutdown(struct device *dev)
1972{
1973 ide_drive_t *drive = to_ide_device(dev);
1974 ide_driver_t *drv = to_ide_driver(dev->driver);
1975
1976 if (dev->driver && drv->shutdown)
1977 drv->shutdown(drive);
1978}
1979
1952struct bus_type ide_bus_type = { 1980struct bus_type ide_bus_type = {
1953 .name = "ide", 1981 .name = "ide",
1954 .match = ide_bus_match, 1982 .match = ide_bus_match,
1955 .uevent = ide_uevent, 1983 .uevent = ide_uevent,
1984 .probe = generic_ide_probe,
1985 .remove = generic_ide_remove,
1986 .shutdown = generic_ide_shutdown,
1956 .dev_attrs = ide_dev_attrs, 1987 .dev_attrs = ide_dev_attrs,
1957 .suspend = generic_ide_suspend, 1988 .suspend = generic_ide_suspend,
1958 .resume = generic_ide_resume, 1989 .resume = generic_ide_resume,
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 3a611fe5497e..c06b18102b6a 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -3163,22 +3163,6 @@ int ib_cm_init_qp_attr(struct ib_cm_id *cm_id,
3163} 3163}
3164EXPORT_SYMBOL(ib_cm_init_qp_attr); 3164EXPORT_SYMBOL(ib_cm_init_qp_attr);
3165 3165
3166static __be64 cm_get_ca_guid(struct ib_device *device)
3167{
3168 struct ib_device_attr *device_attr;
3169 __be64 guid;
3170 int ret;
3171
3172 device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL);
3173 if (!device_attr)
3174 return 0;
3175
3176 ret = ib_query_device(device, device_attr);
3177 guid = ret ? 0 : device_attr->node_guid;
3178 kfree(device_attr);
3179 return guid;
3180}
3181
3182static void cm_add_one(struct ib_device *device) 3166static void cm_add_one(struct ib_device *device)
3183{ 3167{
3184 struct cm_device *cm_dev; 3168 struct cm_device *cm_dev;
@@ -3200,9 +3184,7 @@ static void cm_add_one(struct ib_device *device)
3200 return; 3184 return;
3201 3185
3202 cm_dev->device = device; 3186 cm_dev->device = device;
3203 cm_dev->ca_guid = cm_get_ca_guid(device); 3187 cm_dev->ca_guid = device->node_guid;
3204 if (!cm_dev->ca_guid)
3205 goto error1;
3206 3188
3207 set_bit(IB_MGMT_METHOD_SEND, reg_req.method_mask); 3189 set_bit(IB_MGMT_METHOD_SEND, reg_req.method_mask);
3208 for (i = 1; i <= device->phys_port_cnt; i++) { 3190 for (i = 1; i <= device->phys_port_cnt; i++) {
@@ -3217,11 +3199,11 @@ static void cm_add_one(struct ib_device *device)
3217 cm_recv_handler, 3199 cm_recv_handler,
3218 port); 3200 port);
3219 if (IS_ERR(port->mad_agent)) 3201 if (IS_ERR(port->mad_agent))
3220 goto error2; 3202 goto error1;
3221 3203
3222 ret = ib_modify_port(device, i, 0, &port_modify); 3204 ret = ib_modify_port(device, i, 0, &port_modify);
3223 if (ret) 3205 if (ret)
3224 goto error3; 3206 goto error2;
3225 } 3207 }
3226 ib_set_client_data(device, &cm_client, cm_dev); 3208 ib_set_client_data(device, &cm_client, cm_dev);
3227 3209
@@ -3230,9 +3212,9 @@ static void cm_add_one(struct ib_device *device)
3230 write_unlock_irqrestore(&cm.device_lock, flags); 3212 write_unlock_irqrestore(&cm.device_lock, flags);
3231 return; 3213 return;
3232 3214
3233error3:
3234 ib_unregister_mad_agent(port->mad_agent);
3235error2: 3215error2:
3216 ib_unregister_mad_agent(port->mad_agent);
3217error1:
3236 port_modify.set_port_cap_mask = 0; 3218 port_modify.set_port_cap_mask = 0;
3237 port_modify.clr_port_cap_mask = IB_PORT_CM_SUP; 3219 port_modify.clr_port_cap_mask = IB_PORT_CM_SUP;
3238 while (--i) { 3220 while (--i) {
@@ -3240,7 +3222,6 @@ error2:
3240 ib_modify_port(device, port->port_num, 0, &port_modify); 3222 ib_modify_port(device, port->port_num, 0, &port_modify);
3241 ib_unregister_mad_agent(port->mad_agent); 3223 ib_unregister_mad_agent(port->mad_agent);
3242 } 3224 }
3243error1:
3244 kfree(cm_dev); 3225 kfree(cm_dev);
3245} 3226}
3246 3227
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index e169e798354b..b2f3cb91d9bc 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -38,8 +38,7 @@
38#include <linux/errno.h> 38#include <linux/errno.h>
39#include <linux/slab.h> 39#include <linux/slab.h>
40#include <linux/init.h> 40#include <linux/init.h>
41 41#include <linux/mutex.h>
42#include <asm/semaphore.h>
43 42
44#include "core_priv.h" 43#include "core_priv.h"
45 44
@@ -57,13 +56,13 @@ static LIST_HEAD(device_list);
57static LIST_HEAD(client_list); 56static LIST_HEAD(client_list);
58 57
59/* 58/*
60 * device_sem protects access to both device_list and client_list. 59 * device_mutex protects access to both device_list and client_list.
61 * There's no real point to using multiple locks or something fancier 60 * There's no real point to using multiple locks or something fancier
62 * like an rwsem: we always access both lists, and we're always 61 * like an rwsem: we always access both lists, and we're always
63 * modifying one list or the other list. In any case this is not a 62 * modifying one list or the other list. In any case this is not a
64 * hot path so there's no point in trying to optimize. 63 * hot path so there's no point in trying to optimize.
65 */ 64 */
66static DECLARE_MUTEX(device_sem); 65static DEFINE_MUTEX(device_mutex);
67 66
68static int ib_device_check_mandatory(struct ib_device *device) 67static int ib_device_check_mandatory(struct ib_device *device)
69{ 68{
@@ -221,7 +220,7 @@ int ib_register_device(struct ib_device *device)
221{ 220{
222 int ret; 221 int ret;
223 222
224 down(&device_sem); 223 mutex_lock(&device_mutex);
225 224
226 if (strchr(device->name, '%')) { 225 if (strchr(device->name, '%')) {
227 ret = alloc_name(device->name); 226 ret = alloc_name(device->name);
@@ -259,7 +258,7 @@ int ib_register_device(struct ib_device *device)
259 } 258 }
260 259
261 out: 260 out:
262 up(&device_sem); 261 mutex_unlock(&device_mutex);
263 return ret; 262 return ret;
264} 263}
265EXPORT_SYMBOL(ib_register_device); 264EXPORT_SYMBOL(ib_register_device);
@@ -276,7 +275,7 @@ void ib_unregister_device(struct ib_device *device)
276 struct ib_client_data *context, *tmp; 275 struct ib_client_data *context, *tmp;
277 unsigned long flags; 276 unsigned long flags;
278 277
279 down(&device_sem); 278 mutex_lock(&device_mutex);
280 279
281 list_for_each_entry_reverse(client, &client_list, list) 280 list_for_each_entry_reverse(client, &client_list, list)
282 if (client->remove) 281 if (client->remove)
@@ -284,7 +283,7 @@ void ib_unregister_device(struct ib_device *device)
284 283
285 list_del(&device->core_list); 284 list_del(&device->core_list);
286 285
287 up(&device_sem); 286 mutex_unlock(&device_mutex);
288 287
289 spin_lock_irqsave(&device->client_data_lock, flags); 288 spin_lock_irqsave(&device->client_data_lock, flags);
290 list_for_each_entry_safe(context, tmp, &device->client_data_list, list) 289 list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
@@ -312,14 +311,14 @@ int ib_register_client(struct ib_client *client)
312{ 311{
313 struct ib_device *device; 312 struct ib_device *device;
314 313
315 down(&device_sem); 314 mutex_lock(&device_mutex);
316 315
317 list_add_tail(&client->list, &client_list); 316 list_add_tail(&client->list, &client_list);
318 list_for_each_entry(device, &device_list, core_list) 317 list_for_each_entry(device, &device_list, core_list)
319 if (client->add && !add_client_context(device, client)) 318 if (client->add && !add_client_context(device, client))
320 client->add(device); 319 client->add(device);
321 320
322 up(&device_sem); 321 mutex_unlock(&device_mutex);
323 322
324 return 0; 323 return 0;
325} 324}
@@ -339,7 +338,7 @@ void ib_unregister_client(struct ib_client *client)
339 struct ib_device *device; 338 struct ib_device *device;
340 unsigned long flags; 339 unsigned long flags;
341 340
342 down(&device_sem); 341 mutex_lock(&device_mutex);
343 342
344 list_for_each_entry(device, &device_list, core_list) { 343 list_for_each_entry(device, &device_list, core_list) {
345 if (client->remove) 344 if (client->remove)
@@ -355,7 +354,7 @@ void ib_unregister_client(struct ib_client *client)
355 } 354 }
356 list_del(&client->list); 355 list_del(&client->list);
357 356
358 up(&device_sem); 357 mutex_unlock(&device_mutex);
359} 358}
360EXPORT_SYMBOL(ib_unregister_client); 359EXPORT_SYMBOL(ib_unregister_client);
361 360
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 1f1743c5c9a3..5982d687a000 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -445,13 +445,7 @@ static int ib_device_uevent(struct class_device *cdev, char **envp,
445 return -ENOMEM; 445 return -ENOMEM;
446 446
447 /* 447 /*
448 * It might be nice to pass the node GUID with the event, but 448 * It would be nice to pass the node GUID with the event...
449 * right now the only way to get it is to query the device
450 * provider, and this can crash during device removal because
451 * we are will be running after driver removal has started.
452 * We could add a node_guid field to struct ib_device, or we
453 * could just let userspace read the node GUID from sysfs when
454 * devices are added.
455 */ 449 */
456 450
457 envp[i] = NULL; 451 envp[i] = NULL;
@@ -623,21 +617,15 @@ static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf)
623static ssize_t show_node_guid(struct class_device *cdev, char *buf) 617static ssize_t show_node_guid(struct class_device *cdev, char *buf)
624{ 618{
625 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); 619 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
626 struct ib_device_attr attr;
627 ssize_t ret;
628 620
629 if (!ibdev_is_alive(dev)) 621 if (!ibdev_is_alive(dev))
630 return -ENODEV; 622 return -ENODEV;
631 623
632 ret = ib_query_device(dev, &attr);
633 if (ret)
634 return ret;
635
636 return sprintf(buf, "%04x:%04x:%04x:%04x\n", 624 return sprintf(buf, "%04x:%04x:%04x:%04x\n",
637 be16_to_cpu(((__be16 *) &attr.node_guid)[0]), 625 be16_to_cpu(((__be16 *) &dev->node_guid)[0]),
638 be16_to_cpu(((__be16 *) &attr.node_guid)[1]), 626 be16_to_cpu(((__be16 *) &dev->node_guid)[1]),
639 be16_to_cpu(((__be16 *) &attr.node_guid)[2]), 627 be16_to_cpu(((__be16 *) &dev->node_guid)[2]),
640 be16_to_cpu(((__be16 *) &attr.node_guid)[3])); 628 be16_to_cpu(((__be16 *) &dev->node_guid)[3]));
641} 629}
642 630
643static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL); 631static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index 6e15787d1de1..e95c4293a496 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -42,6 +42,7 @@
42#include <linux/mount.h> 42#include <linux/mount.h>
43#include <linux/cdev.h> 43#include <linux/cdev.h>
44#include <linux/idr.h> 44#include <linux/idr.h>
45#include <linux/mutex.h>
45 46
46#include <asm/uaccess.h> 47#include <asm/uaccess.h>
47 48
@@ -113,7 +114,7 @@ static struct ib_client ucm_client = {
113 .remove = ib_ucm_remove_one 114 .remove = ib_ucm_remove_one
114}; 115};
115 116
116static DECLARE_MUTEX(ctx_id_mutex); 117static DEFINE_MUTEX(ctx_id_mutex);
117static DEFINE_IDR(ctx_id_table); 118static DEFINE_IDR(ctx_id_table);
118static DECLARE_BITMAP(dev_map, IB_UCM_MAX_DEVICES); 119static DECLARE_BITMAP(dev_map, IB_UCM_MAX_DEVICES);
119 120
@@ -121,7 +122,7 @@ static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id)
121{ 122{
122 struct ib_ucm_context *ctx; 123 struct ib_ucm_context *ctx;
123 124
124 down(&ctx_id_mutex); 125 mutex_lock(&ctx_id_mutex);
125 ctx = idr_find(&ctx_id_table, id); 126 ctx = idr_find(&ctx_id_table, id);
126 if (!ctx) 127 if (!ctx)
127 ctx = ERR_PTR(-ENOENT); 128 ctx = ERR_PTR(-ENOENT);
@@ -129,7 +130,7 @@ static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id)
129 ctx = ERR_PTR(-EINVAL); 130 ctx = ERR_PTR(-EINVAL);
130 else 131 else
131 atomic_inc(&ctx->ref); 132 atomic_inc(&ctx->ref);
132 up(&ctx_id_mutex); 133 mutex_unlock(&ctx_id_mutex);
133 134
134 return ctx; 135 return ctx;
135} 136}
@@ -186,9 +187,9 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)
186 if (!result) 187 if (!result)
187 goto error; 188 goto error;
188 189
189 down(&ctx_id_mutex); 190 mutex_lock(&ctx_id_mutex);
190 result = idr_get_new(&ctx_id_table, ctx, &ctx->id); 191 result = idr_get_new(&ctx_id_table, ctx, &ctx->id);
191 up(&ctx_id_mutex); 192 mutex_unlock(&ctx_id_mutex);
192 } while (result == -EAGAIN); 193 } while (result == -EAGAIN);
193 194
194 if (result) 195 if (result)
@@ -550,9 +551,9 @@ static ssize_t ib_ucm_create_id(struct ib_ucm_file *file,
550err2: 551err2:
551 ib_destroy_cm_id(ctx->cm_id); 552 ib_destroy_cm_id(ctx->cm_id);
552err1: 553err1:
553 down(&ctx_id_mutex); 554 mutex_lock(&ctx_id_mutex);
554 idr_remove(&ctx_id_table, ctx->id); 555 idr_remove(&ctx_id_table, ctx->id);
555 up(&ctx_id_mutex); 556 mutex_unlock(&ctx_id_mutex);
556 kfree(ctx); 557 kfree(ctx);
557 return result; 558 return result;
558} 559}
@@ -572,7 +573,7 @@ static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file,
572 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 573 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
573 return -EFAULT; 574 return -EFAULT;
574 575
575 down(&ctx_id_mutex); 576 mutex_lock(&ctx_id_mutex);
576 ctx = idr_find(&ctx_id_table, cmd.id); 577 ctx = idr_find(&ctx_id_table, cmd.id);
577 if (!ctx) 578 if (!ctx)
578 ctx = ERR_PTR(-ENOENT); 579 ctx = ERR_PTR(-ENOENT);
@@ -580,7 +581,7 @@ static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file,
580 ctx = ERR_PTR(-EINVAL); 581 ctx = ERR_PTR(-EINVAL);
581 else 582 else
582 idr_remove(&ctx_id_table, ctx->id); 583 idr_remove(&ctx_id_table, ctx->id);
583 up(&ctx_id_mutex); 584 mutex_unlock(&ctx_id_mutex);
584 585
585 if (IS_ERR(ctx)) 586 if (IS_ERR(ctx))
586 return PTR_ERR(ctx); 587 return PTR_ERR(ctx);
@@ -1280,9 +1281,9 @@ static int ib_ucm_close(struct inode *inode, struct file *filp)
1280 struct ib_ucm_context, file_list); 1281 struct ib_ucm_context, file_list);
1281 up(&file->mutex); 1282 up(&file->mutex);
1282 1283
1283 down(&ctx_id_mutex); 1284 mutex_lock(&ctx_id_mutex);
1284 idr_remove(&ctx_id_table, ctx->id); 1285 idr_remove(&ctx_id_table, ctx->id);
1285 up(&ctx_id_mutex); 1286 mutex_unlock(&ctx_id_mutex);
1286 1287
1287 ib_destroy_cm_id(ctx->cm_id); 1288 ib_destroy_cm_id(ctx->cm_id);
1288 ib_ucm_cleanup_events(ctx); 1289 ib_ucm_cleanup_events(ctx);
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index 7114e3fbab00..f7eecbc6af6c 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -41,6 +41,7 @@
41 41
42#include <linux/kref.h> 42#include <linux/kref.h>
43#include <linux/idr.h> 43#include <linux/idr.h>
44#include <linux/mutex.h>
44 45
45#include <rdma/ib_verbs.h> 46#include <rdma/ib_verbs.h>
46#include <rdma/ib_user_verbs.h> 47#include <rdma/ib_user_verbs.h>
@@ -88,7 +89,7 @@ struct ib_uverbs_event_file {
88 89
89struct ib_uverbs_file { 90struct ib_uverbs_file {
90 struct kref ref; 91 struct kref ref;
91 struct semaphore mutex; 92 struct mutex mutex;
92 struct ib_uverbs_device *device; 93 struct ib_uverbs_device *device;
93 struct ib_ucontext *ucontext; 94 struct ib_ucontext *ucontext;
94 struct ib_event_handler event_handler; 95 struct ib_event_handler event_handler;
@@ -131,7 +132,7 @@ struct ib_ucq_object {
131 u32 async_events_reported; 132 u32 async_events_reported;
132}; 133};
133 134
134extern struct semaphore ib_uverbs_idr_mutex; 135extern struct mutex ib_uverbs_idr_mutex;
135extern struct idr ib_uverbs_pd_idr; 136extern struct idr ib_uverbs_pd_idr;
136extern struct idr ib_uverbs_mr_idr; 137extern struct idr ib_uverbs_mr_idr;
137extern struct idr ib_uverbs_mw_idr; 138extern struct idr ib_uverbs_mw_idr;
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index a02c5a05c984..407b6284d7d5 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -67,7 +67,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
67 if (copy_from_user(&cmd, buf, sizeof cmd)) 67 if (copy_from_user(&cmd, buf, sizeof cmd))
68 return -EFAULT; 68 return -EFAULT;
69 69
70 down(&file->mutex); 70 mutex_lock(&file->mutex);
71 71
72 if (file->ucontext) { 72 if (file->ucontext) {
73 ret = -EINVAL; 73 ret = -EINVAL;
@@ -119,7 +119,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
119 119
120 fd_install(resp.async_fd, filp); 120 fd_install(resp.async_fd, filp);
121 121
122 up(&file->mutex); 122 mutex_unlock(&file->mutex);
123 123
124 return in_len; 124 return in_len;
125 125
@@ -131,7 +131,7 @@ err_free:
131 ibdev->dealloc_ucontext(ucontext); 131 ibdev->dealloc_ucontext(ucontext);
132 132
133err: 133err:
134 up(&file->mutex); 134 mutex_unlock(&file->mutex);
135 return ret; 135 return ret;
136} 136}
137 137
@@ -157,7 +157,7 @@ ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
157 memset(&resp, 0, sizeof resp); 157 memset(&resp, 0, sizeof resp);
158 158
159 resp.fw_ver = attr.fw_ver; 159 resp.fw_ver = attr.fw_ver;
160 resp.node_guid = attr.node_guid; 160 resp.node_guid = file->device->ib_dev->node_guid;
161 resp.sys_image_guid = attr.sys_image_guid; 161 resp.sys_image_guid = attr.sys_image_guid;
162 resp.max_mr_size = attr.max_mr_size; 162 resp.max_mr_size = attr.max_mr_size;
163 resp.page_size_cap = attr.page_size_cap; 163 resp.page_size_cap = attr.page_size_cap;
@@ -290,7 +290,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
290 pd->uobject = uobj; 290 pd->uobject = uobj;
291 atomic_set(&pd->usecnt, 0); 291 atomic_set(&pd->usecnt, 0);
292 292
293 down(&ib_uverbs_idr_mutex); 293 mutex_lock(&ib_uverbs_idr_mutex);
294 294
295retry: 295retry:
296 if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) { 296 if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) {
@@ -314,11 +314,11 @@ retry:
314 goto err_idr; 314 goto err_idr;
315 } 315 }
316 316
317 down(&file->mutex); 317 mutex_lock(&file->mutex);
318 list_add_tail(&uobj->list, &file->ucontext->pd_list); 318 list_add_tail(&uobj->list, &file->ucontext->pd_list);
319 up(&file->mutex); 319 mutex_unlock(&file->mutex);
320 320
321 up(&ib_uverbs_idr_mutex); 321 mutex_unlock(&ib_uverbs_idr_mutex);
322 322
323 return in_len; 323 return in_len;
324 324
@@ -326,7 +326,7 @@ err_idr:
326 idr_remove(&ib_uverbs_pd_idr, uobj->id); 326 idr_remove(&ib_uverbs_pd_idr, uobj->id);
327 327
328err_up: 328err_up:
329 up(&ib_uverbs_idr_mutex); 329 mutex_unlock(&ib_uverbs_idr_mutex);
330 ib_dealloc_pd(pd); 330 ib_dealloc_pd(pd);
331 331
332err: 332err:
@@ -346,7 +346,7 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file,
346 if (copy_from_user(&cmd, buf, sizeof cmd)) 346 if (copy_from_user(&cmd, buf, sizeof cmd))
347 return -EFAULT; 347 return -EFAULT;
348 348
349 down(&ib_uverbs_idr_mutex); 349 mutex_lock(&ib_uverbs_idr_mutex);
350 350
351 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); 351 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
352 if (!pd || pd->uobject->context != file->ucontext) 352 if (!pd || pd->uobject->context != file->ucontext)
@@ -360,14 +360,14 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file,
360 360
361 idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle); 361 idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle);
362 362
363 down(&file->mutex); 363 mutex_lock(&file->mutex);
364 list_del(&uobj->list); 364 list_del(&uobj->list);
365 up(&file->mutex); 365 mutex_unlock(&file->mutex);
366 366
367 kfree(uobj); 367 kfree(uobj);
368 368
369out: 369out:
370 up(&ib_uverbs_idr_mutex); 370 mutex_unlock(&ib_uverbs_idr_mutex);
371 371
372 return ret ? ret : in_len; 372 return ret ? ret : in_len;
373} 373}
@@ -426,7 +426,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
426 426
427 obj->umem.virt_base = cmd.hca_va; 427 obj->umem.virt_base = cmd.hca_va;
428 428
429 down(&ib_uverbs_idr_mutex); 429 mutex_lock(&ib_uverbs_idr_mutex);
430 430
431 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); 431 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
432 if (!pd || pd->uobject->context != file->ucontext) { 432 if (!pd || pd->uobject->context != file->ucontext) {
@@ -476,11 +476,11 @@ retry:
476 goto err_idr; 476 goto err_idr;
477 } 477 }
478 478
479 down(&file->mutex); 479 mutex_lock(&file->mutex);
480 list_add_tail(&obj->uobject.list, &file->ucontext->mr_list); 480 list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
481 up(&file->mutex); 481 mutex_unlock(&file->mutex);
482 482
483 up(&ib_uverbs_idr_mutex); 483 mutex_unlock(&ib_uverbs_idr_mutex);
484 484
485 return in_len; 485 return in_len;
486 486
@@ -492,7 +492,7 @@ err_unreg:
492 atomic_dec(&pd->usecnt); 492 atomic_dec(&pd->usecnt);
493 493
494err_up: 494err_up:
495 up(&ib_uverbs_idr_mutex); 495 mutex_unlock(&ib_uverbs_idr_mutex);
496 496
497 ib_umem_release(file->device->ib_dev, &obj->umem); 497 ib_umem_release(file->device->ib_dev, &obj->umem);
498 498
@@ -513,7 +513,7 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
513 if (copy_from_user(&cmd, buf, sizeof cmd)) 513 if (copy_from_user(&cmd, buf, sizeof cmd))
514 return -EFAULT; 514 return -EFAULT;
515 515
516 down(&ib_uverbs_idr_mutex); 516 mutex_lock(&ib_uverbs_idr_mutex);
517 517
518 mr = idr_find(&ib_uverbs_mr_idr, cmd.mr_handle); 518 mr = idr_find(&ib_uverbs_mr_idr, cmd.mr_handle);
519 if (!mr || mr->uobject->context != file->ucontext) 519 if (!mr || mr->uobject->context != file->ucontext)
@@ -527,15 +527,15 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
527 527
528 idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle); 528 idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle);
529 529
530 down(&file->mutex); 530 mutex_lock(&file->mutex);
531 list_del(&memobj->uobject.list); 531 list_del(&memobj->uobject.list);
532 up(&file->mutex); 532 mutex_unlock(&file->mutex);
533 533
534 ib_umem_release(file->device->ib_dev, &memobj->umem); 534 ib_umem_release(file->device->ib_dev, &memobj->umem);
535 kfree(memobj); 535 kfree(memobj);
536 536
537out: 537out:
538 up(&ib_uverbs_idr_mutex); 538 mutex_unlock(&ib_uverbs_idr_mutex);
539 539
540 return ret ? ret : in_len; 540 return ret ? ret : in_len;
541} 541}
@@ -628,7 +628,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
628 cq->cq_context = ev_file; 628 cq->cq_context = ev_file;
629 atomic_set(&cq->usecnt, 0); 629 atomic_set(&cq->usecnt, 0);
630 630
631 down(&ib_uverbs_idr_mutex); 631 mutex_lock(&ib_uverbs_idr_mutex);
632 632
633retry: 633retry:
634 if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) { 634 if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) {
@@ -653,11 +653,11 @@ retry:
653 goto err_idr; 653 goto err_idr;
654 } 654 }
655 655
656 down(&file->mutex); 656 mutex_lock(&file->mutex);
657 list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list); 657 list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list);
658 up(&file->mutex); 658 mutex_unlock(&file->mutex);
659 659
660 up(&ib_uverbs_idr_mutex); 660 mutex_unlock(&ib_uverbs_idr_mutex);
661 661
662 return in_len; 662 return in_len;
663 663
@@ -665,7 +665,7 @@ err_idr:
665 idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id); 665 idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id);
666 666
667err_up: 667err_up:
668 up(&ib_uverbs_idr_mutex); 668 mutex_unlock(&ib_uverbs_idr_mutex);
669 ib_destroy_cq(cq); 669 ib_destroy_cq(cq);
670 670
671err: 671err:
@@ -701,7 +701,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
701 goto out_wc; 701 goto out_wc;
702 } 702 }
703 703
704 down(&ib_uverbs_idr_mutex); 704 mutex_lock(&ib_uverbs_idr_mutex);
705 cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); 705 cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
706 if (!cq || cq->uobject->context != file->ucontext) { 706 if (!cq || cq->uobject->context != file->ucontext) {
707 ret = -EINVAL; 707 ret = -EINVAL;
@@ -731,7 +731,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
731 ret = -EFAULT; 731 ret = -EFAULT;
732 732
733out: 733out:
734 up(&ib_uverbs_idr_mutex); 734 mutex_unlock(&ib_uverbs_idr_mutex);
735 kfree(resp); 735 kfree(resp);
736 736
737out_wc: 737out_wc:
@@ -750,14 +750,14 @@ ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
750 if (copy_from_user(&cmd, buf, sizeof cmd)) 750 if (copy_from_user(&cmd, buf, sizeof cmd))
751 return -EFAULT; 751 return -EFAULT;
752 752
753 down(&ib_uverbs_idr_mutex); 753 mutex_lock(&ib_uverbs_idr_mutex);
754 cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); 754 cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
755 if (cq && cq->uobject->context == file->ucontext) { 755 if (cq && cq->uobject->context == file->ucontext) {
756 ib_req_notify_cq(cq, cmd.solicited_only ? 756 ib_req_notify_cq(cq, cmd.solicited_only ?
757 IB_CQ_SOLICITED : IB_CQ_NEXT_COMP); 757 IB_CQ_SOLICITED : IB_CQ_NEXT_COMP);
758 ret = in_len; 758 ret = in_len;
759 } 759 }
760 up(&ib_uverbs_idr_mutex); 760 mutex_unlock(&ib_uverbs_idr_mutex);
761 761
762 return ret; 762 return ret;
763} 763}
@@ -779,7 +779,7 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
779 779
780 memset(&resp, 0, sizeof resp); 780 memset(&resp, 0, sizeof resp);
781 781
782 down(&ib_uverbs_idr_mutex); 782 mutex_lock(&ib_uverbs_idr_mutex);
783 783
784 cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); 784 cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
785 if (!cq || cq->uobject->context != file->ucontext) 785 if (!cq || cq->uobject->context != file->ucontext)
@@ -795,9 +795,9 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
795 795
796 idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle); 796 idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle);
797 797
798 down(&file->mutex); 798 mutex_lock(&file->mutex);
799 list_del(&uobj->uobject.list); 799 list_del(&uobj->uobject.list);
800 up(&file->mutex); 800 mutex_unlock(&file->mutex);
801 801
802 ib_uverbs_release_ucq(file, ev_file, uobj); 802 ib_uverbs_release_ucq(file, ev_file, uobj);
803 803
@@ -811,7 +811,7 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
811 ret = -EFAULT; 811 ret = -EFAULT;
812 812
813out: 813out:
814 up(&ib_uverbs_idr_mutex); 814 mutex_unlock(&ib_uverbs_idr_mutex);
815 815
816 return ret ? ret : in_len; 816 return ret ? ret : in_len;
817} 817}
@@ -845,7 +845,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
845 if (!uobj) 845 if (!uobj)
846 return -ENOMEM; 846 return -ENOMEM;
847 847
848 down(&ib_uverbs_idr_mutex); 848 mutex_lock(&ib_uverbs_idr_mutex);
849 849
850 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); 850 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
851 scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle); 851 scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle);
@@ -930,11 +930,11 @@ retry:
930 goto err_idr; 930 goto err_idr;
931 } 931 }
932 932
933 down(&file->mutex); 933 mutex_lock(&file->mutex);
934 list_add_tail(&uobj->uevent.uobject.list, &file->ucontext->qp_list); 934 list_add_tail(&uobj->uevent.uobject.list, &file->ucontext->qp_list);
935 up(&file->mutex); 935 mutex_unlock(&file->mutex);
936 936
937 up(&ib_uverbs_idr_mutex); 937 mutex_unlock(&ib_uverbs_idr_mutex);
938 938
939 return in_len; 939 return in_len;
940 940
@@ -950,7 +950,7 @@ err_destroy:
950 atomic_dec(&attr.srq->usecnt); 950 atomic_dec(&attr.srq->usecnt);
951 951
952err_up: 952err_up:
953 up(&ib_uverbs_idr_mutex); 953 mutex_unlock(&ib_uverbs_idr_mutex);
954 954
955 kfree(uobj); 955 kfree(uobj);
956 return ret; 956 return ret;
@@ -972,7 +972,7 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
972 if (!attr) 972 if (!attr)
973 return -ENOMEM; 973 return -ENOMEM;
974 974
975 down(&ib_uverbs_idr_mutex); 975 mutex_lock(&ib_uverbs_idr_mutex);
976 976
977 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); 977 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
978 if (!qp || qp->uobject->context != file->ucontext) { 978 if (!qp || qp->uobject->context != file->ucontext) {
@@ -1033,7 +1033,7 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
1033 ret = in_len; 1033 ret = in_len;
1034 1034
1035out: 1035out:
1036 up(&ib_uverbs_idr_mutex); 1036 mutex_unlock(&ib_uverbs_idr_mutex);
1037 kfree(attr); 1037 kfree(attr);
1038 1038
1039 return ret; 1039 return ret;
@@ -1054,7 +1054,7 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
1054 1054
1055 memset(&resp, 0, sizeof resp); 1055 memset(&resp, 0, sizeof resp);
1056 1056
1057 down(&ib_uverbs_idr_mutex); 1057 mutex_lock(&ib_uverbs_idr_mutex);
1058 1058
1059 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); 1059 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1060 if (!qp || qp->uobject->context != file->ucontext) 1060 if (!qp || qp->uobject->context != file->ucontext)
@@ -1073,9 +1073,9 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
1073 1073
1074 idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle); 1074 idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle);
1075 1075
1076 down(&file->mutex); 1076 mutex_lock(&file->mutex);
1077 list_del(&uobj->uevent.uobject.list); 1077 list_del(&uobj->uevent.uobject.list);
1078 up(&file->mutex); 1078 mutex_unlock(&file->mutex);
1079 1079
1080 ib_uverbs_release_uevent(file, &uobj->uevent); 1080 ib_uverbs_release_uevent(file, &uobj->uevent);
1081 1081
@@ -1088,7 +1088,7 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
1088 ret = -EFAULT; 1088 ret = -EFAULT;
1089 1089
1090out: 1090out:
1091 up(&ib_uverbs_idr_mutex); 1091 mutex_unlock(&ib_uverbs_idr_mutex);
1092 1092
1093 return ret ? ret : in_len; 1093 return ret ? ret : in_len;
1094} 1094}
@@ -1119,7 +1119,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
1119 if (!user_wr) 1119 if (!user_wr)
1120 return -ENOMEM; 1120 return -ENOMEM;
1121 1121
1122 down(&ib_uverbs_idr_mutex); 1122 mutex_lock(&ib_uverbs_idr_mutex);
1123 1123
1124 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); 1124 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1125 if (!qp || qp->uobject->context != file->ucontext) 1125 if (!qp || qp->uobject->context != file->ucontext)
@@ -1224,7 +1224,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
1224 ret = -EFAULT; 1224 ret = -EFAULT;
1225 1225
1226out: 1226out:
1227 up(&ib_uverbs_idr_mutex); 1227 mutex_unlock(&ib_uverbs_idr_mutex);
1228 1228
1229 while (wr) { 1229 while (wr) {
1230 next = wr->next; 1230 next = wr->next;
@@ -1341,7 +1341,7 @@ ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file,
1341 if (IS_ERR(wr)) 1341 if (IS_ERR(wr))
1342 return PTR_ERR(wr); 1342 return PTR_ERR(wr);
1343 1343
1344 down(&ib_uverbs_idr_mutex); 1344 mutex_lock(&ib_uverbs_idr_mutex);
1345 1345
1346 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); 1346 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1347 if (!qp || qp->uobject->context != file->ucontext) 1347 if (!qp || qp->uobject->context != file->ucontext)
@@ -1362,7 +1362,7 @@ ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file,
1362 ret = -EFAULT; 1362 ret = -EFAULT;
1363 1363
1364out: 1364out:
1365 up(&ib_uverbs_idr_mutex); 1365 mutex_unlock(&ib_uverbs_idr_mutex);
1366 1366
1367 while (wr) { 1367 while (wr) {
1368 next = wr->next; 1368 next = wr->next;
@@ -1392,7 +1392,7 @@ ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file,
1392 if (IS_ERR(wr)) 1392 if (IS_ERR(wr))
1393 return PTR_ERR(wr); 1393 return PTR_ERR(wr);
1394 1394
1395 down(&ib_uverbs_idr_mutex); 1395 mutex_lock(&ib_uverbs_idr_mutex);
1396 1396
1397 srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); 1397 srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
1398 if (!srq || srq->uobject->context != file->ucontext) 1398 if (!srq || srq->uobject->context != file->ucontext)
@@ -1413,7 +1413,7 @@ ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file,
1413 ret = -EFAULT; 1413 ret = -EFAULT;
1414 1414
1415out: 1415out:
1416 up(&ib_uverbs_idr_mutex); 1416 mutex_unlock(&ib_uverbs_idr_mutex);
1417 1417
1418 while (wr) { 1418 while (wr) {
1419 next = wr->next; 1419 next = wr->next;
@@ -1446,7 +1446,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
1446 if (!uobj) 1446 if (!uobj)
1447 return -ENOMEM; 1447 return -ENOMEM;
1448 1448
1449 down(&ib_uverbs_idr_mutex); 1449 mutex_lock(&ib_uverbs_idr_mutex);
1450 1450
1451 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); 1451 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
1452 if (!pd || pd->uobject->context != file->ucontext) { 1452 if (!pd || pd->uobject->context != file->ucontext) {
@@ -1498,11 +1498,11 @@ retry:
1498 goto err_idr; 1498 goto err_idr;
1499 } 1499 }
1500 1500
1501 down(&file->mutex); 1501 mutex_lock(&file->mutex);
1502 list_add_tail(&uobj->list, &file->ucontext->ah_list); 1502 list_add_tail(&uobj->list, &file->ucontext->ah_list);
1503 up(&file->mutex); 1503 mutex_unlock(&file->mutex);
1504 1504
1505 up(&ib_uverbs_idr_mutex); 1505 mutex_unlock(&ib_uverbs_idr_mutex);
1506 1506
1507 return in_len; 1507 return in_len;
1508 1508
@@ -1513,7 +1513,7 @@ err_destroy:
1513 ib_destroy_ah(ah); 1513 ib_destroy_ah(ah);
1514 1514
1515err_up: 1515err_up:
1516 up(&ib_uverbs_idr_mutex); 1516 mutex_unlock(&ib_uverbs_idr_mutex);
1517 1517
1518 kfree(uobj); 1518 kfree(uobj);
1519 return ret; 1519 return ret;
@@ -1530,7 +1530,7 @@ ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file,
1530 if (copy_from_user(&cmd, buf, sizeof cmd)) 1530 if (copy_from_user(&cmd, buf, sizeof cmd))
1531 return -EFAULT; 1531 return -EFAULT;
1532 1532
1533 down(&ib_uverbs_idr_mutex); 1533 mutex_lock(&ib_uverbs_idr_mutex);
1534 1534
1535 ah = idr_find(&ib_uverbs_ah_idr, cmd.ah_handle); 1535 ah = idr_find(&ib_uverbs_ah_idr, cmd.ah_handle);
1536 if (!ah || ah->uobject->context != file->ucontext) 1536 if (!ah || ah->uobject->context != file->ucontext)
@@ -1544,14 +1544,14 @@ ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file,
1544 1544
1545 idr_remove(&ib_uverbs_ah_idr, cmd.ah_handle); 1545 idr_remove(&ib_uverbs_ah_idr, cmd.ah_handle);
1546 1546
1547 down(&file->mutex); 1547 mutex_lock(&file->mutex);
1548 list_del(&uobj->list); 1548 list_del(&uobj->list);
1549 up(&file->mutex); 1549 mutex_unlock(&file->mutex);
1550 1550
1551 kfree(uobj); 1551 kfree(uobj);
1552 1552
1553out: 1553out:
1554 up(&ib_uverbs_idr_mutex); 1554 mutex_unlock(&ib_uverbs_idr_mutex);
1555 1555
1556 return ret ? ret : in_len; 1556 return ret ? ret : in_len;
1557} 1557}
@@ -1569,7 +1569,7 @@ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
1569 if (copy_from_user(&cmd, buf, sizeof cmd)) 1569 if (copy_from_user(&cmd, buf, sizeof cmd))
1570 return -EFAULT; 1570 return -EFAULT;
1571 1571
1572 down(&ib_uverbs_idr_mutex); 1572 mutex_lock(&ib_uverbs_idr_mutex);
1573 1573
1574 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); 1574 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1575 if (!qp || qp->uobject->context != file->ucontext) 1575 if (!qp || qp->uobject->context != file->ucontext)
@@ -1602,7 +1602,7 @@ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
1602 kfree(mcast); 1602 kfree(mcast);
1603 1603
1604out: 1604out:
1605 up(&ib_uverbs_idr_mutex); 1605 mutex_unlock(&ib_uverbs_idr_mutex);
1606 1606
1607 return ret ? ret : in_len; 1607 return ret ? ret : in_len;
1608} 1608}
@@ -1620,7 +1620,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
1620 if (copy_from_user(&cmd, buf, sizeof cmd)) 1620 if (copy_from_user(&cmd, buf, sizeof cmd))
1621 return -EFAULT; 1621 return -EFAULT;
1622 1622
1623 down(&ib_uverbs_idr_mutex); 1623 mutex_lock(&ib_uverbs_idr_mutex);
1624 1624
1625 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); 1625 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1626 if (!qp || qp->uobject->context != file->ucontext) 1626 if (!qp || qp->uobject->context != file->ucontext)
@@ -1641,7 +1641,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
1641 } 1641 }
1642 1642
1643out: 1643out:
1644 up(&ib_uverbs_idr_mutex); 1644 mutex_unlock(&ib_uverbs_idr_mutex);
1645 1645
1646 return ret ? ret : in_len; 1646 return ret ? ret : in_len;
1647} 1647}
@@ -1673,7 +1673,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
1673 if (!uobj) 1673 if (!uobj)
1674 return -ENOMEM; 1674 return -ENOMEM;
1675 1675
1676 down(&ib_uverbs_idr_mutex); 1676 mutex_lock(&ib_uverbs_idr_mutex);
1677 1677
1678 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); 1678 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
1679 1679
@@ -1730,11 +1730,11 @@ retry:
1730 goto err_idr; 1730 goto err_idr;
1731 } 1731 }
1732 1732
1733 down(&file->mutex); 1733 mutex_lock(&file->mutex);
1734 list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list); 1734 list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list);
1735 up(&file->mutex); 1735 mutex_unlock(&file->mutex);
1736 1736
1737 up(&ib_uverbs_idr_mutex); 1737 mutex_unlock(&ib_uverbs_idr_mutex);
1738 1738
1739 return in_len; 1739 return in_len;
1740 1740
@@ -1746,7 +1746,7 @@ err_destroy:
1746 atomic_dec(&pd->usecnt); 1746 atomic_dec(&pd->usecnt);
1747 1747
1748err_up: 1748err_up:
1749 up(&ib_uverbs_idr_mutex); 1749 mutex_unlock(&ib_uverbs_idr_mutex);
1750 1750
1751 kfree(uobj); 1751 kfree(uobj);
1752 return ret; 1752 return ret;
@@ -1764,7 +1764,7 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
1764 if (copy_from_user(&cmd, buf, sizeof cmd)) 1764 if (copy_from_user(&cmd, buf, sizeof cmd))
1765 return -EFAULT; 1765 return -EFAULT;
1766 1766
1767 down(&ib_uverbs_idr_mutex); 1767 mutex_lock(&ib_uverbs_idr_mutex);
1768 1768
1769 srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); 1769 srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
1770 if (!srq || srq->uobject->context != file->ucontext) { 1770 if (!srq || srq->uobject->context != file->ucontext) {
@@ -1778,7 +1778,7 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
1778 ret = ib_modify_srq(srq, &attr, cmd.attr_mask); 1778 ret = ib_modify_srq(srq, &attr, cmd.attr_mask);
1779 1779
1780out: 1780out:
1781 up(&ib_uverbs_idr_mutex); 1781 mutex_unlock(&ib_uverbs_idr_mutex);
1782 1782
1783 return ret ? ret : in_len; 1783 return ret ? ret : in_len;
1784} 1784}
@@ -1796,7 +1796,7 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
1796 if (copy_from_user(&cmd, buf, sizeof cmd)) 1796 if (copy_from_user(&cmd, buf, sizeof cmd))
1797 return -EFAULT; 1797 return -EFAULT;
1798 1798
1799 down(&ib_uverbs_idr_mutex); 1799 mutex_lock(&ib_uverbs_idr_mutex);
1800 1800
1801 memset(&resp, 0, sizeof resp); 1801 memset(&resp, 0, sizeof resp);
1802 1802
@@ -1812,9 +1812,9 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
1812 1812
1813 idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle); 1813 idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle);
1814 1814
1815 down(&file->mutex); 1815 mutex_lock(&file->mutex);
1816 list_del(&uobj->uobject.list); 1816 list_del(&uobj->uobject.list);
1817 up(&file->mutex); 1817 mutex_unlock(&file->mutex);
1818 1818
1819 ib_uverbs_release_uevent(file, uobj); 1819 ib_uverbs_release_uevent(file, uobj);
1820 1820
@@ -1827,7 +1827,7 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
1827 ret = -EFAULT; 1827 ret = -EFAULT;
1828 1828
1829out: 1829out:
1830 up(&ib_uverbs_idr_mutex); 1830 mutex_unlock(&ib_uverbs_idr_mutex);
1831 1831
1832 return ret ? ret : in_len; 1832 return ret ? ret : in_len;
1833} 1833}
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 81737bd6faea..96ea79b63df7 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -66,7 +66,7 @@ enum {
66 66
67static struct class *uverbs_class; 67static struct class *uverbs_class;
68 68
69DECLARE_MUTEX(ib_uverbs_idr_mutex); 69DEFINE_MUTEX(ib_uverbs_idr_mutex);
70DEFINE_IDR(ib_uverbs_pd_idr); 70DEFINE_IDR(ib_uverbs_pd_idr);
71DEFINE_IDR(ib_uverbs_mr_idr); 71DEFINE_IDR(ib_uverbs_mr_idr);
72DEFINE_IDR(ib_uverbs_mw_idr); 72DEFINE_IDR(ib_uverbs_mw_idr);
@@ -180,7 +180,7 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
180 if (!context) 180 if (!context)
181 return 0; 181 return 0;
182 182
183 down(&ib_uverbs_idr_mutex); 183 mutex_lock(&ib_uverbs_idr_mutex);
184 184
185 list_for_each_entry_safe(uobj, tmp, &context->ah_list, list) { 185 list_for_each_entry_safe(uobj, tmp, &context->ah_list, list) {
186 struct ib_ah *ah = idr_find(&ib_uverbs_ah_idr, uobj->id); 186 struct ib_ah *ah = idr_find(&ib_uverbs_ah_idr, uobj->id);
@@ -250,7 +250,7 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
250 kfree(uobj); 250 kfree(uobj);
251 } 251 }
252 252
253 up(&ib_uverbs_idr_mutex); 253 mutex_unlock(&ib_uverbs_idr_mutex);
254 254
255 return context->device->dealloc_ucontext(context); 255 return context->device->dealloc_ucontext(context);
256} 256}
@@ -653,7 +653,7 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)
653 file->ucontext = NULL; 653 file->ucontext = NULL;
654 file->async_file = NULL; 654 file->async_file = NULL;
655 kref_init(&file->ref); 655 kref_init(&file->ref);
656 init_MUTEX(&file->mutex); 656 mutex_init(&file->mutex);
657 657
658 filp->private_data = file; 658 filp->private_data = file;
659 659
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index 22fdc446f25c..a14eed08a0fc 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -163,6 +163,11 @@ int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah)
163 return 0; 163 return 0;
164} 164}
165 165
166int mthca_ah_grh_present(struct mthca_ah *ah)
167{
168 return !!(ah->av->g_slid & 0x80);
169}
170
166int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah, 171int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
167 struct ib_ud_header *header) 172 struct ib_ud_header *header)
168{ 173{
@@ -172,8 +177,7 @@ int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
172 header->lrh.service_level = be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 28; 177 header->lrh.service_level = be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 28;
173 header->lrh.destination_lid = ah->av->dlid; 178 header->lrh.destination_lid = ah->av->dlid;
174 header->lrh.source_lid = cpu_to_be16(ah->av->g_slid & 0x7f); 179 header->lrh.source_lid = cpu_to_be16(ah->av->g_slid & 0x7f);
175 if (ah->av->g_slid & 0x80) { 180 if (mthca_ah_grh_present(ah)) {
176 header->grh_present = 1;
177 header->grh.traffic_class = 181 header->grh.traffic_class =
178 (be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 20) & 0xff; 182 (be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 20) & 0xff;
179 header->grh.flow_label = 183 header->grh.flow_label =
@@ -184,8 +188,6 @@ int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
184 &header->grh.source_gid); 188 &header->grh.source_gid);
185 memcpy(header->grh.destination_gid.raw, 189 memcpy(header->grh.destination_gid.raw,
186 ah->av->dgid, 16); 190 ah->av->dgid, 16);
187 } else {
188 header->grh_present = 0;
189 } 191 }
190 192
191 return 0; 193 return 0;
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 22ac72bc20c3..be1791be627b 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -606,7 +606,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm,
606 err = -EINVAL; 606 err = -EINVAL;
607 goto out; 607 goto out;
608 } 608 }
609 for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i) { 609 for (i = 0; i < mthca_icm_size(&iter) >> lg; ++i) {
610 if (virt != -1) { 610 if (virt != -1) {
611 pages[nent * 2] = cpu_to_be64(virt); 611 pages[nent * 2] = cpu_to_be64(virt);
612 virt += 1 << lg; 612 virt += 1 << lg;
@@ -727,8 +727,8 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status)
727 * system pages needed. 727 * system pages needed.
728 */ 728 */
729 dev->fw.arbel.fw_pages = 729 dev->fw.arbel.fw_pages =
730 (dev->fw.arbel.fw_pages + (1 << (PAGE_SHIFT - 12)) - 1) >> 730 ALIGN(dev->fw.arbel.fw_pages, PAGE_SIZE >> 12) >>
731 (PAGE_SHIFT - 12); 731 (PAGE_SHIFT - 12);
732 732
733 mthca_dbg(dev, "Clear int @ %llx, EQ arm @ %llx, EQ set CI @ %llx\n", 733 mthca_dbg(dev, "Clear int @ %llx, EQ arm @ %llx, EQ set CI @ %llx\n",
734 (unsigned long long) dev->fw.arbel.clr_int_base, 734 (unsigned long long) dev->fw.arbel.clr_int_base,
@@ -1445,6 +1445,7 @@ int mthca_SET_ICM_SIZE(struct mthca_dev *dev, u64 icm_size, u64 *aux_pages,
1445 * pages needed. 1445 * pages needed.
1446 */ 1446 */
1447 *aux_pages = (*aux_pages + (1 << (PAGE_SHIFT - 12)) - 1) >> (PAGE_SHIFT - 12); 1447 *aux_pages = (*aux_pages + (1 << (PAGE_SHIFT - 12)) - 1) >> (PAGE_SHIFT - 12);
1448 *aux_pages = ALIGN(*aux_pages, PAGE_SIZE >> 12) >> (PAGE_SHIFT - 12);
1448 1449
1449 return 0; 1450 return 0;
1450} 1451}
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index 795b379260bf..a104ab041ea3 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -520,6 +520,7 @@ int mthca_create_ah(struct mthca_dev *dev,
520int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah); 520int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah);
521int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah, 521int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
522 struct ib_ud_header *header); 522 struct ib_ud_header *header);
523int mthca_ah_grh_present(struct mthca_ah *ah);
523 524
524int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid); 525int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
525int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid); 526int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
index e8a948f087c0..2eabb27804cd 100644
--- a/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -45,6 +45,7 @@
45enum { 45enum {
46 MTHCA_NUM_ASYNC_EQE = 0x80, 46 MTHCA_NUM_ASYNC_EQE = 0x80,
47 MTHCA_NUM_CMD_EQE = 0x80, 47 MTHCA_NUM_CMD_EQE = 0x80,
48 MTHCA_NUM_SPARE_EQE = 0x80,
48 MTHCA_EQ_ENTRY_SIZE = 0x20 49 MTHCA_EQ_ENTRY_SIZE = 0x20
49}; 50};
50 51
@@ -277,11 +278,10 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq)
277{ 278{
278 struct mthca_eqe *eqe; 279 struct mthca_eqe *eqe;
279 int disarm_cqn; 280 int disarm_cqn;
280 int eqes_found = 0; 281 int eqes_found = 0;
282 int set_ci = 0;
281 283
282 while ((eqe = next_eqe_sw(eq))) { 284 while ((eqe = next_eqe_sw(eq))) {
283 int set_ci = 0;
284
285 /* 285 /*
286 * Make sure we read EQ entry contents after we've 286 * Make sure we read EQ entry contents after we've
287 * checked the ownership bit. 287 * checked the ownership bit.
@@ -345,12 +345,6 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq)
345 be16_to_cpu(eqe->event.cmd.token), 345 be16_to_cpu(eqe->event.cmd.token),
346 eqe->event.cmd.status, 346 eqe->event.cmd.status,
347 be64_to_cpu(eqe->event.cmd.out_param)); 347 be64_to_cpu(eqe->event.cmd.out_param));
348 /*
349 * cmd_event() may add more commands.
350 * The card will think the queue has overflowed if
351 * we don't tell it we've been processing events.
352 */
353 set_ci = 1;
354 break; 348 break;
355 349
356 case MTHCA_EVENT_TYPE_PORT_CHANGE: 350 case MTHCA_EVENT_TYPE_PORT_CHANGE:
@@ -385,8 +379,16 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq)
385 set_eqe_hw(eqe); 379 set_eqe_hw(eqe);
386 ++eq->cons_index; 380 ++eq->cons_index;
387 eqes_found = 1; 381 eqes_found = 1;
382 ++set_ci;
388 383
389 if (unlikely(set_ci)) { 384 /*
385 * The HCA will think the queue has overflowed if we
386 * don't tell it we've been processing events. We
387 * create our EQs with MTHCA_NUM_SPARE_EQE extra
388 * entries, so we must update our consumer index at
389 * least that often.
390 */
391 if (unlikely(set_ci >= MTHCA_NUM_SPARE_EQE)) {
390 /* 392 /*
391 * Conditional on hca_type is OK here because 393 * Conditional on hca_type is OK here because
392 * this is a rare case, not the fast path. 394 * this is a rare case, not the fast path.
@@ -862,19 +864,19 @@ int __devinit mthca_init_eq_table(struct mthca_dev *dev)
862 intr = (dev->mthca_flags & MTHCA_FLAG_MSI) ? 864 intr = (dev->mthca_flags & MTHCA_FLAG_MSI) ?
863 128 : dev->eq_table.inta_pin; 865 128 : dev->eq_table.inta_pin;
864 866
865 err = mthca_create_eq(dev, dev->limits.num_cqs, 867 err = mthca_create_eq(dev, dev->limits.num_cqs + MTHCA_NUM_SPARE_EQE,
866 (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 128 : intr, 868 (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 128 : intr,
867 &dev->eq_table.eq[MTHCA_EQ_COMP]); 869 &dev->eq_table.eq[MTHCA_EQ_COMP]);
868 if (err) 870 if (err)
869 goto err_out_unmap; 871 goto err_out_unmap;
870 872
871 err = mthca_create_eq(dev, MTHCA_NUM_ASYNC_EQE, 873 err = mthca_create_eq(dev, MTHCA_NUM_ASYNC_EQE + MTHCA_NUM_SPARE_EQE,
872 (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 129 : intr, 874 (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 129 : intr,
873 &dev->eq_table.eq[MTHCA_EQ_ASYNC]); 875 &dev->eq_table.eq[MTHCA_EQ_ASYNC]);
874 if (err) 876 if (err)
875 goto err_out_comp; 877 goto err_out_comp;
876 878
877 err = mthca_create_eq(dev, MTHCA_NUM_CMD_EQE, 879 err = mthca_create_eq(dev, MTHCA_NUM_CMD_EQE + MTHCA_NUM_SPARE_EQE,
878 (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 130 : intr, 880 (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 130 : intr,
879 &dev->eq_table.eq[MTHCA_EQ_CMD]); 881 &dev->eq_table.eq[MTHCA_EQ_CMD]);
880 if (err) 882 if (err)
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 4cc7e2846df1..484a7e6b7f8c 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -33,7 +33,7 @@
33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 * SOFTWARE. 34 * SOFTWARE.
35 * 35 *
36 * $Id: mthca_provider.c 1397 2004-12-28 05:09:00Z roland $ 36 * $Id: mthca_provider.c 4859 2006-01-09 21:55:10Z roland $
37 */ 37 */
38 38
39#include <rdma/ib_smi.h> 39#include <rdma/ib_smi.h>
@@ -45,6 +45,14 @@
45#include "mthca_user.h" 45#include "mthca_user.h"
46#include "mthca_memfree.h" 46#include "mthca_memfree.h"
47 47
48static void init_query_mad(struct ib_smp *mad)
49{
50 mad->base_version = 1;
51 mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
52 mad->class_version = 1;
53 mad->method = IB_MGMT_METHOD_GET;
54}
55
48static int mthca_query_device(struct ib_device *ibdev, 56static int mthca_query_device(struct ib_device *ibdev,
49 struct ib_device_attr *props) 57 struct ib_device_attr *props)
50{ 58{
@@ -55,7 +63,7 @@ static int mthca_query_device(struct ib_device *ibdev,
55 63
56 u8 status; 64 u8 status;
57 65
58 in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); 66 in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
59 out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); 67 out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
60 if (!in_mad || !out_mad) 68 if (!in_mad || !out_mad)
61 goto out; 69 goto out;
@@ -64,12 +72,8 @@ static int mthca_query_device(struct ib_device *ibdev,
64 72
65 props->fw_ver = mdev->fw_ver; 73 props->fw_ver = mdev->fw_ver;
66 74
67 memset(in_mad, 0, sizeof *in_mad); 75 init_query_mad(in_mad);
68 in_mad->base_version = 1; 76 in_mad->attr_id = IB_SMP_ATTR_NODE_INFO;
69 in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
70 in_mad->class_version = 1;
71 in_mad->method = IB_MGMT_METHOD_GET;
72 in_mad->attr_id = IB_SMP_ATTR_NODE_INFO;
73 77
74 err = mthca_MAD_IFC(mdev, 1, 1, 78 err = mthca_MAD_IFC(mdev, 1, 1,
75 1, NULL, NULL, in_mad, out_mad, 79 1, NULL, NULL, in_mad, out_mad,
@@ -87,7 +91,6 @@ static int mthca_query_device(struct ib_device *ibdev,
87 props->vendor_part_id = be16_to_cpup((__be16 *) (out_mad->data + 30)); 91 props->vendor_part_id = be16_to_cpup((__be16 *) (out_mad->data + 30));
88 props->hw_ver = be32_to_cpup((__be32 *) (out_mad->data + 32)); 92 props->hw_ver = be32_to_cpup((__be32 *) (out_mad->data + 32));
89 memcpy(&props->sys_image_guid, out_mad->data + 4, 8); 93 memcpy(&props->sys_image_guid, out_mad->data + 4, 8);
90 memcpy(&props->node_guid, out_mad->data + 12, 8);
91 94
92 props->max_mr_size = ~0ull; 95 props->max_mr_size = ~0ull;
93 props->page_size_cap = mdev->limits.page_size_cap; 96 props->page_size_cap = mdev->limits.page_size_cap;
@@ -128,20 +131,16 @@ static int mthca_query_port(struct ib_device *ibdev,
128 int err = -ENOMEM; 131 int err = -ENOMEM;
129 u8 status; 132 u8 status;
130 133
131 in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); 134 in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
132 out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); 135 out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
133 if (!in_mad || !out_mad) 136 if (!in_mad || !out_mad)
134 goto out; 137 goto out;
135 138
136 memset(props, 0, sizeof *props); 139 memset(props, 0, sizeof *props);
137 140
138 memset(in_mad, 0, sizeof *in_mad); 141 init_query_mad(in_mad);
139 in_mad->base_version = 1; 142 in_mad->attr_id = IB_SMP_ATTR_PORT_INFO;
140 in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; 143 in_mad->attr_mod = cpu_to_be32(port);
141 in_mad->class_version = 1;
142 in_mad->method = IB_MGMT_METHOD_GET;
143 in_mad->attr_id = IB_SMP_ATTR_PORT_INFO;
144 in_mad->attr_mod = cpu_to_be32(port);
145 144
146 err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1, 145 err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
147 port, NULL, NULL, in_mad, out_mad, 146 port, NULL, NULL, in_mad, out_mad,
@@ -220,18 +219,14 @@ static int mthca_query_pkey(struct ib_device *ibdev,
220 int err = -ENOMEM; 219 int err = -ENOMEM;
221 u8 status; 220 u8 status;
222 221
223 in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); 222 in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
224 out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); 223 out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
225 if (!in_mad || !out_mad) 224 if (!in_mad || !out_mad)
226 goto out; 225 goto out;
227 226
228 memset(in_mad, 0, sizeof *in_mad); 227 init_query_mad(in_mad);
229 in_mad->base_version = 1; 228 in_mad->attr_id = IB_SMP_ATTR_PKEY_TABLE;
230 in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; 229 in_mad->attr_mod = cpu_to_be32(index / 32);
231 in_mad->class_version = 1;
232 in_mad->method = IB_MGMT_METHOD_GET;
233 in_mad->attr_id = IB_SMP_ATTR_PKEY_TABLE;
234 in_mad->attr_mod = cpu_to_be32(index / 32);
235 230
236 err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1, 231 err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
237 port, NULL, NULL, in_mad, out_mad, 232 port, NULL, NULL, in_mad, out_mad,
@@ -259,18 +254,14 @@ static int mthca_query_gid(struct ib_device *ibdev, u8 port,
259 int err = -ENOMEM; 254 int err = -ENOMEM;
260 u8 status; 255 u8 status;
261 256
262 in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); 257 in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
263 out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); 258 out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
264 if (!in_mad || !out_mad) 259 if (!in_mad || !out_mad)
265 goto out; 260 goto out;
266 261
267 memset(in_mad, 0, sizeof *in_mad); 262 init_query_mad(in_mad);
268 in_mad->base_version = 1; 263 in_mad->attr_id = IB_SMP_ATTR_PORT_INFO;
269 in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; 264 in_mad->attr_mod = cpu_to_be32(port);
270 in_mad->class_version = 1;
271 in_mad->method = IB_MGMT_METHOD_GET;
272 in_mad->attr_id = IB_SMP_ATTR_PORT_INFO;
273 in_mad->attr_mod = cpu_to_be32(port);
274 265
275 err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1, 266 err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
276 port, NULL, NULL, in_mad, out_mad, 267 port, NULL, NULL, in_mad, out_mad,
@@ -284,13 +275,9 @@ static int mthca_query_gid(struct ib_device *ibdev, u8 port,
284 275
285 memcpy(gid->raw, out_mad->data + 8, 8); 276 memcpy(gid->raw, out_mad->data + 8, 8);
286 277
287 memset(in_mad, 0, sizeof *in_mad); 278 init_query_mad(in_mad);
288 in_mad->base_version = 1; 279 in_mad->attr_id = IB_SMP_ATTR_GUID_INFO;
289 in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; 280 in_mad->attr_mod = cpu_to_be32(index / 8);
290 in_mad->class_version = 1;
291 in_mad->method = IB_MGMT_METHOD_GET;
292 in_mad->attr_id = IB_SMP_ATTR_GUID_INFO;
293 in_mad->attr_mod = cpu_to_be32(index / 8);
294 281
295 err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1, 282 err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
296 port, NULL, NULL, in_mad, out_mad, 283 port, NULL, NULL, in_mad, out_mad,
@@ -458,8 +445,10 @@ static struct ib_srq *mthca_create_srq(struct ib_pd *pd,
458 if (pd->uobject) { 445 if (pd->uobject) {
459 context = to_mucontext(pd->uobject->context); 446 context = to_mucontext(pd->uobject->context);
460 447
461 if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) 448 if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) {
462 return ERR_PTR(-EFAULT); 449 err = -EFAULT;
450 goto err_free;
451 }
463 452
464 err = mthca_map_user_db(to_mdev(pd->device), &context->uar, 453 err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
465 context->db_tab, ucmd.db_index, 454 context->db_tab, ucmd.db_index,
@@ -535,8 +524,10 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
535 if (pd->uobject) { 524 if (pd->uobject) {
536 context = to_mucontext(pd->uobject->context); 525 context = to_mucontext(pd->uobject->context);
537 526
538 if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) 527 if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) {
528 kfree(qp);
539 return ERR_PTR(-EFAULT); 529 return ERR_PTR(-EFAULT);
530 }
540 531
541 err = mthca_map_user_db(to_mdev(pd->device), &context->uar, 532 err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
542 context->db_tab, 533 context->db_tab,
@@ -783,24 +774,20 @@ static struct ib_mr *mthca_reg_phys_mr(struct ib_pd *pd,
783 if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK)) 774 if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK))
784 return ERR_PTR(-EINVAL); 775 return ERR_PTR(-EINVAL);
785 776
786 if (num_phys_buf > 1 &&
787 ((buffer_list[0].addr + buffer_list[0].size) & ~PAGE_MASK))
788 return ERR_PTR(-EINVAL);
789
790 mask = 0; 777 mask = 0;
791 total_size = 0; 778 total_size = 0;
792 for (i = 0; i < num_phys_buf; ++i) { 779 for (i = 0; i < num_phys_buf; ++i) {
793 if (i != 0 && buffer_list[i].addr & ~PAGE_MASK) 780 if (i != 0)
794 return ERR_PTR(-EINVAL); 781 mask |= buffer_list[i].addr;
795 if (i != 0 && i != num_phys_buf - 1 && 782 if (i != num_phys_buf - 1)
796 (buffer_list[i].size & ~PAGE_MASK)) 783 mask |= buffer_list[i].addr + buffer_list[i].size;
797 return ERR_PTR(-EINVAL);
798 784
799 total_size += buffer_list[i].size; 785 total_size += buffer_list[i].size;
800 if (i > 0)
801 mask |= buffer_list[i].addr;
802 } 786 }
803 787
788 if (mask & ~PAGE_MASK)
789 return ERR_PTR(-EINVAL);
790
804 /* Find largest page shift we can use to cover buffers */ 791 /* Find largest page shift we can use to cover buffers */
805 for (shift = PAGE_SHIFT; shift < 31; ++shift) 792 for (shift = PAGE_SHIFT; shift < 31; ++shift)
806 if (num_phys_buf > 1) { 793 if (num_phys_buf > 1) {
@@ -1070,11 +1057,48 @@ static struct class_device_attribute *mthca_class_attributes[] = {
1070 &class_device_attr_board_id 1057 &class_device_attr_board_id
1071}; 1058};
1072 1059
1060static int mthca_init_node_data(struct mthca_dev *dev)
1061{
1062 struct ib_smp *in_mad = NULL;
1063 struct ib_smp *out_mad = NULL;
1064 int err = -ENOMEM;
1065 u8 status;
1066
1067 in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
1068 out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
1069 if (!in_mad || !out_mad)
1070 goto out;
1071
1072 init_query_mad(in_mad);
1073 in_mad->attr_id = IB_SMP_ATTR_NODE_INFO;
1074
1075 err = mthca_MAD_IFC(dev, 1, 1,
1076 1, NULL, NULL, in_mad, out_mad,
1077 &status);
1078 if (err)
1079 goto out;
1080 if (status) {
1081 err = -EINVAL;
1082 goto out;
1083 }
1084
1085 memcpy(&dev->ib_dev.node_guid, out_mad->data + 12, 8);
1086
1087out:
1088 kfree(in_mad);
1089 kfree(out_mad);
1090 return err;
1091}
1092
1073int mthca_register_device(struct mthca_dev *dev) 1093int mthca_register_device(struct mthca_dev *dev)
1074{ 1094{
1075 int ret; 1095 int ret;
1076 int i; 1096 int i;
1077 1097
1098 ret = mthca_init_node_data(dev);
1099 if (ret)
1100 return ret;
1101
1078 strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX); 1102 strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX);
1079 dev->ib_dev.owner = THIS_MODULE; 1103 dev->ib_dev.owner = THIS_MODULE;
1080 1104
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 564b6d51c394..fba608ed7df2 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -1434,7 +1434,7 @@ static int build_mlx_header(struct mthca_dev *dev, struct mthca_sqp *sqp,
1434 u16 pkey; 1434 u16 pkey;
1435 1435
1436 ib_ud_header_init(256, /* assume a MAD */ 1436 ib_ud_header_init(256, /* assume a MAD */
1437 sqp->ud_header.grh_present, 1437 mthca_ah_grh_present(to_mah(wr->wr.ud.ah)),
1438 &sqp->ud_header); 1438 &sqp->ud_header);
1439 1439
1440 err = mthca_read_ah(dev, to_mah(wr->wr.ud.ah), &sqp->ud_header); 1440 err = mthca_read_ah(dev, to_mah(wr->wr.ud.ah), &sqp->ud_header);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 9923a15a9996..e0a5412b7e68 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -45,11 +45,11 @@
45#include <linux/config.h> 45#include <linux/config.h>
46#include <linux/kref.h> 46#include <linux/kref.h>
47#include <linux/if_infiniband.h> 47#include <linux/if_infiniband.h>
48#include <linux/mutex.h>
48 49
49#include <net/neighbour.h> 50#include <net/neighbour.h>
50 51
51#include <asm/atomic.h> 52#include <asm/atomic.h>
52#include <asm/semaphore.h>
53 53
54#include <rdma/ib_verbs.h> 54#include <rdma/ib_verbs.h>
55#include <rdma/ib_pack.h> 55#include <rdma/ib_pack.h>
@@ -123,8 +123,8 @@ struct ipoib_dev_priv {
123 123
124 unsigned long flags; 124 unsigned long flags;
125 125
126 struct semaphore mcast_mutex; 126 struct mutex mcast_mutex;
127 struct semaphore vlan_mutex; 127 struct mutex vlan_mutex;
128 128
129 struct rb_root path_tree; 129 struct rb_root path_tree;
130 struct list_head path_list; 130 struct list_head path_list;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 23885801b6d2..86bcdd72a107 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -52,7 +52,7 @@ MODULE_PARM_DESC(data_debug_level,
52 52
53#define IPOIB_OP_RECV (1ul << 31) 53#define IPOIB_OP_RECV (1ul << 31)
54 54
55static DECLARE_MUTEX(pkey_sem); 55static DEFINE_MUTEX(pkey_mutex);
56 56
57struct ipoib_ah *ipoib_create_ah(struct net_device *dev, 57struct ipoib_ah *ipoib_create_ah(struct net_device *dev,
58 struct ib_pd *pd, struct ib_ah_attr *attr) 58 struct ib_pd *pd, struct ib_ah_attr *attr)
@@ -445,25 +445,16 @@ int ipoib_ib_dev_down(struct net_device *dev)
445 445
446 /* Shutdown the P_Key thread if still active */ 446 /* Shutdown the P_Key thread if still active */
447 if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { 447 if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) {
448 down(&pkey_sem); 448 mutex_lock(&pkey_mutex);
449 set_bit(IPOIB_PKEY_STOP, &priv->flags); 449 set_bit(IPOIB_PKEY_STOP, &priv->flags);
450 cancel_delayed_work(&priv->pkey_task); 450 cancel_delayed_work(&priv->pkey_task);
451 up(&pkey_sem); 451 mutex_unlock(&pkey_mutex);
452 flush_workqueue(ipoib_workqueue); 452 flush_workqueue(ipoib_workqueue);
453 } 453 }
454 454
455 ipoib_mcast_stop_thread(dev, 1); 455 ipoib_mcast_stop_thread(dev, 1);
456
457 /*
458 * Flush the multicast groups first so we stop any multicast joins. The
459 * completion thread may have already died and we may deadlock waiting
460 * for the completion thread to finish some multicast joins.
461 */
462 ipoib_mcast_dev_flush(dev); 456 ipoib_mcast_dev_flush(dev);
463 457
464 /* Delete broadcast and local addresses since they will be recreated */
465 ipoib_mcast_dev_down(dev);
466
467 ipoib_flush_paths(dev); 458 ipoib_flush_paths(dev);
468 459
469 return 0; 460 return 0;
@@ -608,13 +599,13 @@ void ipoib_ib_dev_flush(void *_dev)
608 if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) 599 if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
609 ipoib_ib_dev_up(dev); 600 ipoib_ib_dev_up(dev);
610 601
611 down(&priv->vlan_mutex); 602 mutex_lock(&priv->vlan_mutex);
612 603
613 /* Flush any child interfaces too */ 604 /* Flush any child interfaces too */
614 list_for_each_entry(cpriv, &priv->child_intfs, list) 605 list_for_each_entry(cpriv, &priv->child_intfs, list)
615 ipoib_ib_dev_flush(&cpriv->dev); 606 ipoib_ib_dev_flush(&cpriv->dev);
616 607
617 up(&priv->vlan_mutex); 608 mutex_unlock(&priv->vlan_mutex);
618} 609}
619 610
620void ipoib_ib_dev_cleanup(struct net_device *dev) 611void ipoib_ib_dev_cleanup(struct net_device *dev)
@@ -624,9 +615,7 @@ void ipoib_ib_dev_cleanup(struct net_device *dev)
624 ipoib_dbg(priv, "cleaning up ib_dev\n"); 615 ipoib_dbg(priv, "cleaning up ib_dev\n");
625 616
626 ipoib_mcast_stop_thread(dev, 1); 617 ipoib_mcast_stop_thread(dev, 1);
627 618 ipoib_mcast_dev_flush(dev);
628 /* Delete the broadcast address and the local address */
629 ipoib_mcast_dev_down(dev);
630 619
631 ipoib_transport_dev_cleanup(dev); 620 ipoib_transport_dev_cleanup(dev);
632} 621}
@@ -662,12 +651,12 @@ void ipoib_pkey_poll(void *dev_ptr)
662 if (test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) 651 if (test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags))
663 ipoib_open(dev); 652 ipoib_open(dev);
664 else { 653 else {
665 down(&pkey_sem); 654 mutex_lock(&pkey_mutex);
666 if (!test_bit(IPOIB_PKEY_STOP, &priv->flags)) 655 if (!test_bit(IPOIB_PKEY_STOP, &priv->flags))
667 queue_delayed_work(ipoib_workqueue, 656 queue_delayed_work(ipoib_workqueue,
668 &priv->pkey_task, 657 &priv->pkey_task,
669 HZ); 658 HZ);
670 up(&pkey_sem); 659 mutex_unlock(&pkey_mutex);
671 } 660 }
672} 661}
673 662
@@ -681,12 +670,12 @@ int ipoib_pkey_dev_delay_open(struct net_device *dev)
681 670
682 /* P_Key value not assigned yet - start polling */ 671 /* P_Key value not assigned yet - start polling */
683 if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { 672 if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) {
684 down(&pkey_sem); 673 mutex_lock(&pkey_mutex);
685 clear_bit(IPOIB_PKEY_STOP, &priv->flags); 674 clear_bit(IPOIB_PKEY_STOP, &priv->flags);
686 queue_delayed_work(ipoib_workqueue, 675 queue_delayed_work(ipoib_workqueue,
687 &priv->pkey_task, 676 &priv->pkey_task,
688 HZ); 677 HZ);
689 up(&pkey_sem); 678 mutex_unlock(&pkey_mutex);
690 return 1; 679 return 1;
691 } 680 }
692 681
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 780009c7eaa6..fd3f5c862a5d 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -105,7 +105,7 @@ int ipoib_open(struct net_device *dev)
105 struct ipoib_dev_priv *cpriv; 105 struct ipoib_dev_priv *cpriv;
106 106
107 /* Bring up any child interfaces too */ 107 /* Bring up any child interfaces too */
108 down(&priv->vlan_mutex); 108 mutex_lock(&priv->vlan_mutex);
109 list_for_each_entry(cpriv, &priv->child_intfs, list) { 109 list_for_each_entry(cpriv, &priv->child_intfs, list) {
110 int flags; 110 int flags;
111 111
@@ -115,7 +115,7 @@ int ipoib_open(struct net_device *dev)
115 115
116 dev_change_flags(cpriv->dev, flags | IFF_UP); 116 dev_change_flags(cpriv->dev, flags | IFF_UP);
117 } 117 }
118 up(&priv->vlan_mutex); 118 mutex_unlock(&priv->vlan_mutex);
119 } 119 }
120 120
121 netif_start_queue(dev); 121 netif_start_queue(dev);
@@ -140,7 +140,7 @@ static int ipoib_stop(struct net_device *dev)
140 struct ipoib_dev_priv *cpriv; 140 struct ipoib_dev_priv *cpriv;
141 141
142 /* Bring down any child interfaces too */ 142 /* Bring down any child interfaces too */
143 down(&priv->vlan_mutex); 143 mutex_lock(&priv->vlan_mutex);
144 list_for_each_entry(cpriv, &priv->child_intfs, list) { 144 list_for_each_entry(cpriv, &priv->child_intfs, list) {
145 int flags; 145 int flags;
146 146
@@ -150,7 +150,7 @@ static int ipoib_stop(struct net_device *dev)
150 150
151 dev_change_flags(cpriv->dev, flags & ~IFF_UP); 151 dev_change_flags(cpriv->dev, flags & ~IFF_UP);
152 } 152 }
153 up(&priv->vlan_mutex); 153 mutex_unlock(&priv->vlan_mutex);
154 } 154 }
155 155
156 return 0; 156 return 0;
@@ -892,8 +892,8 @@ static void ipoib_setup(struct net_device *dev)
892 spin_lock_init(&priv->lock); 892 spin_lock_init(&priv->lock);
893 spin_lock_init(&priv->tx_lock); 893 spin_lock_init(&priv->tx_lock);
894 894
895 init_MUTEX(&priv->mcast_mutex); 895 mutex_init(&priv->mcast_mutex);
896 init_MUTEX(&priv->vlan_mutex); 896 mutex_init(&priv->vlan_mutex);
897 897
898 INIT_LIST_HEAD(&priv->path_list); 898 INIT_LIST_HEAD(&priv->path_list);
899 INIT_LIST_HEAD(&priv->child_intfs); 899 INIT_LIST_HEAD(&priv->child_intfs);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index ed0c2ead8bc1..98039da0caf0 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -55,7 +55,7 @@ MODULE_PARM_DESC(mcast_debug_level,
55 "Enable multicast debug tracing if > 0"); 55 "Enable multicast debug tracing if > 0");
56#endif 56#endif
57 57
58static DECLARE_MUTEX(mcast_mutex); 58static DEFINE_MUTEX(mcast_mutex);
59 59
60/* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */ 60/* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */
61struct ipoib_mcast { 61struct ipoib_mcast {
@@ -97,8 +97,6 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
97 struct ipoib_dev_priv *priv = netdev_priv(dev); 97 struct ipoib_dev_priv *priv = netdev_priv(dev);
98 struct ipoib_neigh *neigh, *tmp; 98 struct ipoib_neigh *neigh, *tmp;
99 unsigned long flags; 99 unsigned long flags;
100 LIST_HEAD(ah_list);
101 struct ipoib_ah *ah, *tah;
102 100
103 ipoib_dbg_mcast(netdev_priv(dev), 101 ipoib_dbg_mcast(netdev_priv(dev),
104 "deleting multicast group " IPOIB_GID_FMT "\n", 102 "deleting multicast group " IPOIB_GID_FMT "\n",
@@ -107,8 +105,14 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
107 spin_lock_irqsave(&priv->lock, flags); 105 spin_lock_irqsave(&priv->lock, flags);
108 106
109 list_for_each_entry_safe(neigh, tmp, &mcast->neigh_list, list) { 107 list_for_each_entry_safe(neigh, tmp, &mcast->neigh_list, list) {
108 /*
109 * It's safe to call ipoib_put_ah() inside priv->lock
110 * here, because we know that mcast->ah will always
111 * hold one more reference, so ipoib_put_ah() will
112 * never do more than decrement the ref count.
113 */
110 if (neigh->ah) 114 if (neigh->ah)
111 list_add_tail(&neigh->ah->list, &ah_list); 115 ipoib_put_ah(neigh->ah);
112 *to_ipoib_neigh(neigh->neighbour) = NULL; 116 *to_ipoib_neigh(neigh->neighbour) = NULL;
113 neigh->neighbour->ops->destructor = NULL; 117 neigh->neighbour->ops->destructor = NULL;
114 kfree(neigh); 118 kfree(neigh);
@@ -116,9 +120,6 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
116 120
117 spin_unlock_irqrestore(&priv->lock, flags); 121 spin_unlock_irqrestore(&priv->lock, flags);
118 122
119 list_for_each_entry_safe(ah, tah, &ah_list, list)
120 ipoib_put_ah(ah);
121
122 if (mcast->ah) 123 if (mcast->ah)
123 ipoib_put_ah(mcast->ah); 124 ipoib_put_ah(mcast->ah);
124 125
@@ -384,10 +385,10 @@ static void ipoib_mcast_join_complete(int status,
384 385
385 if (!status && !ipoib_mcast_join_finish(mcast, mcmember)) { 386 if (!status && !ipoib_mcast_join_finish(mcast, mcmember)) {
386 mcast->backoff = 1; 387 mcast->backoff = 1;
387 down(&mcast_mutex); 388 mutex_lock(&mcast_mutex);
388 if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) 389 if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
389 queue_work(ipoib_workqueue, &priv->mcast_task); 390 queue_work(ipoib_workqueue, &priv->mcast_task);
390 up(&mcast_mutex); 391 mutex_unlock(&mcast_mutex);
391 complete(&mcast->done); 392 complete(&mcast->done);
392 return; 393 return;
393 } 394 }
@@ -417,7 +418,7 @@ static void ipoib_mcast_join_complete(int status,
417 418
418 mcast->query = NULL; 419 mcast->query = NULL;
419 420
420 down(&mcast_mutex); 421 mutex_lock(&mcast_mutex);
421 if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) { 422 if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) {
422 if (status == -ETIMEDOUT) 423 if (status == -ETIMEDOUT)
423 queue_work(ipoib_workqueue, &priv->mcast_task); 424 queue_work(ipoib_workqueue, &priv->mcast_task);
@@ -426,7 +427,7 @@ static void ipoib_mcast_join_complete(int status,
426 mcast->backoff * HZ); 427 mcast->backoff * HZ);
427 } else 428 } else
428 complete(&mcast->done); 429 complete(&mcast->done);
429 up(&mcast_mutex); 430 mutex_unlock(&mcast_mutex);
430 431
431 return; 432 return;
432} 433}
@@ -481,12 +482,12 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast,
481 if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS) 482 if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS)
482 mcast->backoff = IPOIB_MAX_BACKOFF_SECONDS; 483 mcast->backoff = IPOIB_MAX_BACKOFF_SECONDS;
483 484
484 down(&mcast_mutex); 485 mutex_lock(&mcast_mutex);
485 if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) 486 if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
486 queue_delayed_work(ipoib_workqueue, 487 queue_delayed_work(ipoib_workqueue,
487 &priv->mcast_task, 488 &priv->mcast_task,
488 mcast->backoff * HZ); 489 mcast->backoff * HZ);
489 up(&mcast_mutex); 490 mutex_unlock(&mcast_mutex);
490 } else 491 } else
491 mcast->query_id = ret; 492 mcast->query_id = ret;
492} 493}
@@ -519,11 +520,11 @@ void ipoib_mcast_join_task(void *dev_ptr)
519 priv->broadcast = ipoib_mcast_alloc(dev, 1); 520 priv->broadcast = ipoib_mcast_alloc(dev, 1);
520 if (!priv->broadcast) { 521 if (!priv->broadcast) {
521 ipoib_warn(priv, "failed to allocate broadcast group\n"); 522 ipoib_warn(priv, "failed to allocate broadcast group\n");
522 down(&mcast_mutex); 523 mutex_lock(&mcast_mutex);
523 if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) 524 if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
524 queue_delayed_work(ipoib_workqueue, 525 queue_delayed_work(ipoib_workqueue,
525 &priv->mcast_task, HZ); 526 &priv->mcast_task, HZ);
526 up(&mcast_mutex); 527 mutex_unlock(&mcast_mutex);
527 return; 528 return;
528 } 529 }
529 530
@@ -579,10 +580,10 @@ int ipoib_mcast_start_thread(struct net_device *dev)
579 580
580 ipoib_dbg_mcast(priv, "starting multicast thread\n"); 581 ipoib_dbg_mcast(priv, "starting multicast thread\n");
581 582
582 down(&mcast_mutex); 583 mutex_lock(&mcast_mutex);
583 if (!test_and_set_bit(IPOIB_MCAST_RUN, &priv->flags)) 584 if (!test_and_set_bit(IPOIB_MCAST_RUN, &priv->flags))
584 queue_work(ipoib_workqueue, &priv->mcast_task); 585 queue_work(ipoib_workqueue, &priv->mcast_task);
585 up(&mcast_mutex); 586 mutex_unlock(&mcast_mutex);
586 587
587 return 0; 588 return 0;
588} 589}
@@ -594,10 +595,10 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
594 595
595 ipoib_dbg_mcast(priv, "stopping multicast thread\n"); 596 ipoib_dbg_mcast(priv, "stopping multicast thread\n");
596 597
597 down(&mcast_mutex); 598 mutex_lock(&mcast_mutex);
598 clear_bit(IPOIB_MCAST_RUN, &priv->flags); 599 clear_bit(IPOIB_MCAST_RUN, &priv->flags);
599 cancel_delayed_work(&priv->mcast_task); 600 cancel_delayed_work(&priv->mcast_task);
600 up(&mcast_mutex); 601 mutex_unlock(&mcast_mutex);
601 602
602 if (flush) 603 if (flush)
603 flush_workqueue(ipoib_workqueue); 604 flush_workqueue(ipoib_workqueue);
@@ -741,48 +742,23 @@ void ipoib_mcast_dev_flush(struct net_device *dev)
741{ 742{
742 struct ipoib_dev_priv *priv = netdev_priv(dev); 743 struct ipoib_dev_priv *priv = netdev_priv(dev);
743 LIST_HEAD(remove_list); 744 LIST_HEAD(remove_list);
744 struct ipoib_mcast *mcast, *tmcast, *nmcast; 745 struct ipoib_mcast *mcast, *tmcast;
745 unsigned long flags; 746 unsigned long flags;
746 747
747 ipoib_dbg_mcast(priv, "flushing multicast list\n"); 748 ipoib_dbg_mcast(priv, "flushing multicast list\n");
748 749
749 spin_lock_irqsave(&priv->lock, flags); 750 spin_lock_irqsave(&priv->lock, flags);
750 list_for_each_entry_safe(mcast, tmcast, &priv->multicast_list, list) {
751 nmcast = ipoib_mcast_alloc(dev, 0);
752 if (nmcast) {
753 nmcast->flags =
754 mcast->flags & (1 << IPOIB_MCAST_FLAG_SENDONLY);
755 751
756 nmcast->mcmember.mgid = mcast->mcmember.mgid; 752 list_for_each_entry_safe(mcast, tmcast, &priv->multicast_list, list) {
757 753 list_del(&mcast->list);
758 /* Add the new group in before the to-be-destroyed group */ 754 rb_erase(&mcast->rb_node, &priv->multicast_tree);
759 list_add_tail(&nmcast->list, &mcast->list); 755 list_add_tail(&mcast->list, &remove_list);
760 list_del_init(&mcast->list);
761
762 rb_replace_node(&mcast->rb_node, &nmcast->rb_node,
763 &priv->multicast_tree);
764
765 list_add_tail(&mcast->list, &remove_list);
766 } else {
767 ipoib_warn(priv, "could not reallocate multicast group "
768 IPOIB_GID_FMT "\n",
769 IPOIB_GID_ARG(mcast->mcmember.mgid));
770 }
771 } 756 }
772 757
773 if (priv->broadcast) { 758 if (priv->broadcast) {
774 nmcast = ipoib_mcast_alloc(dev, 0); 759 rb_erase(&priv->broadcast->rb_node, &priv->multicast_tree);
775 if (nmcast) { 760 list_add_tail(&priv->broadcast->list, &remove_list);
776 nmcast->mcmember.mgid = priv->broadcast->mcmember.mgid; 761 priv->broadcast = NULL;
777
778 rb_replace_node(&priv->broadcast->rb_node,
779 &nmcast->rb_node,
780 &priv->multicast_tree);
781
782 list_add_tail(&priv->broadcast->list, &remove_list);
783 }
784
785 priv->broadcast = nmcast;
786 } 762 }
787 763
788 spin_unlock_irqrestore(&priv->lock, flags); 764 spin_unlock_irqrestore(&priv->lock, flags);
@@ -793,24 +769,6 @@ void ipoib_mcast_dev_flush(struct net_device *dev)
793 } 769 }
794} 770}
795 771
796void ipoib_mcast_dev_down(struct net_device *dev)
797{
798 struct ipoib_dev_priv *priv = netdev_priv(dev);
799 unsigned long flags;
800
801 /* Delete broadcast since it will be recreated */
802 if (priv->broadcast) {
803 ipoib_dbg_mcast(priv, "deleting broadcast group\n");
804
805 spin_lock_irqsave(&priv->lock, flags);
806 rb_erase(&priv->broadcast->rb_node, &priv->multicast_tree);
807 spin_unlock_irqrestore(&priv->lock, flags);
808 ipoib_mcast_leave(dev, priv->broadcast);
809 ipoib_mcast_free(priv->broadcast);
810 priv->broadcast = NULL;
811 }
812}
813
814void ipoib_mcast_restart_task(void *dev_ptr) 772void ipoib_mcast_restart_task(void *dev_ptr)
815{ 773{
816 struct net_device *dev = dev_ptr; 774 struct net_device *dev = dev_ptr;
@@ -824,7 +782,8 @@ void ipoib_mcast_restart_task(void *dev_ptr)
824 782
825 ipoib_mcast_stop_thread(dev, 0); 783 ipoib_mcast_stop_thread(dev, 0);
826 784
827 spin_lock_irqsave(&priv->lock, flags); 785 spin_lock_irqsave(&dev->xmit_lock, flags);
786 spin_lock(&priv->lock);
828 787
829 /* 788 /*
830 * Unfortunately, the networking core only gives us a list of all of 789 * Unfortunately, the networking core only gives us a list of all of
@@ -896,7 +855,9 @@ void ipoib_mcast_restart_task(void *dev_ptr)
896 list_add_tail(&mcast->list, &remove_list); 855 list_add_tail(&mcast->list, &remove_list);
897 } 856 }
898 } 857 }
899 spin_unlock_irqrestore(&priv->lock, flags); 858
859 spin_unlock(&priv->lock);
860 spin_unlock_irqrestore(&dev->xmit_lock, flags);
900 861
901 /* We have to cancel outside of the spinlock */ 862 /* We have to cancel outside of the spinlock */
902 list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { 863 list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
index e829e10400e3..faaf10e5fc7b 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
@@ -65,9 +65,9 @@ int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid)
65 } 65 }
66 66
67 /* attach QP to multicast group */ 67 /* attach QP to multicast group */
68 down(&priv->mcast_mutex); 68 mutex_lock(&priv->mcast_mutex);
69 ret = ib_attach_mcast(priv->qp, mgid, mlid); 69 ret = ib_attach_mcast(priv->qp, mgid, mlid);
70 up(&priv->mcast_mutex); 70 mutex_unlock(&priv->mcast_mutex);
71 if (ret) 71 if (ret)
72 ipoib_warn(priv, "failed to attach to multicast group, ret = %d\n", ret); 72 ipoib_warn(priv, "failed to attach to multicast group, ret = %d\n", ret);
73 73
@@ -81,9 +81,9 @@ int ipoib_mcast_detach(struct net_device *dev, u16 mlid, union ib_gid *mgid)
81 struct ipoib_dev_priv *priv = netdev_priv(dev); 81 struct ipoib_dev_priv *priv = netdev_priv(dev);
82 int ret; 82 int ret;
83 83
84 down(&priv->mcast_mutex); 84 mutex_lock(&priv->mcast_mutex);
85 ret = ib_detach_mcast(priv->qp, mgid, mlid); 85 ret = ib_detach_mcast(priv->qp, mgid, mlid);
86 up(&priv->mcast_mutex); 86 mutex_unlock(&priv->mcast_mutex);
87 if (ret) 87 if (ret)
88 ipoib_warn(priv, "ib_detach_mcast failed (result = %d)\n", ret); 88 ipoib_warn(priv, "ib_detach_mcast failed (result = %d)\n", ret);
89 89
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index d280b341a37f..4ca175553f9f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -63,7 +63,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
63 63
64 ppriv = netdev_priv(pdev); 64 ppriv = netdev_priv(pdev);
65 65
66 down(&ppriv->vlan_mutex); 66 mutex_lock(&ppriv->vlan_mutex);
67 67
68 /* 68 /*
69 * First ensure this isn't a duplicate. We check the parent device and 69 * First ensure this isn't a duplicate. We check the parent device and
@@ -124,7 +124,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
124 124
125 list_add_tail(&priv->list, &ppriv->child_intfs); 125 list_add_tail(&priv->list, &ppriv->child_intfs);
126 126
127 up(&ppriv->vlan_mutex); 127 mutex_unlock(&ppriv->vlan_mutex);
128 128
129 return 0; 129 return 0;
130 130
@@ -139,7 +139,7 @@ device_init_failed:
139 free_netdev(priv->dev); 139 free_netdev(priv->dev);
140 140
141err: 141err:
142 up(&ppriv->vlan_mutex); 142 mutex_unlock(&ppriv->vlan_mutex);
143 return result; 143 return result;
144} 144}
145 145
@@ -153,7 +153,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
153 153
154 ppriv = netdev_priv(pdev); 154 ppriv = netdev_priv(pdev);
155 155
156 down(&ppriv->vlan_mutex); 156 mutex_lock(&ppriv->vlan_mutex);
157 list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) { 157 list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) {
158 if (priv->pkey == pkey) { 158 if (priv->pkey == pkey) {
159 unregister_netdev(priv->dev); 159 unregister_netdev(priv->dev);
@@ -167,7 +167,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
167 break; 167 break;
168 } 168 }
169 } 169 }
170 up(&ppriv->vlan_mutex); 170 mutex_unlock(&ppriv->vlan_mutex);
171 171
172 return ret; 172 return ret;
173} 173}
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index dd488d3cffa9..31207e664148 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1516,8 +1516,7 @@ static ssize_t show_port(struct class_device *class_dev, char *buf)
1516 1516
1517static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL); 1517static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
1518 1518
1519static struct srp_host *srp_add_port(struct ib_device *device, 1519static struct srp_host *srp_add_port(struct ib_device *device, u8 port)
1520 __be64 node_guid, u8 port)
1521{ 1520{
1522 struct srp_host *host; 1521 struct srp_host *host;
1523 1522
@@ -1532,7 +1531,7 @@ static struct srp_host *srp_add_port(struct ib_device *device,
1532 host->port = port; 1531 host->port = port;
1533 1532
1534 host->initiator_port_id[7] = port; 1533 host->initiator_port_id[7] = port;
1535 memcpy(host->initiator_port_id + 8, &node_guid, 8); 1534 memcpy(host->initiator_port_id + 8, &device->node_guid, 8);
1536 1535
1537 host->pd = ib_alloc_pd(device); 1536 host->pd = ib_alloc_pd(device);
1538 if (IS_ERR(host->pd)) 1537 if (IS_ERR(host->pd))
@@ -1580,22 +1579,11 @@ static void srp_add_one(struct ib_device *device)
1580{ 1579{
1581 struct list_head *dev_list; 1580 struct list_head *dev_list;
1582 struct srp_host *host; 1581 struct srp_host *host;
1583 struct ib_device_attr *dev_attr;
1584 int s, e, p; 1582 int s, e, p;
1585 1583
1586 dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL);
1587 if (!dev_attr)
1588 return;
1589
1590 if (ib_query_device(device, dev_attr)) {
1591 printk(KERN_WARNING PFX "Couldn't query node GUID for %s.\n",
1592 device->name);
1593 goto out;
1594 }
1595
1596 dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL); 1584 dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL);
1597 if (!dev_list) 1585 if (!dev_list)
1598 goto out; 1586 return;
1599 1587
1600 INIT_LIST_HEAD(dev_list); 1588 INIT_LIST_HEAD(dev_list);
1601 1589
@@ -1608,15 +1596,12 @@ static void srp_add_one(struct ib_device *device)
1608 } 1596 }
1609 1597
1610 for (p = s; p <= e; ++p) { 1598 for (p = s; p <= e; ++p) {
1611 host = srp_add_port(device, dev_attr->node_guid, p); 1599 host = srp_add_port(device, p);
1612 if (host) 1600 if (host)
1613 list_add_tail(&host->list, dev_list); 1601 list_add_tail(&host->list, dev_list);
1614 } 1602 }
1615 1603
1616 ib_set_client_data(device, &srp_client, dev_list); 1604 ib_set_client_data(device, &srp_client, dev_list);
1617
1618out:
1619 kfree(dev_attr);
1620} 1605}
1621 1606
1622static void srp_remove_one(struct ib_device *device) 1607static void srp_remove_one(struct ib_device *device)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 362b33556b1a..745979f33dc2 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -159,7 +159,7 @@ struct input_event_compat {
159#ifdef CONFIG_X86_64 159#ifdef CONFIG_X86_64
160# define COMPAT_TEST is_compat_task() 160# define COMPAT_TEST is_compat_task()
161#elif defined(CONFIG_IA64) 161#elif defined(CONFIG_IA64)
162# define COMPAT_TEST IS_IA32_PROCESS(ia64_task_regs(current)) 162# define COMPAT_TEST IS_IA32_PROCESS(task_pt_regs(current))
163#elif defined(CONFIG_S390) 163#elif defined(CONFIG_S390)
164# define COMPAT_TEST test_thread_flag(TIF_31BIT) 164# define COMPAT_TEST test_thread_flag(TIF_31BIT)
165#elif defined(CONFIG_MIPS) 165#elif defined(CONFIG_MIPS)
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index caac6d63d46f..b765a155c008 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -50,9 +50,7 @@ static DECLARE_MUTEX(gameport_sem);
50 50
51static LIST_HEAD(gameport_list); 51static LIST_HEAD(gameport_list);
52 52
53static struct bus_type gameport_bus = { 53static struct bus_type gameport_bus;
54 .name = "gameport",
55};
56 54
57static void gameport_add_port(struct gameport *gameport); 55static void gameport_add_port(struct gameport *gameport);
58static void gameport_destroy_port(struct gameport *gameport); 56static void gameport_destroy_port(struct gameport *gameport);
@@ -703,11 +701,15 @@ static int gameport_driver_remove(struct device *dev)
703 return 0; 701 return 0;
704} 702}
705 703
704static struct bus_type gameport_bus = {
705 .name = "gameport",
706 .probe = gameport_driver_probe,
707 .remove = gameport_driver_remove,
708};
709
706void __gameport_register_driver(struct gameport_driver *drv, struct module *owner) 710void __gameport_register_driver(struct gameport_driver *drv, struct module *owner)
707{ 711{
708 drv->driver.bus = &gameport_bus; 712 drv->driver.bus = &gameport_bus;
709 drv->driver.probe = gameport_driver_probe;
710 drv->driver.remove = gameport_driver_remove;
711 gameport_queue_event(drv, owner, GAMEPORT_REGISTER_DRIVER); 713 gameport_queue_event(drv, owner, GAMEPORT_REGISTER_DRIVER);
712} 714}
713 715
diff --git a/drivers/input/input.c b/drivers/input/input.c
index fe33ff334e27..4fe3da3c667a 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -528,40 +528,56 @@ INPUT_DEV_STRING_ATTR_SHOW(name);
528INPUT_DEV_STRING_ATTR_SHOW(phys); 528INPUT_DEV_STRING_ATTR_SHOW(phys);
529INPUT_DEV_STRING_ATTR_SHOW(uniq); 529INPUT_DEV_STRING_ATTR_SHOW(uniq);
530 530
531static int print_modalias_bits(char *buf, char prefix, unsigned long *arr, 531static int print_modalias_bits(char *buf, int size, char prefix, unsigned long *arr,
532 unsigned int min, unsigned int max) 532 unsigned int min, unsigned int max)
533{ 533{
534 int len, i; 534 int len, i;
535 535
536 len = sprintf(buf, "%c", prefix); 536 len = snprintf(buf, size, "%c", prefix);
537 for (i = min; i < max; i++) 537 for (i = min; i < max; i++)
538 if (arr[LONG(i)] & BIT(i)) 538 if (arr[LONG(i)] & BIT(i))
539 len += sprintf(buf+len, "%X,", i); 539 len += snprintf(buf + len, size - len, "%X,", i);
540 return len; 540 return len;
541} 541}
542 542
543static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf) 543static int print_modalias(char *buf, int size, struct input_dev *id)
544{ 544{
545 struct input_dev *id = to_input_dev(dev); 545 int len;
546 ssize_t len = 0;
547 546
548 len += sprintf(buf+len, "input:b%04Xv%04Xp%04Xe%04X-", 547 len = snprintf(buf, size, "input:b%04Xv%04Xp%04Xe%04X-",
549 id->id.bustype, 548 id->id.bustype,
550 id->id.vendor, 549 id->id.vendor,
551 id->id.product, 550 id->id.product,
552 id->id.version); 551 id->id.version);
553 552
554 len += print_modalias_bits(buf+len, 'e', id->evbit, 0, EV_MAX); 553 len += print_modalias_bits(buf + len, size - len, 'e', id->evbit,
555 len += print_modalias_bits(buf+len, 'k', id->keybit, 554 0, EV_MAX);
555 len += print_modalias_bits(buf + len, size - len, 'k', id->keybit,
556 KEY_MIN_INTERESTING, KEY_MAX); 556 KEY_MIN_INTERESTING, KEY_MAX);
557 len += print_modalias_bits(buf+len, 'r', id->relbit, 0, REL_MAX); 557 len += print_modalias_bits(buf + len, size - len, 'r', id->relbit,
558 len += print_modalias_bits(buf+len, 'a', id->absbit, 0, ABS_MAX); 558 0, REL_MAX);
559 len += print_modalias_bits(buf+len, 'm', id->mscbit, 0, MSC_MAX); 559 len += print_modalias_bits(buf + len, size - len, 'a', id->absbit,
560 len += print_modalias_bits(buf+len, 'l', id->ledbit, 0, LED_MAX); 560 0, ABS_MAX);
561 len += print_modalias_bits(buf+len, 's', id->sndbit, 0, SND_MAX); 561 len += print_modalias_bits(buf + len, size - len, 'm', id->mscbit,
562 len += print_modalias_bits(buf+len, 'f', id->ffbit, 0, FF_MAX); 562 0, MSC_MAX);
563 len += print_modalias_bits(buf+len, 'w', id->swbit, 0, SW_MAX); 563 len += print_modalias_bits(buf + len, size - len, 'l', id->ledbit,
564 len += sprintf(buf+len, "\n"); 564 0, LED_MAX);
565 len += print_modalias_bits(buf + len, size - len, 's', id->sndbit,
566 0, SND_MAX);
567 len += print_modalias_bits(buf + len, size - len, 'f', id->ffbit,
568 0, FF_MAX);
569 len += print_modalias_bits(buf + len, size - len, 'w', id->swbit,
570 0, SW_MAX);
571 return len;
572}
573
574static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
575{
576 struct input_dev *id = to_input_dev(dev);
577 ssize_t len;
578
579 len = print_modalias(buf, PAGE_SIZE, id);
580 len += snprintf(buf + len, PAGE_SIZE-len, "\n");
565 return len; 581 return len;
566} 582}
567static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); 583static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
@@ -728,8 +744,11 @@ static int input_dev_uevent(struct class_device *cdev, char **envp,
728 if (test_bit(EV_SW, dev->evbit)) 744 if (test_bit(EV_SW, dev->evbit))
729 INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX); 745 INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX);
730 746
731 envp[i] = NULL; 747 envp[i++] = buffer + len;
748 len += snprintf(buffer + len, buffer_size - len, "MODALIAS=");
749 len += print_modalias(buffer + len, buffer_size - len, dev) + 1;
732 750
751 envp[i] = NULL;
733 return 0; 752 return 0;
734} 753}
735 754
diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c
index 8558a99f6635..ec55a29fc861 100644
--- a/drivers/input/joystick/amijoy.c
+++ b/drivers/input/joystick/amijoy.c
@@ -64,8 +64,8 @@ static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
64 if (amijoy[i]) { 64 if (amijoy[i]) {
65 65
66 switch (i) { 66 switch (i) {
67 case 0: data = ~custom.joy0dat; button = (~ciaa.pra >> 6) & 1; break; 67 case 0: data = ~amiga_custom.joy0dat; button = (~ciaa.pra >> 6) & 1; break;
68 case 1: data = ~custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break; 68 case 1: data = ~amiga_custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break;
69 } 69 }
70 70
71 input_regs(amijoy_dev[i], fp); 71 input_regs(amijoy_dev[i], fp);
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 24474335dfd1..2141501e9f2e 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -348,6 +348,40 @@ static int alps_tap_mode(struct psmouse *psmouse, int enable)
348 return 0; 348 return 0;
349} 349}
350 350
351/*
352 * alps_poll() - poll the touchpad for current motion packet.
353 * Used in resync.
354 */
355static int alps_poll(struct psmouse *psmouse)
356{
357 struct alps_data *priv = psmouse->private;
358 unsigned char buf[6];
359 int poll_failed;
360
361 if (priv->i->flags & ALPS_PASS)
362 alps_passthrough_mode(psmouse, 1);
363
364 poll_failed = ps2_command(&psmouse->ps2dev, buf,
365 PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;
366
367 if (priv->i->flags & ALPS_PASS)
368 alps_passthrough_mode(psmouse, 0);
369
370 if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0)
371 return -1;
372
373 if ((psmouse->badbyte & 0xc8) == 0x08) {
374/*
375 * Poll the track stick ...
376 */
377 if (ps2_command(&psmouse->ps2dev, buf, PSMOUSE_CMD_POLL | (3 << 8)))
378 return -1;
379 }
380
381 memcpy(psmouse->packet, buf, sizeof(buf));
382 return 0;
383}
384
351static int alps_reconnect(struct psmouse *psmouse) 385static int alps_reconnect(struct psmouse *psmouse)
352{ 386{
353 struct alps_data *priv = psmouse->private; 387 struct alps_data *priv = psmouse->private;
@@ -451,10 +485,14 @@ int alps_init(struct psmouse *psmouse)
451 input_register_device(priv->dev2); 485 input_register_device(priv->dev2);
452 486
453 psmouse->protocol_handler = alps_process_byte; 487 psmouse->protocol_handler = alps_process_byte;
488 psmouse->poll = alps_poll;
454 psmouse->disconnect = alps_disconnect; 489 psmouse->disconnect = alps_disconnect;
455 psmouse->reconnect = alps_reconnect; 490 psmouse->reconnect = alps_reconnect;
456 psmouse->pktsize = 6; 491 psmouse->pktsize = 6;
457 492
493 /* We are having trouble resyncing ALPS touchpads so disable it for now */
494 psmouse->resync_time = 0;
495
458 return 0; 496 return 0;
459 497
460init_fail: 498init_fail:
diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c
index d13d4c8fe3c5..c8b2cc9f184c 100644
--- a/drivers/input/mouse/amimouse.c
+++ b/drivers/input/mouse/amimouse.c
@@ -41,7 +41,7 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
41 unsigned short joy0dat, potgor; 41 unsigned short joy0dat, potgor;
42 int nx, ny, dx, dy; 42 int nx, ny, dx, dy;
43 43
44 joy0dat = custom.joy0dat; 44 joy0dat = amiga_custom.joy0dat;
45 45
46 nx = joy0dat & 0xff; 46 nx = joy0dat & 0xff;
47 ny = joy0dat >> 8; 47 ny = joy0dat >> 8;
@@ -57,7 +57,7 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
57 amimouse_lastx = nx; 57 amimouse_lastx = nx;
58 amimouse_lasty = ny; 58 amimouse_lasty = ny;
59 59
60 potgor = custom.potgor; 60 potgor = amiga_custom.potgor;
61 61
62 input_regs(amimouse_dev, fp); 62 input_regs(amimouse_dev, fp);
63 63
@@ -77,7 +77,7 @@ static int amimouse_open(struct input_dev *dev)
77{ 77{
78 unsigned short joy0dat; 78 unsigned short joy0dat;
79 79
80 joy0dat = custom.joy0dat; 80 joy0dat = amiga_custom.joy0dat;
81 81
82 amimouse_lastx = joy0dat & 0xff; 82 amimouse_lastx = joy0dat & 0xff;
83 amimouse_lasty = joy0dat >> 8; 83 amimouse_lasty = joy0dat >> 8;
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 025a71de5404..c88520d3d13c 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -117,7 +117,7 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha
117 if (psmouse_sliced_command(psmouse, command)) 117 if (psmouse_sliced_command(psmouse, command))
118 return -1; 118 return -1;
119 119
120 if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL)) 120 if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL | 0x0300))
121 return -1; 121 return -1;
122 122
123 return 0; 123 return 0;
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 4d5ecc04c5b6..7665fd9ce559 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -54,10 +54,14 @@ static unsigned int psmouse_smartscroll = 1;
54module_param_named(smartscroll, psmouse_smartscroll, bool, 0644); 54module_param_named(smartscroll, psmouse_smartscroll, bool, 0644);
55MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); 55MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
56 56
57static unsigned int psmouse_resetafter; 57static unsigned int psmouse_resetafter = 5;
58module_param_named(resetafter, psmouse_resetafter, uint, 0644); 58module_param_named(resetafter, psmouse_resetafter, uint, 0644);
59MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); 59MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
60 60
61static unsigned int psmouse_resync_time = 5;
62module_param_named(resync_time, psmouse_resync_time, uint, 0644);
63MODULE_PARM_DESC(resync_time, "How long can mouse stay idle before forcing resync (in seconds, 0 = never).");
64
61PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO, 65PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO,
62 NULL, 66 NULL,
63 psmouse_attr_show_protocol, psmouse_attr_set_protocol); 67 psmouse_attr_show_protocol, psmouse_attr_set_protocol);
@@ -70,12 +74,16 @@ PSMOUSE_DEFINE_ATTR(resolution, S_IWUSR | S_IRUGO,
70PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO, 74PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO,
71 (void *) offsetof(struct psmouse, resetafter), 75 (void *) offsetof(struct psmouse, resetafter),
72 psmouse_show_int_attr, psmouse_set_int_attr); 76 psmouse_show_int_attr, psmouse_set_int_attr);
77PSMOUSE_DEFINE_ATTR(resync_time, S_IWUSR | S_IRUGO,
78 (void *) offsetof(struct psmouse, resync_time),
79 psmouse_show_int_attr, psmouse_set_int_attr);
73 80
74static struct attribute *psmouse_attributes[] = { 81static struct attribute *psmouse_attributes[] = {
75 &psmouse_attr_protocol.dattr.attr, 82 &psmouse_attr_protocol.dattr.attr,
76 &psmouse_attr_rate.dattr.attr, 83 &psmouse_attr_rate.dattr.attr,
77 &psmouse_attr_resolution.dattr.attr, 84 &psmouse_attr_resolution.dattr.attr,
78 &psmouse_attr_resetafter.dattr.attr, 85 &psmouse_attr_resetafter.dattr.attr,
86 &psmouse_attr_resync_time.dattr.attr,
79 NULL 87 NULL
80}; 88};
81 89
@@ -98,6 +106,8 @@ __obsolete_setup("psmouse_rate=");
98 */ 106 */
99static DECLARE_MUTEX(psmouse_sem); 107static DECLARE_MUTEX(psmouse_sem);
100 108
109static struct workqueue_struct *kpsmoused_wq;
110
101struct psmouse_protocol { 111struct psmouse_protocol {
102 enum psmouse_type type; 112 enum psmouse_type type;
103 char *name; 113 char *name;
@@ -178,15 +188,79 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_reg
178} 188}
179 189
180/* 190/*
181 * psmouse_interrupt() handles incoming characters, either gathering them into 191 * __psmouse_set_state() sets new psmouse state and resets all flags.
182 * packets or passing them to the command routine as command output. 192 */
193
194static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
195{
196 psmouse->state = new_state;
197 psmouse->pktcnt = psmouse->out_of_sync = 0;
198 psmouse->ps2dev.flags = 0;
199 psmouse->last = jiffies;
200}
201
202
203/*
204 * psmouse_set_state() sets new psmouse state and resets all flags and
205 * counters while holding serio lock so fighting with interrupt handler
206 * is not a concern.
207 */
208
209static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
210{
211 serio_pause_rx(psmouse->ps2dev.serio);
212 __psmouse_set_state(psmouse, new_state);
213 serio_continue_rx(psmouse->ps2dev.serio);
214}
215
216/*
217 * psmouse_handle_byte() processes one byte of the input data stream
218 * by calling corresponding protocol handler.
219 */
220
221static int psmouse_handle_byte(struct psmouse *psmouse, struct pt_regs *regs)
222{
223 psmouse_ret_t rc = psmouse->protocol_handler(psmouse, regs);
224
225 switch (rc) {
226 case PSMOUSE_BAD_DATA:
227 if (psmouse->state == PSMOUSE_ACTIVATED) {
228 printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",
229 psmouse->name, psmouse->phys, psmouse->pktcnt);
230 if (++psmouse->out_of_sync == psmouse->resetafter) {
231 __psmouse_set_state(psmouse, PSMOUSE_IGNORE);
232 printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
233 serio_reconnect(psmouse->ps2dev.serio);
234 return -1;
235 }
236 }
237 psmouse->pktcnt = 0;
238 break;
239
240 case PSMOUSE_FULL_PACKET:
241 psmouse->pktcnt = 0;
242 if (psmouse->out_of_sync) {
243 psmouse->out_of_sync = 0;
244 printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",
245 psmouse->name, psmouse->phys);
246 }
247 break;
248
249 case PSMOUSE_GOOD_DATA:
250 break;
251 }
252 return 0;
253}
254
255/*
256 * psmouse_interrupt() handles incoming characters, either passing them
257 * for normal processing or gathering them as command response.
183 */ 258 */
184 259
185static irqreturn_t psmouse_interrupt(struct serio *serio, 260static irqreturn_t psmouse_interrupt(struct serio *serio,
186 unsigned char data, unsigned int flags, struct pt_regs *regs) 261 unsigned char data, unsigned int flags, struct pt_regs *regs)
187{ 262{
188 struct psmouse *psmouse = serio_get_drvdata(serio); 263 struct psmouse *psmouse = serio_get_drvdata(serio);
189 psmouse_ret_t rc;
190 264
191 if (psmouse->state == PSMOUSE_IGNORE) 265 if (psmouse->state == PSMOUSE_IGNORE)
192 goto out; 266 goto out;
@@ -208,67 +282,58 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
208 if (ps2_handle_response(&psmouse->ps2dev, data)) 282 if (ps2_handle_response(&psmouse->ps2dev, data))
209 goto out; 283 goto out;
210 284
211 if (psmouse->state == PSMOUSE_INITIALIZING) 285 if (psmouse->state <= PSMOUSE_RESYNCING)
212 goto out; 286 goto out;
213 287
214 if (psmouse->state == PSMOUSE_ACTIVATED && 288 if (psmouse->state == PSMOUSE_ACTIVATED &&
215 psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) { 289 psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {
216 printk(KERN_WARNING "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n", 290 printk(KERN_INFO "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n",
217 psmouse->name, psmouse->phys, psmouse->pktcnt); 291 psmouse->name, psmouse->phys, psmouse->pktcnt);
218 psmouse->pktcnt = 0; 292 psmouse->badbyte = psmouse->packet[0];
293 __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
294 queue_work(kpsmoused_wq, &psmouse->resync_work);
295 goto out;
219 } 296 }
220 297
221 psmouse->last = jiffies;
222 psmouse->packet[psmouse->pktcnt++] = data; 298 psmouse->packet[psmouse->pktcnt++] = data;
223 299/*
224 if (psmouse->packet[0] == PSMOUSE_RET_BAT) { 300 * Check if this is a new device announcement (0xAA 0x00)
301 */
302 if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) {
225 if (psmouse->pktcnt == 1) 303 if (psmouse->pktcnt == 1)
226 goto out; 304 goto out;
227 305
228 if (psmouse->pktcnt == 2) { 306 if (psmouse->packet[1] == PSMOUSE_RET_ID) {
229 if (psmouse->packet[1] == PSMOUSE_RET_ID) { 307 __psmouse_set_state(psmouse, PSMOUSE_IGNORE);
230 psmouse->state = PSMOUSE_IGNORE; 308 serio_reconnect(serio);
231 serio_reconnect(serio); 309 goto out;
232 goto out;
233 }
234 if (psmouse->type == PSMOUSE_SYNAPTICS) {
235 /* neither 0xAA nor 0x00 are valid first bytes
236 * for a packet in absolute mode
237 */
238 psmouse->pktcnt = 0;
239 goto out;
240 }
241 } 310 }
242 } 311/*
243 312 * Not a new device, try processing first byte normally
244 rc = psmouse->protocol_handler(psmouse, regs); 313 */
314 psmouse->pktcnt = 1;
315 if (psmouse_handle_byte(psmouse, regs))
316 goto out;
245 317
246 switch (rc) { 318 psmouse->packet[psmouse->pktcnt++] = data;
247 case PSMOUSE_BAD_DATA: 319 }
248 printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",
249 psmouse->name, psmouse->phys, psmouse->pktcnt);
250 psmouse->pktcnt = 0;
251 320
252 if (++psmouse->out_of_sync == psmouse->resetafter) { 321/*
253 psmouse->state = PSMOUSE_IGNORE; 322 * See if we need to force resync because mouse was idle for too long
254 printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); 323 */
255 serio_reconnect(psmouse->ps2dev.serio); 324 if (psmouse->state == PSMOUSE_ACTIVATED &&
256 } 325 psmouse->pktcnt == 1 && psmouse->resync_time &&
257 break; 326 time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) {
327 psmouse->badbyte = psmouse->packet[0];
328 __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
329 queue_work(kpsmoused_wq, &psmouse->resync_work);
330 goto out;
331 }
258 332
259 case PSMOUSE_FULL_PACKET: 333 psmouse->last = jiffies;
260 psmouse->pktcnt = 0; 334 psmouse_handle_byte(psmouse, regs);
261 if (psmouse->out_of_sync) {
262 psmouse->out_of_sync = 0;
263 printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",
264 psmouse->name, psmouse->phys);
265 }
266 break;
267 335
268 case PSMOUSE_GOOD_DATA: 336 out:
269 break;
270 }
271out:
272 return IRQ_HANDLED; 337 return IRQ_HANDLED;
273} 338}
274 339
@@ -752,21 +817,6 @@ static void psmouse_initialize(struct psmouse *psmouse)
752} 817}
753 818
754/* 819/*
755 * psmouse_set_state() sets new psmouse state and resets all flags and
756 * counters while holding serio lock so fighting with interrupt handler
757 * is not a concern.
758 */
759
760static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
761{
762 serio_pause_rx(psmouse->ps2dev.serio);
763 psmouse->state = new_state;
764 psmouse->pktcnt = psmouse->out_of_sync = 0;
765 psmouse->ps2dev.flags = 0;
766 serio_continue_rx(psmouse->ps2dev.serio);
767}
768
769/*
770 * psmouse_activate() enables the mouse so that we get motion reports from it. 820 * psmouse_activate() enables the mouse so that we get motion reports from it.
771 */ 821 */
772 822
@@ -794,6 +844,111 @@ static void psmouse_deactivate(struct psmouse *psmouse)
794 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); 844 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
795} 845}
796 846
847/*
848 * psmouse_poll() - default poll hanlder. Everyone except for ALPS uses it.
849 */
850
851static int psmouse_poll(struct psmouse *psmouse)
852{
853 return ps2_command(&psmouse->ps2dev, psmouse->packet,
854 PSMOUSE_CMD_POLL | (psmouse->pktsize << 8));
855}
856
857
858/*
859 * psmouse_resync() attempts to re-validate current protocol.
860 */
861
862static void psmouse_resync(void *p)
863{
864 struct psmouse *psmouse = p, *parent = NULL;
865 struct serio *serio = psmouse->ps2dev.serio;
866 psmouse_ret_t rc = PSMOUSE_GOOD_DATA;
867 int failed = 0, enabled = 0;
868 int i;
869
870 down(&psmouse_sem);
871
872 if (psmouse->state != PSMOUSE_RESYNCING)
873 goto out;
874
875 if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
876 parent = serio_get_drvdata(serio->parent);
877 psmouse_deactivate(parent);
878 }
879
880/*
881 * Some mice don't ACK commands sent while they are in the middle of
882 * transmitting motion packet. To avoid delay we use ps2_sendbyte()
883 * instead of ps2_command() which would wait for 200ms for an ACK
884 * that may never come.
885 * As an additional quirk ALPS touchpads may not only forget to ACK
886 * disable command but will stop reporting taps, so if we see that
887 * mouse at least once ACKs disable we will do full reconnect if ACK
888 * is missing.
889 */
890 psmouse->num_resyncs++;
891
892 if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) {
893 if (psmouse->num_resyncs < 3 || psmouse->acks_disable_command)
894 failed = 1;
895 } else
896 psmouse->acks_disable_command = 1;
897
898/*
899 * Poll the mouse. If it was reset the packet will be shorter than
900 * psmouse->pktsize and ps2_command will fail. We do not expect and
901 * do not handle scenario when mouse "upgrades" its protocol while
902 * disconnected since it would require additional delay. If we ever
903 * see a mouse that does it we'll adjust the code.
904 */
905 if (!failed) {
906 if (psmouse->poll(psmouse))
907 failed = 1;
908 else {
909 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
910 for (i = 0; i < psmouse->pktsize; i++) {
911 psmouse->pktcnt++;
912 rc = psmouse->protocol_handler(psmouse, NULL);
913 if (rc != PSMOUSE_GOOD_DATA)
914 break;
915 }
916 if (rc != PSMOUSE_FULL_PACKET)
917 failed = 1;
918 psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
919 }
920 }
921/*
922 * Now try to enable mouse. We try to do that even if poll failed and also
923 * repeat our attempts 5 times, otherwise we may be left out with disabled
924 * mouse.
925 */
926 for (i = 0; i < 5; i++) {
927 if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
928 enabled = 1;
929 break;
930 }
931 msleep(200);
932 }
933
934 if (!enabled) {
935 printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n",
936 psmouse->ps2dev.serio->phys);
937 failed = 1;
938 }
939
940 if (failed) {
941 psmouse_set_state(psmouse, PSMOUSE_IGNORE);
942 printk(KERN_INFO "psmouse.c: resync failed, issuing reconnect request\n");
943 serio_reconnect(serio);
944 } else
945 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
946
947 if (parent)
948 psmouse_activate(parent);
949 out:
950 up(&psmouse_sem);
951}
797 952
798/* 953/*
799 * psmouse_cleanup() resets the mouse into power-on state. 954 * psmouse_cleanup() resets the mouse into power-on state.
@@ -822,6 +977,11 @@ static void psmouse_disconnect(struct serio *serio)
822 977
823 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); 978 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
824 979
980 /* make sure we don't have a resync in progress */
981 up(&psmouse_sem);
982 flush_workqueue(kpsmoused_wq);
983 down(&psmouse_sem);
984
825 if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { 985 if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
826 parent = serio_get_drvdata(serio->parent); 986 parent = serio_get_drvdata(serio->parent);
827 psmouse_deactivate(parent); 987 psmouse_deactivate(parent);
@@ -859,6 +1019,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto
859 1019
860 psmouse->set_rate = psmouse_set_rate; 1020 psmouse->set_rate = psmouse_set_rate;
861 psmouse->set_resolution = psmouse_set_resolution; 1021 psmouse->set_resolution = psmouse_set_resolution;
1022 psmouse->poll = psmouse_poll;
862 psmouse->protocol_handler = psmouse_process_byte; 1023 psmouse->protocol_handler = psmouse_process_byte;
863 psmouse->pktsize = 3; 1024 psmouse->pktsize = 3;
864 1025
@@ -874,6 +1035,23 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto
874 else 1035 else
875 psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1); 1036 psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);
876 1037
1038 /*
1039 * If mouse's packet size is 3 there is no point in polling the
1040 * device in hopes to detect protocol reset - we won't get less
1041 * than 3 bytes response anyhow.
1042 */
1043 if (psmouse->pktsize == 3)
1044 psmouse->resync_time = 0;
1045
1046 /*
1047 * Some smart KVMs fake response to POLL command returning just
1048 * 3 bytes and messing up our resync logic, so if initial poll
1049 * fails we won't try polling the device anymore. Hopefully
1050 * such KVM will maintain initially selected protocol.
1051 */
1052 if (psmouse->resync_time && psmouse->poll(psmouse))
1053 psmouse->resync_time = 0;
1054
877 sprintf(psmouse->devname, "%s %s %s", 1055 sprintf(psmouse->devname, "%s %s %s",
878 psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); 1056 psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);
879 1057
@@ -914,6 +1092,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
914 goto out; 1092 goto out;
915 1093
916 ps2_init(&psmouse->ps2dev, serio); 1094 ps2_init(&psmouse->ps2dev, serio);
1095 INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse);
917 psmouse->dev = input_dev; 1096 psmouse->dev = input_dev;
918 sprintf(psmouse->phys, "%s/input0", serio->phys); 1097 sprintf(psmouse->phys, "%s/input0", serio->phys);
919 1098
@@ -934,6 +1113,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
934 psmouse->rate = psmouse_rate; 1113 psmouse->rate = psmouse_rate;
935 psmouse->resolution = psmouse_resolution; 1114 psmouse->resolution = psmouse_resolution;
936 psmouse->resetafter = psmouse_resetafter; 1115 psmouse->resetafter = psmouse_resetafter;
1116 psmouse->resync_time = parent ? 0 : psmouse_resync_time;
937 psmouse->smartscroll = psmouse_smartscroll; 1117 psmouse->smartscroll = psmouse_smartscroll;
938 1118
939 psmouse_switch_protocol(psmouse, NULL); 1119 psmouse_switch_protocol(psmouse, NULL);
@@ -1278,13 +1458,21 @@ static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp)
1278 1458
1279static int __init psmouse_init(void) 1459static int __init psmouse_init(void)
1280{ 1460{
1461 kpsmoused_wq = create_singlethread_workqueue("kpsmoused");
1462 if (!kpsmoused_wq) {
1463 printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n");
1464 return -ENOMEM;
1465 }
1466
1281 serio_register_driver(&psmouse_drv); 1467 serio_register_driver(&psmouse_drv);
1468
1282 return 0; 1469 return 0;
1283} 1470}
1284 1471
1285static void __exit psmouse_exit(void) 1472static void __exit psmouse_exit(void)
1286{ 1473{
1287 serio_unregister_driver(&psmouse_drv); 1474 serio_unregister_driver(&psmouse_drv);
1475 destroy_workqueue(kpsmoused_wq);
1288} 1476}
1289 1477
1290module_init(psmouse_init); 1478module_init(psmouse_init);
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 7c4192bd1279..4d9107fba6a1 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -7,7 +7,7 @@
7#define PSMOUSE_CMD_GETINFO 0x03e9 7#define PSMOUSE_CMD_GETINFO 0x03e9
8#define PSMOUSE_CMD_SETSTREAM 0x00ea 8#define PSMOUSE_CMD_SETSTREAM 0x00ea
9#define PSMOUSE_CMD_SETPOLL 0x00f0 9#define PSMOUSE_CMD_SETPOLL 0x00f0
10#define PSMOUSE_CMD_POLL 0x03eb 10#define PSMOUSE_CMD_POLL 0x00eb /* caller sets number of bytes to receive */
11#define PSMOUSE_CMD_GETID 0x02f2 11#define PSMOUSE_CMD_GETID 0x02f2
12#define PSMOUSE_CMD_SETRATE 0x10f3 12#define PSMOUSE_CMD_SETRATE 0x10f3
13#define PSMOUSE_CMD_ENABLE 0x00f4 13#define PSMOUSE_CMD_ENABLE 0x00f4
@@ -23,6 +23,7 @@
23enum psmouse_state { 23enum psmouse_state {
24 PSMOUSE_IGNORE, 24 PSMOUSE_IGNORE,
25 PSMOUSE_INITIALIZING, 25 PSMOUSE_INITIALIZING,
26 PSMOUSE_RESYNCING,
26 PSMOUSE_CMD_MODE, 27 PSMOUSE_CMD_MODE,
27 PSMOUSE_ACTIVATED, 28 PSMOUSE_ACTIVATED,
28}; 29};
@@ -38,15 +39,19 @@ struct psmouse {
38 void *private; 39 void *private;
39 struct input_dev *dev; 40 struct input_dev *dev;
40 struct ps2dev ps2dev; 41 struct ps2dev ps2dev;
42 struct work_struct resync_work;
41 char *vendor; 43 char *vendor;
42 char *name; 44 char *name;
43 unsigned char packet[8]; 45 unsigned char packet[8];
46 unsigned char badbyte;
44 unsigned char pktcnt; 47 unsigned char pktcnt;
45 unsigned char pktsize; 48 unsigned char pktsize;
46 unsigned char type; 49 unsigned char type;
50 unsigned char acks_disable_command;
47 unsigned int model; 51 unsigned int model;
48 unsigned long last; 52 unsigned long last;
49 unsigned long out_of_sync; 53 unsigned long out_of_sync;
54 unsigned long num_resyncs;
50 enum psmouse_state state; 55 enum psmouse_state state;
51 char devname[64]; 56 char devname[64];
52 char phys[32]; 57 char phys[32];
@@ -54,6 +59,7 @@ struct psmouse {
54 unsigned int rate; 59 unsigned int rate;
55 unsigned int resolution; 60 unsigned int resolution;
56 unsigned int resetafter; 61 unsigned int resetafter;
62 unsigned int resync_time;
57 unsigned int smartscroll; /* Logitech only */ 63 unsigned int smartscroll; /* Logitech only */
58 64
59 psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs); 65 psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs);
@@ -62,6 +68,7 @@ struct psmouse {
62 68
63 int (*reconnect)(struct psmouse *psmouse); 69 int (*reconnect)(struct psmouse *psmouse);
64 void (*disconnect)(struct psmouse *psmouse); 70 void (*disconnect)(struct psmouse *psmouse);
71 int (*poll)(struct psmouse *psmouse);
65 72
66 void (*pt_activate)(struct psmouse *psmouse); 73 void (*pt_activate)(struct psmouse *psmouse);
67 void (*pt_deactivate)(struct psmouse *psmouse); 74 void (*pt_deactivate)(struct psmouse *psmouse);
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 97cdfd6acaca..2051bec2c394 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -652,6 +652,8 @@ int synaptics_init(struct psmouse *psmouse)
652 psmouse->disconnect = synaptics_disconnect; 652 psmouse->disconnect = synaptics_disconnect;
653 psmouse->reconnect = synaptics_reconnect; 653 psmouse->reconnect = synaptics_reconnect;
654 psmouse->pktsize = 6; 654 psmouse->pktsize = 6;
655 /* Synaptics can usually stay in sync without extra help */
656 psmouse->resync_time = 0;
655 657
656 if (SYN_CAP_PASS_THROUGH(priv->capabilities)) 658 if (SYN_CAP_PASS_THROUGH(priv->capabilities))
657 synaptics_pt_create(psmouse); 659 synaptics_pt_create(psmouse);
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 2d2f9fb3aded..a4c6f3522723 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -173,6 +173,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
173 DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), 173 DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"),
174 }, 174 },
175 }, 175 },
176 {
177 .ident = "Sony Vaio FS-115b",
178 .matches = {
179 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
180 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
181 },
182 },
176 { } 183 { }
177}; 184};
178 185
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 8e530cc970e1..2f76813c3a64 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -59,9 +59,7 @@ static DECLARE_MUTEX(serio_sem);
59 59
60static LIST_HEAD(serio_list); 60static LIST_HEAD(serio_list);
61 61
62static struct bus_type serio_bus = { 62static struct bus_type serio_bus;
63 .name = "serio",
64};
65 63
66static void serio_add_port(struct serio *serio); 64static void serio_add_port(struct serio *serio);
67static void serio_destroy_port(struct serio *serio); 65static void serio_destroy_port(struct serio *serio);
@@ -750,11 +748,15 @@ static int serio_driver_remove(struct device *dev)
750 return 0; 748 return 0;
751} 749}
752 750
751static struct bus_type serio_bus = {
752 .name = "serio",
753 .probe = serio_driver_probe,
754 .remove = serio_driver_remove,
755};
756
753void __serio_register_driver(struct serio_driver *drv, struct module *owner) 757void __serio_register_driver(struct serio_driver *drv, struct module *owner)
754{ 758{
755 drv->driver.bus = &serio_bus; 759 drv->driver.bus = &serio_bus;
756 drv->driver.probe = serio_driver_probe;
757 drv->driver.remove = serio_driver_remove;
758 760
759 serio_queue_event(drv, owner, SERIO_REGISTER_DRIVER); 761 serio_queue_event(drv, owner, SERIO_REGISTER_DRIVER);
760} 762}
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 21d55ed4b88a..2c674023a6ac 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -11,6 +11,19 @@ menuconfig INPUT_TOUCHSCREEN
11 11
12if INPUT_TOUCHSCREEN 12if INPUT_TOUCHSCREEN
13 13
14config TOUCHSCREEN_ADS7846
15 tristate "ADS 7846 based touchscreens"
16 depends on SPI_MASTER
17 help
18 Say Y here if you have a touchscreen interface using the
19 ADS7846 controller, and your board-specific initialization
20 code includes that in its table of SPI devices.
21
22 If unsure, say N (but it's safe to say "Y").
23
24 To compile this driver as a module, choose M here: the
25 module will be called ads7846.
26
14config TOUCHSCREEN_BITSY 27config TOUCHSCREEN_BITSY
15 tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" 28 tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
16 depends on SA1100_BITSY 29 depends on SA1100_BITSY
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 6842869c9a26..5e5557c43121 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -4,6 +4,7 @@
4 4
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
7obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o 8obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
8obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o 9obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
9obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o 10obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
new file mode 100644
index 000000000000..dd8c6a9ffc76
--- /dev/null
+++ b/drivers/input/touchscreen/ads7846.c
@@ -0,0 +1,625 @@
1/*
2 * ADS7846 based touchscreen and sensor driver
3 *
4 * Copyright (c) 2005 David Brownell
5 *
6 * Using code from:
7 * - corgi_ts.c
8 * Copyright (C) 2004-2005 Richard Purdie
9 * - omap_ts.[hc], ads7846.h, ts_osk.c
10 * Copyright (C) 2002 MontaVista Software
11 * Copyright (C) 2004 Texas Instruments
12 * Copyright (C) 2005 Dirk Behme
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18#include <linux/device.h>
19#include <linux/init.h>
20#include <linux/delay.h>
21#include <linux/input.h>
22#include <linux/interrupt.h>
23#include <linux/slab.h>
24#include <linux/spi/spi.h>
25#include <linux/spi/ads7846.h>
26
27#ifdef CONFIG_ARM
28#include <asm/mach-types.h>
29#ifdef CONFIG_ARCH_OMAP
30#include <asm/arch/gpio.h>
31#endif
32
33#else
34#define set_irq_type(irq,type) do{}while(0)
35#endif
36
37
38/*
39 * This code has been lightly tested on an ads7846.
40 * Support for ads7843 and ads7845 has only been stubbed in.
41 *
42 * Not yet done: investigate the values reported. Are x/y/pressure
43 * event values sane enough for X11? How accurate are the temperature
44 * and voltage readings? (System-specific calibration should support
45 * accuracy of 0.3 degrees C; otherwise it's 2.0 degrees.)
46 *
47 * app note sbaa036 talks in more detail about accurate sampling...
48 * that ought to help in situations like LCDs inducing noise (which
49 * can also be helped by using synch signals) and more generally.
50 */
51
52#define TS_POLL_PERIOD msecs_to_jiffies(10)
53
54struct ts_event {
55 /* For portability, we can't read 12 bit values using SPI (which
56 * would make the controller deliver them as native byteorder u16
57 * with msbs zeroed). Instead, we read them as two 8-byte values,
58 * which need byteswapping then range adjustment.
59 */
60 __be16 x;
61 __be16 y;
62 __be16 z1, z2;
63};
64
65struct ads7846 {
66 struct input_dev input;
67 char phys[32];
68
69 struct spi_device *spi;
70 u16 model;
71 u16 vref_delay_usecs;
72 u16 x_plate_ohms;
73
74 struct ts_event tc;
75
76 struct spi_transfer xfer[8];
77 struct spi_message msg;
78
79 spinlock_t lock;
80 struct timer_list timer; /* P: lock */
81 unsigned pendown:1; /* P: lock */
82 unsigned pending:1; /* P: lock */
83// FIXME remove "irq_disabled"
84 unsigned irq_disabled:1; /* P: lock */
85};
86
87/* leave chip selected when we're done, for quicker re-select? */
88#if 0
89#define CS_CHANGE(xfer) ((xfer).cs_change = 1)
90#else
91#define CS_CHANGE(xfer) ((xfer).cs_change = 0)
92#endif
93
94/*--------------------------------------------------------------------------*/
95
96/* The ADS7846 has touchscreen and other sensors.
97 * Earlier ads784x chips are somewhat compatible.
98 */
99#define ADS_START (1 << 7)
100#define ADS_A2A1A0_d_y (1 << 4) /* differential */
101#define ADS_A2A1A0_d_z1 (3 << 4) /* differential */
102#define ADS_A2A1A0_d_z2 (4 << 4) /* differential */
103#define ADS_A2A1A0_d_x (5 << 4) /* differential */
104#define ADS_A2A1A0_temp0 (0 << 4) /* non-differential */
105#define ADS_A2A1A0_vbatt (2 << 4) /* non-differential */
106#define ADS_A2A1A0_vaux (6 << 4) /* non-differential */
107#define ADS_A2A1A0_temp1 (7 << 4) /* non-differential */
108#define ADS_8_BIT (1 << 3)
109#define ADS_12_BIT (0 << 3)
110#define ADS_SER (1 << 2) /* non-differential */
111#define ADS_DFR (0 << 2) /* differential */
112#define ADS_PD10_PDOWN (0 << 0) /* lowpower mode + penirq */
113#define ADS_PD10_ADC_ON (1 << 0) /* ADC on */
114#define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */
115#define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */
116
117#define MAX_12BIT ((1<<12)-1)
118
119/* leave ADC powered up (disables penirq) between differential samples */
120#define READ_12BIT_DFR(x) (ADS_START | ADS_A2A1A0_d_ ## x \
121 | ADS_12_BIT | ADS_DFR)
122
123static const u8 read_y = READ_12BIT_DFR(y) | ADS_PD10_ADC_ON;
124static const u8 read_z1 = READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON;
125static const u8 read_z2 = READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON;
126static const u8 read_x = READ_12BIT_DFR(x) | ADS_PD10_PDOWN; /* LAST */
127
128/* single-ended samples need to first power up reference voltage;
129 * we leave both ADC and VREF powered
130 */
131#define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \
132 | ADS_12_BIT | ADS_SER)
133
134static const u8 ref_on = READ_12BIT_DFR(x) | ADS_PD10_ALL_ON;
135static const u8 ref_off = READ_12BIT_DFR(y) | ADS_PD10_PDOWN;
136
137/*--------------------------------------------------------------------------*/
138
139/*
140 * Non-touchscreen sensors only use single-ended conversions.
141 */
142
143struct ser_req {
144 u8 command;
145 u16 scratch;
146 __be16 sample;
147 struct spi_message msg;
148 struct spi_transfer xfer[6];
149};
150
151static int ads7846_read12_ser(struct device *dev, unsigned command)
152{
153 struct spi_device *spi = to_spi_device(dev);
154 struct ads7846 *ts = dev_get_drvdata(dev);
155 struct ser_req *req = kzalloc(sizeof *req, SLAB_KERNEL);
156 int status;
157 int sample;
158 int i;
159
160 if (!req)
161 return -ENOMEM;
162
163 INIT_LIST_HEAD(&req->msg.transfers);
164
165 /* activate reference, so it has time to settle; */
166 req->xfer[0].tx_buf = &ref_on;
167 req->xfer[0].len = 1;
168 req->xfer[1].rx_buf = &req->scratch;
169 req->xfer[1].len = 2;
170
171 /*
172 * for external VREF, 0 usec (and assume it's always on);
173 * for 1uF, use 800 usec;
174 * no cap, 100 usec.
175 */
176 req->xfer[1].delay_usecs = ts->vref_delay_usecs;
177
178 /* take sample */
179 req->command = (u8) command;
180 req->xfer[2].tx_buf = &req->command;
181 req->xfer[2].len = 1;
182 req->xfer[3].rx_buf = &req->sample;
183 req->xfer[3].len = 2;
184
185 /* REVISIT: take a few more samples, and compare ... */
186
187 /* turn off reference */
188 req->xfer[4].tx_buf = &ref_off;
189 req->xfer[4].len = 1;
190 req->xfer[5].rx_buf = &req->scratch;
191 req->xfer[5].len = 2;
192
193 CS_CHANGE(req->xfer[5]);
194
195 /* group all the transfers together, so we can't interfere with
196 * reading touchscreen state; disable penirq while sampling
197 */
198 for (i = 0; i < 6; i++)
199 spi_message_add_tail(&req->xfer[i], &req->msg);
200
201 disable_irq(spi->irq);
202 status = spi_sync(spi, &req->msg);
203 enable_irq(spi->irq);
204
205 if (req->msg.status)
206 status = req->msg.status;
207 sample = be16_to_cpu(req->sample);
208 sample = sample >> 4;
209 kfree(req);
210
211 return status ? status : sample;
212}
213
214#define SHOW(name) static ssize_t \
215name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
216{ \
217 ssize_t v = ads7846_read12_ser(dev, \
218 READ_12BIT_SER(name) | ADS_PD10_ALL_ON); \
219 if (v < 0) \
220 return v; \
221 return sprintf(buf, "%u\n", (unsigned) v); \
222} \
223static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
224
225SHOW(temp0)
226SHOW(temp1)
227SHOW(vaux)
228SHOW(vbatt)
229
230/*--------------------------------------------------------------------------*/
231
232/*
233 * PENIRQ only kicks the timer. The timer only reissues the SPI transfer,
234 * to retrieve touchscreen status.
235 *
236 * The SPI transfer completion callback does the real work. It reports
237 * touchscreen events and reactivates the timer (or IRQ) as appropriate.
238 */
239
240static void ads7846_rx(void *ads)
241{
242 struct ads7846 *ts = ads;
243 unsigned Rt;
244 unsigned sync = 0;
245 u16 x, y, z1, z2;
246 unsigned long flags;
247
248 /* adjust: 12 bit samples (left aligned), built from
249 * two 8 bit values writen msb-first.
250 */
251 x = be16_to_cpu(ts->tc.x) >> 4;
252 y = be16_to_cpu(ts->tc.y) >> 4;
253 z1 = be16_to_cpu(ts->tc.z1) >> 4;
254 z2 = be16_to_cpu(ts->tc.z2) >> 4;
255
256 /* range filtering */
257 if (x == MAX_12BIT)
258 x = 0;
259
260 if (x && z1 && ts->spi->dev.power.power_state.event == PM_EVENT_ON) {
261 /* compute touch pressure resistance using equation #2 */
262 Rt = z2;
263 Rt -= z1;
264 Rt *= x;
265 Rt *= ts->x_plate_ohms;
266 Rt /= z1;
267 Rt = (Rt + 2047) >> 12;
268 } else
269 Rt = 0;
270
271 /* NOTE: "pendown" is inferred from pressure; we don't rely on
272 * being able to check nPENIRQ status, or "friendly" trigger modes
273 * (both-edges is much better than just-falling or low-level).
274 *
275 * REVISIT: some boards may require reading nPENIRQ; it's
276 * needed on 7843. and 7845 reads pressure differently...
277 *
278 * REVISIT: the touchscreen might not be connected; this code
279 * won't notice that, even if nPENIRQ never fires ...
280 */
281 if (!ts->pendown && Rt != 0) {
282 input_report_key(&ts->input, BTN_TOUCH, 1);
283 sync = 1;
284 } else if (ts->pendown && Rt == 0) {
285 input_report_key(&ts->input, BTN_TOUCH, 0);
286 sync = 1;
287 }
288
289 if (Rt) {
290 input_report_abs(&ts->input, ABS_X, x);
291 input_report_abs(&ts->input, ABS_Y, y);
292 input_report_abs(&ts->input, ABS_PRESSURE, Rt);
293 sync = 1;
294 }
295 if (sync)
296 input_sync(&ts->input);
297
298#ifdef VERBOSE
299 if (Rt || ts->pendown)
300 pr_debug("%s: %d/%d/%d%s\n", ts->spi->dev.bus_id,
301 x, y, Rt, Rt ? "" : " UP");
302#endif
303
304 /* don't retrigger while we're suspended */
305 spin_lock_irqsave(&ts->lock, flags);
306
307 ts->pendown = (Rt != 0);
308 ts->pending = 0;
309
310 if (ts->spi->dev.power.power_state.event == PM_EVENT_ON) {
311 if (ts->pendown)
312 mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
313 else if (ts->irq_disabled) {
314 ts->irq_disabled = 0;
315 enable_irq(ts->spi->irq);
316 }
317 }
318
319 spin_unlock_irqrestore(&ts->lock, flags);
320}
321
322static void ads7846_timer(unsigned long handle)
323{
324 struct ads7846 *ts = (void *)handle;
325 int status = 0;
326 unsigned long flags;
327
328 spin_lock_irqsave(&ts->lock, flags);
329 if (!ts->pending) {
330 ts->pending = 1;
331 if (!ts->irq_disabled) {
332 ts->irq_disabled = 1;
333 disable_irq(ts->spi->irq);
334 }
335 status = spi_async(ts->spi, &ts->msg);
336 if (status)
337 dev_err(&ts->spi->dev, "spi_async --> %d\n",
338 status);
339 }
340 spin_unlock_irqrestore(&ts->lock, flags);
341}
342
343static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
344{
345 ads7846_timer((unsigned long) handle);
346 return IRQ_HANDLED;
347}
348
349/*--------------------------------------------------------------------------*/
350
351static int
352ads7846_suspend(struct spi_device *spi, pm_message_t message)
353{
354 struct ads7846 *ts = dev_get_drvdata(&spi->dev);
355 unsigned long flags;
356
357 spin_lock_irqsave(&ts->lock, flags);
358
359 spi->dev.power.power_state = message;
360
361 /* are we waiting for IRQ, or polling? */
362 if (!ts->pendown) {
363 if (!ts->irq_disabled) {
364 ts->irq_disabled = 1;
365 disable_irq(ts->spi->irq);
366 }
367 } else {
368 /* polling; force a final SPI completion;
369 * that will clean things up neatly
370 */
371 if (!ts->pending)
372 mod_timer(&ts->timer, jiffies);
373
374 while (ts->pendown || ts->pending) {
375 spin_unlock_irqrestore(&ts->lock, flags);
376 udelay(10);
377 spin_lock_irqsave(&ts->lock, flags);
378 }
379 }
380
381 /* we know the chip's in lowpower mode since we always
382 * leave it that way after every request
383 */
384
385 spin_unlock_irqrestore(&ts->lock, flags);
386 return 0;
387}
388
389static int ads7846_resume(struct spi_device *spi)
390{
391 struct ads7846 *ts = dev_get_drvdata(&spi->dev);
392
393 ts->irq_disabled = 0;
394 enable_irq(ts->spi->irq);
395 spi->dev.power.power_state = PMSG_ON;
396 return 0;
397}
398
399static int __devinit ads7846_probe(struct spi_device *spi)
400{
401 struct ads7846 *ts;
402 struct ads7846_platform_data *pdata = spi->dev.platform_data;
403 struct spi_transfer *x;
404 int i;
405
406 if (!spi->irq) {
407 dev_dbg(&spi->dev, "no IRQ?\n");
408 return -ENODEV;
409 }
410
411 if (!pdata) {
412 dev_dbg(&spi->dev, "no platform data?\n");
413 return -ENODEV;
414 }
415
416 /* don't exceed max specified sample rate */
417 if (spi->max_speed_hz > (125000 * 16)) {
418 dev_dbg(&spi->dev, "f(sample) %d KHz?\n",
419 (spi->max_speed_hz/16)/1000);
420 return -EINVAL;
421 }
422
423 /* We'd set the wordsize to 12 bits ... except that some controllers
424 * will then treat the 8 bit command words as 12 bits (and drop the
425 * four MSBs of the 12 bit result). Result: inputs must be shifted
426 * to discard the four garbage LSBs.
427 */
428
429 if (!(ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL)))
430 return -ENOMEM;
431
432 dev_set_drvdata(&spi->dev, ts);
433
434 ts->spi = spi;
435 spi->dev.power.power_state = PMSG_ON;
436
437 init_timer(&ts->timer);
438 ts->timer.data = (unsigned long) ts;
439 ts->timer.function = ads7846_timer;
440
441 ts->model = pdata->model ? : 7846;
442 ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
443 ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
444
445 init_input_dev(&ts->input);
446
447 ts->input.dev = &spi->dev;
448 ts->input.name = "ADS784x Touchscreen";
449 snprintf(ts->phys, sizeof ts->phys, "%s/input0", spi->dev.bus_id);
450 ts->input.phys = ts->phys;
451
452 ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
453 ts->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
454 input_set_abs_params(&ts->input, ABS_X,
455 pdata->x_min ? : 0,
456 pdata->x_max ? : MAX_12BIT,
457 0, 0);
458 input_set_abs_params(&ts->input, ABS_Y,
459 pdata->y_min ? : 0,
460 pdata->y_max ? : MAX_12BIT,
461 0, 0);
462 input_set_abs_params(&ts->input, ABS_PRESSURE,
463 pdata->pressure_min, pdata->pressure_max, 0, 0);
464
465 input_register_device(&ts->input);
466
467 /* set up the transfers to read touchscreen state; this assumes we
468 * use formula #2 for pressure, not #3.
469 */
470 x = ts->xfer;
471
472 /* y- still on; turn on only y+ (and ADC) */
473 x->tx_buf = &read_y;
474 x->len = 1;
475 x++;
476 x->rx_buf = &ts->tc.y;
477 x->len = 2;
478 x++;
479
480 /* turn y+ off, x- on; we'll use formula #2 */
481 if (ts->model == 7846) {
482 x->tx_buf = &read_z1;
483 x->len = 1;
484 x++;
485 x->rx_buf = &ts->tc.z1;
486 x->len = 2;
487 x++;
488
489 x->tx_buf = &read_z2;
490 x->len = 1;
491 x++;
492 x->rx_buf = &ts->tc.z2;
493 x->len = 2;
494 x++;
495 }
496
497 /* turn y- off, x+ on, then leave in lowpower */
498 x->tx_buf = &read_x;
499 x->len = 1;
500 x++;
501 x->rx_buf = &ts->tc.x;
502 x->len = 2;
503 x++;
504
505 CS_CHANGE(x[-1]);
506
507 for (i = 0; i < x - ts->xfer; i++)
508 spi_message_add_tail(&ts->xfer[i], &ts->msg);
509 ts->msg.complete = ads7846_rx;
510 ts->msg.context = ts;
511
512 if (request_irq(spi->irq, ads7846_irq, SA_SAMPLE_RANDOM,
513 spi->dev.bus_id, ts)) {
514 dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
515 input_unregister_device(&ts->input);
516 kfree(ts);
517 return -EBUSY;
518 }
519 set_irq_type(spi->irq, IRQT_FALLING);
520
521 dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq);
522
523 /* take a first sample, leaving nPENIRQ active; avoid
524 * the touchscreen, in case it's not connected.
525 */
526 (void) ads7846_read12_ser(&spi->dev,
527 READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
528
529 /* ads7843/7845 don't have temperature sensors, and
530 * use the other sensors a bit differently too
531 */
532 if (ts->model == 7846) {
533 device_create_file(&spi->dev, &dev_attr_temp0);
534 device_create_file(&spi->dev, &dev_attr_temp1);
535 }
536 if (ts->model != 7845)
537 device_create_file(&spi->dev, &dev_attr_vbatt);
538 device_create_file(&spi->dev, &dev_attr_vaux);
539
540 return 0;
541}
542
543static int __devexit ads7846_remove(struct spi_device *spi)
544{
545 struct ads7846 *ts = dev_get_drvdata(&spi->dev);
546
547 ads7846_suspend(spi, PMSG_SUSPEND);
548 free_irq(ts->spi->irq, ts);
549 if (ts->irq_disabled)
550 enable_irq(ts->spi->irq);
551
552 if (ts->model == 7846) {
553 device_remove_file(&spi->dev, &dev_attr_temp0);
554 device_remove_file(&spi->dev, &dev_attr_temp1);
555 }
556 if (ts->model != 7845)
557 device_remove_file(&spi->dev, &dev_attr_vbatt);
558 device_remove_file(&spi->dev, &dev_attr_vaux);
559
560 input_unregister_device(&ts->input);
561 kfree(ts);
562
563 dev_dbg(&spi->dev, "unregistered touchscreen\n");
564 return 0;
565}
566
567static struct spi_driver ads7846_driver = {
568 .driver = {
569 .name = "ads7846",
570 .bus = &spi_bus_type,
571 .owner = THIS_MODULE,
572 },
573 .probe = ads7846_probe,
574 .remove = __devexit_p(ads7846_remove),
575 .suspend = ads7846_suspend,
576 .resume = ads7846_resume,
577};
578
579static int __init ads7846_init(void)
580{
581 /* grr, board-specific init should stay out of drivers!! */
582
583#ifdef CONFIG_ARCH_OMAP
584 if (machine_is_omap_osk()) {
585 /* GPIO4 = PENIRQ; GPIO6 = BUSY */
586 omap_request_gpio(4);
587 omap_set_gpio_direction(4, 1);
588 omap_request_gpio(6);
589 omap_set_gpio_direction(6, 1);
590 }
591 // also TI 1510 Innovator, bitbanging through FPGA
592 // also Nokia 770
593 // also Palm Tungsten T2
594#endif
595
596 // PXA:
597 // also Dell Axim X50
598 // also HP iPaq H191x/H192x/H415x/H435x
599 // also Intel Lubbock (additional to UCB1400; as temperature sensor)
600 // also Sharp Zaurus C7xx, C8xx (corgi/sheperd/husky)
601
602 // Atmel at91sam9261-EK uses ads7843
603
604 // also various AMD Au1x00 devel boards
605
606 return spi_register_driver(&ads7846_driver);
607}
608module_init(ads7846_init);
609
610static void __exit ads7846_exit(void)
611{
612 spi_unregister_driver(&ads7846_driver);
613
614#ifdef CONFIG_ARCH_OMAP
615 if (machine_is_omap_osk()) {
616 omap_free_gpio(4);
617 omap_free_gpio(6);
618 }
619#endif
620
621}
622module_exit(ads7846_exit);
623
624MODULE_DESCRIPTION("ADS7846 TouchScreen Driver");
625MODULE_LICENSE("GPL");
diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index 71aeb912ec61..d56d400b6aaa 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -239,7 +239,7 @@ static int adb_iop_write(struct adb_request *req)
239 239
240 local_irq_save(flags); 240 local_irq_save(flags);
241 241
242 req->next = 0; 242 req->next = NULL;
243 req->sent = 0; 243 req->sent = 0;
244 req->complete = 0; 244 req->complete = 0;
245 req->reply_len = 0; 245 req->reply_len = 0;
diff --git a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c
index cf6a6f2248ac..314fc0830d90 100644
--- a/drivers/macintosh/macio-adb.c
+++ b/drivers/macintosh/macio-adb.c
@@ -17,6 +17,7 @@
17#include <asm/irq.h> 17#include <asm/irq.h>
18#include <asm/system.h> 18#include <asm/system.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/ioport.h>
20 21
21struct preg { 22struct preg {
22 unsigned char r; 23 unsigned char r;
@@ -88,24 +89,26 @@ int macio_probe(void)
88int macio_init(void) 89int macio_init(void)
89{ 90{
90 struct device_node *adbs; 91 struct device_node *adbs;
92 struct resource r;
91 93
92 adbs = find_compatible_devices("adb", "chrp,adb0"); 94 adbs = find_compatible_devices("adb", "chrp,adb0");
93 if (adbs == 0) 95 if (adbs == 0)
94 return -ENXIO; 96 return -ENXIO;
95 97
96#if 0 98#if 0
97 { int i; 99 { int i = 0;
98 100
99 printk("macio_adb_init: node = %p, addrs =", adbs->node); 101 printk("macio_adb_init: node = %p, addrs =", adbs->node);
100 for (i = 0; i < adbs->n_addrs; ++i) 102 while(!of_address_to_resource(adbs, i, &r))
101 printk(" %x(%x)", adbs->addrs[i].address, adbs->addrs[i].size); 103 printk(" %x(%x)", r.start, r.end - r.start);
102 printk(", intrs ="); 104 printk(", intrs =");
103 for (i = 0; i < adbs->n_intrs; ++i) 105 for (i = 0; i < adbs->n_intrs; ++i)
104 printk(" %x", adbs->intrs[i].line); 106 printk(" %x", adbs->intrs[i].line);
105 printk("\n"); } 107 printk("\n"); }
106#endif 108#endif
107 109 if (of_address_to_resource(adbs, 0, &r))
108 adb = ioremap(adbs->addrs->address, sizeof(struct adb_regs)); 110 return -ENXIO;
111 adb = ioremap(r.start, sizeof(struct adb_regs));
109 112
110 out_8(&adb->ctrl.r, 0); 113 out_8(&adb->ctrl.r, 0);
111 out_8(&adb->intr.r, 0); 114 out_8(&adb->intr.r, 0);
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 2a545ceb523b..ed6d3174d660 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -211,6 +211,9 @@ struct bus_type macio_bus_type = {
211 .name = "macio", 211 .name = "macio",
212 .match = macio_bus_match, 212 .match = macio_bus_match,
213 .uevent = macio_uevent, 213 .uevent = macio_uevent,
214 .probe = macio_device_probe,
215 .remove = macio_device_remove,
216 .shutdown = macio_device_shutdown,
214 .suspend = macio_device_suspend, 217 .suspend = macio_device_suspend,
215 .resume = macio_device_resume, 218 .resume = macio_device_resume,
216 .dev_attrs = macio_dev_attrs, 219 .dev_attrs = macio_dev_attrs,
@@ -528,9 +531,6 @@ int macio_register_driver(struct macio_driver *drv)
528 /* initialize common driver fields */ 531 /* initialize common driver fields */
529 drv->driver.name = drv->name; 532 drv->driver.name = drv->name;
530 drv->driver.bus = &macio_bus_type; 533 drv->driver.bus = &macio_bus_type;
531 drv->driver.probe = macio_device_probe;
532 drv->driver.remove = macio_device_remove;
533 drv->driver.shutdown = macio_device_shutdown;
534 534
535 /* register with core */ 535 /* register with core */
536 count = driver_register(&drv->driver); 536 count = driver_register(&drv->driver);
diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
index e9a159ad3022..2a2ffe060169 100644
--- a/drivers/macintosh/via-macii.c
+++ b/drivers/macintosh/via-macii.c
@@ -260,7 +260,7 @@ static int macii_write(struct adb_request *req)
260 return -EINVAL; 260 return -EINVAL;
261 } 261 }
262 262
263 req->next = 0; 263 req->next = NULL;
264 req->sent = 0; 264 req->sent = 0;
265 req->complete = 0; 265 req->complete = 0;
266 req->reply_len = 0; 266 req->reply_len = 0;
@@ -295,7 +295,7 @@ static void macii_poll(void)
295 unsigned long flags; 295 unsigned long flags;
296 296
297 local_irq_save(flags); 297 local_irq_save(flags);
298 if (via[IFR] & SR_INT) macii_interrupt(0, 0, 0); 298 if (via[IFR] & SR_INT) macii_interrupt(0, NULL, NULL);
299 local_irq_restore(flags); 299 local_irq_restore(flags);
300} 300}
301 301
diff --git a/drivers/macintosh/via-maciisi.c b/drivers/macintosh/via-maciisi.c
index a1966975d58f..0129fcc3b183 100644
--- a/drivers/macintosh/via-maciisi.c
+++ b/drivers/macintosh/via-maciisi.c
@@ -294,6 +294,24 @@ static void maciisi_sync(struct adb_request *req)
294 printk(KERN_ERR "maciisi_send_request: poll timed out!\n"); 294 printk(KERN_ERR "maciisi_send_request: poll timed out!\n");
295} 295}
296 296
297int
298maciisi_request(struct adb_request *req, void (*done)(struct adb_request *),
299 int nbytes, ...)
300{
301 va_list list;
302 int i;
303
304 req->nbytes = nbytes;
305 req->done = done;
306 req->reply_expected = 0;
307 va_start(list, nbytes);
308 for (i = 0; i < nbytes; i++)
309 req->data[i++] = va_arg(list, int);
310 va_end(list);
311
312 return maciisi_send_request(req, 1);
313}
314
297/* Enqueue a request, and run the queue if possible */ 315/* Enqueue a request, and run the queue if possible */
298static int 316static int
299maciisi_write(struct adb_request* req) 317maciisi_write(struct adb_request* req)
@@ -308,7 +326,7 @@ maciisi_write(struct adb_request* req)
308 req->complete = 1; 326 req->complete = 1;
309 return -EINVAL; 327 return -EINVAL;
310 } 328 }
311 req->next = 0; 329 req->next = NULL;
312 req->sent = 0; 330 req->sent = 0;
313 req->complete = 0; 331 req->complete = 0;
314 req->reply_len = 0; 332 req->reply_len = 0;
@@ -403,7 +421,7 @@ maciisi_poll(void)
403 421
404 local_irq_save(flags); 422 local_irq_save(flags);
405 if (via[IFR] & SR_INT) { 423 if (via[IFR] & SR_INT) {
406 maciisi_interrupt(0, 0, 0); 424 maciisi_interrupt(0, NULL, NULL);
407 } 425 }
408 else /* avoid calling this function too quickly in a loop */ 426 else /* avoid calling this function too quickly in a loop */
409 udelay(ADB_DELAY); 427 udelay(ADB_DELAY);
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c
index 6f80d76ac17c..f08e52f2107b 100644
--- a/drivers/macintosh/via-pmu68k.c
+++ b/drivers/macintosh/via-pmu68k.c
@@ -493,7 +493,7 @@ pmu_queue_request(struct adb_request *req)
493 return -EINVAL; 493 return -EINVAL;
494 } 494 }
495 495
496 req->next = 0; 496 req->next = NULL;
497 req->sent = 0; 497 req->sent = 0;
498 req->complete = 0; 498 req->complete = 0;
499 local_irq_save(flags); 499 local_irq_save(flags);
@@ -717,7 +717,7 @@ pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs)
717 printk(KERN_ERR "PMU: extra ADB reply\n"); 717 printk(KERN_ERR "PMU: extra ADB reply\n");
718 return; 718 return;
719 } 719 }
720 req_awaiting_reply = 0; 720 req_awaiting_reply = NULL;
721 if (len <= 2) 721 if (len <= 2)
722 req->reply_len = 0; 722 req->reply_len = 0;
723 else { 723 else {
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 0302723fa21f..1778104e106c 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1238,6 +1238,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1238 mdk_rdev_t *same_pdev; 1238 mdk_rdev_t *same_pdev;
1239 char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; 1239 char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
1240 struct kobject *ko; 1240 struct kobject *ko;
1241 char *s;
1241 1242
1242 if (rdev->mddev) { 1243 if (rdev->mddev) {
1243 MD_BUG(); 1244 MD_BUG();
@@ -1277,6 +1278,8 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1277 bdevname(rdev->bdev,b); 1278 bdevname(rdev->bdev,b);
1278 if (kobject_set_name(&rdev->kobj, "dev-%s", b) < 0) 1279 if (kobject_set_name(&rdev->kobj, "dev-%s", b) < 0)
1279 return -ENOMEM; 1280 return -ENOMEM;
1281 while ( (s=strchr(rdev->kobj.k_name, '/')) != NULL)
1282 *s = '!';
1280 1283
1281 list_add(&rdev->same_set, &mddev->disks); 1284 list_add(&rdev->same_set, &mddev->disks);
1282 rdev->mddev = mddev; 1285 rdev->mddev = mddev;
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index f65f64b00ff3..44fcbe77c8f9 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -779,9 +779,8 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
779 return 0; 779 return 0;
780} 780}
781 781
782static int dvb_bt8xx_probe(struct device *dev) 782static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
783{ 783{
784 struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
785 struct dvb_bt8xx_card *card; 784 struct dvb_bt8xx_card *card;
786 struct pci_dev* bttv_pci_dev; 785 struct pci_dev* bttv_pci_dev;
787 int ret; 786 int ret;
@@ -890,13 +889,13 @@ static int dvb_bt8xx_probe(struct device *dev)
890 return ret; 889 return ret;
891 } 890 }
892 891
893 dev_set_drvdata(dev, card); 892 dev_set_drvdata(&sub->dev, card);
894 return 0; 893 return 0;
895} 894}
896 895
897static int dvb_bt8xx_remove(struct device *dev) 896static int dvb_bt8xx_remove(struct bttv_sub_device *sub)
898{ 897{
899 struct dvb_bt8xx_card *card = dev_get_drvdata(dev); 898 struct dvb_bt8xx_card *card = dev_get_drvdata(&sub->dev);
900 899
901 dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr); 900 dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr);
902 901
@@ -919,14 +918,14 @@ static int dvb_bt8xx_remove(struct device *dev)
919static struct bttv_sub_driver driver = { 918static struct bttv_sub_driver driver = {
920 .drv = { 919 .drv = {
921 .name = "dvb-bt8xx", 920 .name = "dvb-bt8xx",
922 .probe = dvb_bt8xx_probe,
923 .remove = dvb_bt8xx_remove,
924 /* FIXME:
925 * .shutdown = dvb_bt8xx_shutdown,
926 * .suspend = dvb_bt8xx_suspend,
927 * .resume = dvb_bt8xx_resume,
928 */
929 }, 921 },
922 .probe = dvb_bt8xx_probe,
923 .remove = dvb_bt8xx_remove,
924 /* FIXME:
925 * .shutdown = dvb_bt8xx_shutdown,
926 * .suspend = dvb_bt8xx_suspend,
927 * .resume = dvb_bt8xx_resume,
928 */
930}; 929};
931 930
932static int __init dvb_bt8xx_init(void) 931static int __init dvb_bt8xx_init(void)
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c
index d64accc17b0e..c4d5e2b70c28 100644
--- a/drivers/media/video/bttv-gpio.c
+++ b/drivers/media/video/bttv-gpio.c
@@ -47,9 +47,29 @@ static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv)
47 return 0; 47 return 0;
48} 48}
49 49
50static int bttv_sub_probe(struct device *dev)
51{
52 struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
53 struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
54
55 return sub->probe ? sub->probe(sdev) : -ENODEV;
56}
57
58static int bttv_sub_remove(struct device *dev)
59{
60 struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
61 struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
62
63 if (sub->remove)
64 sub->remove(sdev);
65 return 0;
66}
67
50struct bus_type bttv_sub_bus_type = { 68struct bus_type bttv_sub_bus_type = {
51 .name = "bttv-sub", 69 .name = "bttv-sub",
52 .match = &bttv_sub_bus_match, 70 .match = &bttv_sub_bus_match,
71 .probe = bttv_sub_probe,
72 .remove = bttv_sub_remove,
53}; 73};
54EXPORT_SYMBOL(bttv_sub_bus_type); 74EXPORT_SYMBOL(bttv_sub_bus_type);
55 75
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index e370d74f2a1b..9908c8e0c951 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -365,6 +365,8 @@ struct bttv_sub_device {
365struct bttv_sub_driver { 365struct bttv_sub_driver {
366 struct device_driver drv; 366 struct device_driver drv;
367 char wanted[BUS_ID_SIZE]; 367 char wanted[BUS_ID_SIZE];
368 int (*probe)(struct bttv_sub_device *sub);
369 void (*remove)(struct bttv_sub_device *sub);
368 void (*gpio_irq)(struct bttv_sub_device *sub); 370 void (*gpio_irq)(struct bttv_sub_device *sub);
369}; 371};
370#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) 372#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv)
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index 55ba23075c90..75f401d52fda 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -77,6 +77,8 @@ static int mcp_bus_resume(struct device *dev)
77static struct bus_type mcp_bus_type = { 77static struct bus_type mcp_bus_type = {
78 .name = "mcp", 78 .name = "mcp",
79 .match = mcp_bus_match, 79 .match = mcp_bus_match,
80 .probe = mcp_bus_probe,
81 .remove = mcp_bus_remove,
80 .suspend = mcp_bus_suspend, 82 .suspend = mcp_bus_suspend,
81 .resume = mcp_bus_resume, 83 .resume = mcp_bus_resume,
82}; 84};
@@ -227,8 +229,6 @@ EXPORT_SYMBOL(mcp_host_unregister);
227int mcp_driver_register(struct mcp_driver *mcpdrv) 229int mcp_driver_register(struct mcp_driver *mcpdrv)
228{ 230{
229 mcpdrv->drv.bus = &mcp_bus_type; 231 mcpdrv->drv.bus = &mcp_bus_type;
230 mcpdrv->drv.probe = mcp_bus_probe;
231 mcpdrv->drv.remove = mcp_bus_remove;
232 return driver_register(&mcpdrv->drv); 232 return driver_register(&mcpdrv->drv);
233} 233}
234EXPORT_SYMBOL(mcp_driver_register); 234EXPORT_SYMBOL(mcp_driver_register);
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index b42e0fbab59b..aff83f966803 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -24,13 +24,14 @@
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/device.h> 26#include <linux/device.h>
27#include <linux/mutex.h>
27 28
28#include <asm/dma.h> 29#include <asm/dma.h>
29#include <asm/hardware.h> 30#include <asm/hardware.h>
30 31
31#include "ucb1x00.h" 32#include "ucb1x00.h"
32 33
33static DECLARE_MUTEX(ucb1x00_sem); 34static DEFINE_MUTEX(ucb1x00_mutex);
34static LIST_HEAD(ucb1x00_drivers); 35static LIST_HEAD(ucb1x00_drivers);
35static LIST_HEAD(ucb1x00_devices); 36static LIST_HEAD(ucb1x00_devices);
36 37
@@ -521,12 +522,12 @@ static int ucb1x00_probe(struct mcp *mcp)
521 goto err_irq; 522 goto err_irq;
522 523
523 INIT_LIST_HEAD(&ucb->devs); 524 INIT_LIST_HEAD(&ucb->devs);
524 down(&ucb1x00_sem); 525 mutex_lock(&ucb1x00_mutex);
525 list_add(&ucb->node, &ucb1x00_devices); 526 list_add(&ucb->node, &ucb1x00_devices);
526 list_for_each_entry(drv, &ucb1x00_drivers, node) { 527 list_for_each_entry(drv, &ucb1x00_drivers, node) {
527 ucb1x00_add_dev(ucb, drv); 528 ucb1x00_add_dev(ucb, drv);
528 } 529 }
529 up(&ucb1x00_sem); 530 mutex_unlock(&ucb1x00_mutex);
530 goto out; 531 goto out;
531 532
532 err_irq: 533 err_irq:
@@ -544,13 +545,13 @@ static void ucb1x00_remove(struct mcp *mcp)
544 struct ucb1x00 *ucb = mcp_get_drvdata(mcp); 545 struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
545 struct list_head *l, *n; 546 struct list_head *l, *n;
546 547
547 down(&ucb1x00_sem); 548 mutex_lock(&ucb1x00_mutex);
548 list_del(&ucb->node); 549 list_del(&ucb->node);
549 list_for_each_safe(l, n, &ucb->devs) { 550 list_for_each_safe(l, n, &ucb->devs) {
550 struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, dev_node); 551 struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, dev_node);
551 ucb1x00_remove_dev(dev); 552 ucb1x00_remove_dev(dev);
552 } 553 }
553 up(&ucb1x00_sem); 554 mutex_unlock(&ucb1x00_mutex);
554 555
555 free_irq(ucb->irq, ucb); 556 free_irq(ucb->irq, ucb);
556 class_device_unregister(&ucb->cdev); 557 class_device_unregister(&ucb->cdev);
@@ -561,12 +562,12 @@ int ucb1x00_register_driver(struct ucb1x00_driver *drv)
561 struct ucb1x00 *ucb; 562 struct ucb1x00 *ucb;
562 563
563 INIT_LIST_HEAD(&drv->devs); 564 INIT_LIST_HEAD(&drv->devs);
564 down(&ucb1x00_sem); 565 mutex_lock(&ucb1x00_mutex);
565 list_add(&drv->node, &ucb1x00_drivers); 566 list_add(&drv->node, &ucb1x00_drivers);
566 list_for_each_entry(ucb, &ucb1x00_devices, node) { 567 list_for_each_entry(ucb, &ucb1x00_devices, node) {
567 ucb1x00_add_dev(ucb, drv); 568 ucb1x00_add_dev(ucb, drv);
568 } 569 }
569 up(&ucb1x00_sem); 570 mutex_unlock(&ucb1x00_mutex);
570 return 0; 571 return 0;
571} 572}
572 573
@@ -574,13 +575,13 @@ void ucb1x00_unregister_driver(struct ucb1x00_driver *drv)
574{ 575{
575 struct list_head *n, *l; 576 struct list_head *n, *l;
576 577
577 down(&ucb1x00_sem); 578 mutex_lock(&ucb1x00_mutex);
578 list_del(&drv->node); 579 list_del(&drv->node);
579 list_for_each_safe(l, n, &drv->devs) { 580 list_for_each_safe(l, n, &drv->devs) {
580 struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, drv_node); 581 struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, drv_node);
581 ucb1x00_remove_dev(dev); 582 ucb1x00_remove_dev(dev);
582 } 583 }
583 up(&ucb1x00_sem); 584 mutex_unlock(&ucb1x00_mutex);
584} 585}
585 586
586static int ucb1x00_suspend(struct mcp *mcp, pm_message_t state) 587static int ucb1x00_suspend(struct mcp *mcp, pm_message_t state)
@@ -588,12 +589,12 @@ static int ucb1x00_suspend(struct mcp *mcp, pm_message_t state)
588 struct ucb1x00 *ucb = mcp_get_drvdata(mcp); 589 struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
589 struct ucb1x00_dev *dev; 590 struct ucb1x00_dev *dev;
590 591
591 down(&ucb1x00_sem); 592 mutex_lock(&ucb1x00_mutex);
592 list_for_each_entry(dev, &ucb->devs, dev_node) { 593 list_for_each_entry(dev, &ucb->devs, dev_node) {
593 if (dev->drv->suspend) 594 if (dev->drv->suspend)
594 dev->drv->suspend(dev, state); 595 dev->drv->suspend(dev, state);
595 } 596 }
596 up(&ucb1x00_sem); 597 mutex_unlock(&ucb1x00_mutex);
597 return 0; 598 return 0;
598} 599}
599 600
@@ -602,12 +603,12 @@ static int ucb1x00_resume(struct mcp *mcp)
602 struct ucb1x00 *ucb = mcp_get_drvdata(mcp); 603 struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
603 struct ucb1x00_dev *dev; 604 struct ucb1x00_dev *dev;
604 605
605 down(&ucb1x00_sem); 606 mutex_lock(&ucb1x00_mutex);
606 list_for_each_entry(dev, &ucb->devs, dev_node) { 607 list_for_each_entry(dev, &ucb->devs, dev_node) {
607 if (dev->drv->resume) 608 if (dev->drv->resume)
608 dev->drv->resume(dev); 609 dev->drv->resume(dev);
609 } 610 }
610 up(&ucb1x00_sem); 611 mutex_unlock(&ucb1x00_mutex);
611 return 0; 612 return 0;
612} 613}
613 614
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index f2c42b13945d..9b7c37e0e574 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -28,6 +28,7 @@
28#include <linux/kdev_t.h> 28#include <linux/kdev_t.h>
29#include <linux/blkdev.h> 29#include <linux/blkdev.h>
30#include <linux/devfs_fs_kernel.h> 30#include <linux/devfs_fs_kernel.h>
31#include <linux/mutex.h>
31 32
32#include <linux/mmc/card.h> 33#include <linux/mmc/card.h>
33#include <linux/mmc/protocol.h> 34#include <linux/mmc/protocol.h>
@@ -57,33 +58,33 @@ struct mmc_blk_data {
57 unsigned int read_only; 58 unsigned int read_only;
58}; 59};
59 60
60static DECLARE_MUTEX(open_lock); 61static DEFINE_MUTEX(open_lock);
61 62
62static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) 63static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
63{ 64{
64 struct mmc_blk_data *md; 65 struct mmc_blk_data *md;
65 66
66 down(&open_lock); 67 mutex_lock(&open_lock);
67 md = disk->private_data; 68 md = disk->private_data;
68 if (md && md->usage == 0) 69 if (md && md->usage == 0)
69 md = NULL; 70 md = NULL;
70 if (md) 71 if (md)
71 md->usage++; 72 md->usage++;
72 up(&open_lock); 73 mutex_unlock(&open_lock);
73 74
74 return md; 75 return md;
75} 76}
76 77
77static void mmc_blk_put(struct mmc_blk_data *md) 78static void mmc_blk_put(struct mmc_blk_data *md)
78{ 79{
79 down(&open_lock); 80 mutex_lock(&open_lock);
80 md->usage--; 81 md->usage--;
81 if (md->usage == 0) { 82 if (md->usage == 0) {
82 put_disk(md->disk); 83 put_disk(md->disk);
83 mmc_cleanup_queue(&md->queue); 84 mmc_cleanup_queue(&md->queue);
84 kfree(md); 85 kfree(md);
85 } 86 }
86 up(&open_lock); 87 mutex_unlock(&open_lock);
87} 88}
88 89
89static int mmc_blk_open(struct inode *inode, struct file *filp) 90static int mmc_blk_open(struct inode *inode, struct file *filp)
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c
index ec701667abfc..a2a35fd946ee 100644
--- a/drivers/mmc/mmc_sysfs.c
+++ b/drivers/mmc/mmc_sysfs.c
@@ -136,17 +136,7 @@ static int mmc_bus_resume(struct device *dev)
136 return ret; 136 return ret;
137} 137}
138 138
139static struct bus_type mmc_bus_type = { 139static int mmc_bus_probe(struct device *dev)
140 .name = "mmc",
141 .dev_attrs = mmc_dev_attrs,
142 .match = mmc_bus_match,
143 .uevent = mmc_bus_uevent,
144 .suspend = mmc_bus_suspend,
145 .resume = mmc_bus_resume,
146};
147
148
149static int mmc_drv_probe(struct device *dev)
150{ 140{
151 struct mmc_driver *drv = to_mmc_driver(dev->driver); 141 struct mmc_driver *drv = to_mmc_driver(dev->driver);
152 struct mmc_card *card = dev_to_mmc_card(dev); 142 struct mmc_card *card = dev_to_mmc_card(dev);
@@ -154,7 +144,7 @@ static int mmc_drv_probe(struct device *dev)
154 return drv->probe(card); 144 return drv->probe(card);
155} 145}
156 146
157static int mmc_drv_remove(struct device *dev) 147static int mmc_bus_remove(struct device *dev)
158{ 148{
159 struct mmc_driver *drv = to_mmc_driver(dev->driver); 149 struct mmc_driver *drv = to_mmc_driver(dev->driver);
160 struct mmc_card *card = dev_to_mmc_card(dev); 150 struct mmc_card *card = dev_to_mmc_card(dev);
@@ -164,6 +154,16 @@ static int mmc_drv_remove(struct device *dev)
164 return 0; 154 return 0;
165} 155}
166 156
157static struct bus_type mmc_bus_type = {
158 .name = "mmc",
159 .dev_attrs = mmc_dev_attrs,
160 .match = mmc_bus_match,
161 .uevent = mmc_bus_uevent,
162 .probe = mmc_bus_probe,
163 .remove = mmc_bus_remove,
164 .suspend = mmc_bus_suspend,
165 .resume = mmc_bus_resume,
166};
167 167
168/** 168/**
169 * mmc_register_driver - register a media driver 169 * mmc_register_driver - register a media driver
@@ -172,8 +172,6 @@ static int mmc_drv_remove(struct device *dev)
172int mmc_register_driver(struct mmc_driver *drv) 172int mmc_register_driver(struct mmc_driver *drv)
173{ 173{
174 drv->drv.bus = &mmc_bus_type; 174 drv->drv.bus = &mmc_bus_type;
175 drv->drv.probe = mmc_drv_probe;
176 drv->drv.remove = mmc_drv_remove;
177 return driver_register(&drv->drv); 175 return driver_register(&drv->drv);
178} 176}
179 177
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 9a2aa4033c6a..5038e90ceb12 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -47,6 +47,22 @@ config MTD_MS02NV
47 accelerator. Say Y here if you have a DECstation 5000/2x0 or a 47 accelerator. Say Y here if you have a DECstation 5000/2x0 or a
48 DECsystem 5900 equipped with such a module. 48 DECsystem 5900 equipped with such a module.
49 49
50config MTD_DATAFLASH
51 tristate "Support for AT45xxx DataFlash"
52 depends on MTD && SPI_MASTER && EXPERIMENTAL
53 help
54 This enables access to AT45xxx DataFlash chips, using SPI.
55 Sometimes DataFlash chips are packaged inside MMC-format
56 cards; at this writing, the MMC stack won't handle those.
57
58config MTD_M25P80
59 tristate "Support for M25 SPI Flash"
60 depends on MTD && SPI_MASTER && EXPERIMENTAL
61 help
62 This enables access to ST M25P80 and similar SPI flash chips,
63 used for program and data storage. Set up your spi devices
64 with the right board-specific platform data.
65
50config MTD_SLRAM 66config MTD_SLRAM
51 tristate "Uncached system RAM" 67 tristate "Uncached system RAM"
52 depends on MTD 68 depends on MTD
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index e38db348057d..7c5ed2178380 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -23,3 +23,5 @@ obj-$(CONFIG_MTD_MTDRAM) += mtdram.o
23obj-$(CONFIG_MTD_LART) += lart.o 23obj-$(CONFIG_MTD_LART) += lart.o
24obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o 24obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o
25obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o 25obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o
26obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o
27obj-$(CONFIG_MTD_M25P80) += m25p80.o
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
new file mode 100644
index 000000000000..d5f24089be71
--- /dev/null
+++ b/drivers/mtd/devices/m25p80.c
@@ -0,0 +1,582 @@
1/*
2 * MTD SPI driver for ST M25Pxx flash chips
3 *
4 * Author: Mike Lavender, mike@steroidmicros.com
5 *
6 * Copyright (c) 2005, Intec Automation Inc.
7 *
8 * Some parts are based on lart.c by Abraham Van Der Merwe
9 *
10 * Cleaned up and generalized based on mtd_dataflash.c
11 *
12 * This code is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/device.h>
21#include <linux/interrupt.h>
22#include <linux/interrupt.h>
23#include <linux/mtd/mtd.h>
24#include <linux/mtd/partitions.h>
25#include <linux/spi/spi.h>
26#include <linux/spi/flash.h>
27
28#include <asm/semaphore.h>
29
30
31/* NOTE: AT 25F and SST 25LF series are very similar,
32 * but commands for sector erase and chip id differ...
33 */
34
35#define FLASH_PAGESIZE 256
36
37/* Flash opcodes. */
38#define OPCODE_WREN 6 /* Write enable */
39#define OPCODE_RDSR 5 /* Read status register */
40#define OPCODE_READ 3 /* Read data bytes */
41#define OPCODE_PP 2 /* Page program */
42#define OPCODE_SE 0xd8 /* Sector erase */
43#define OPCODE_RES 0xab /* Read Electronic Signature */
44#define OPCODE_RDID 0x9f /* Read JEDEC ID */
45
46/* Status Register bits. */
47#define SR_WIP 1 /* Write in progress */
48#define SR_WEL 2 /* Write enable latch */
49#define SR_BP0 4 /* Block protect 0 */
50#define SR_BP1 8 /* Block protect 1 */
51#define SR_BP2 0x10 /* Block protect 2 */
52#define SR_SRWD 0x80 /* SR write protect */
53
54/* Define max times to check status register before we give up. */
55#define MAX_READY_WAIT_COUNT 100000
56
57
58#ifdef CONFIG_MTD_PARTITIONS
59#define mtd_has_partitions() (1)
60#else
61#define mtd_has_partitions() (0)
62#endif
63
64/****************************************************************************/
65
66struct m25p {
67 struct spi_device *spi;
68 struct semaphore lock;
69 struct mtd_info mtd;
70 unsigned partitioned;
71 u8 command[4];
72};
73
74static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
75{
76 return container_of(mtd, struct m25p, mtd);
77}
78
79/****************************************************************************/
80
81/*
82 * Internal helper functions
83 */
84
85/*
86 * Read the status register, returning its value in the location
87 * Return the status register value.
88 * Returns negative if error occurred.
89 */
90static int read_sr(struct m25p *flash)
91{
92 ssize_t retval;
93 u8 code = OPCODE_RDSR;
94 u8 val;
95
96 retval = spi_write_then_read(flash->spi, &code, 1, &val, 1);
97
98 if (retval < 0) {
99 dev_err(&flash->spi->dev, "error %d reading SR\n",
100 (int) retval);
101 return retval;
102 }
103
104 return val;
105}
106
107
108/*
109 * Set write enable latch with Write Enable command.
110 * Returns negative if error occurred.
111 */
112static inline int write_enable(struct m25p *flash)
113{
114 u8 code = OPCODE_WREN;
115
116 return spi_write_then_read(flash->spi, &code, 1, NULL, 0);
117}
118
119
120/*
121 * Service routine to read status register until ready, or timeout occurs.
122 * Returns non-zero if error.
123 */
124static int wait_till_ready(struct m25p *flash)
125{
126 int count;
127 int sr;
128
129 /* one chip guarantees max 5 msec wait here after page writes,
130 * but potentially three seconds (!) after page erase.
131 */
132 for (count = 0; count < MAX_READY_WAIT_COUNT; count++) {
133 if ((sr = read_sr(flash)) < 0)
134 break;
135 else if (!(sr & SR_WIP))
136 return 0;
137
138 /* REVISIT sometimes sleeping would be best */
139 }
140
141 return 1;
142}
143
144
145/*
146 * Erase one sector of flash memory at offset ``offset'' which is any
147 * address within the sector which should be erased.
148 *
149 * Returns 0 if successful, non-zero otherwise.
150 */
151static int erase_sector(struct m25p *flash, u32 offset)
152{
153 DEBUG(MTD_DEBUG_LEVEL3, "%s: %s at 0x%08x\n", flash->spi->dev.bus_id,
154 __FUNCTION__, offset);
155
156 /* Wait until finished previous write command. */
157 if (wait_till_ready(flash))
158 return 1;
159
160 /* Send write enable, then erase commands. */
161 write_enable(flash);
162
163 /* Set up command buffer. */
164 flash->command[0] = OPCODE_SE;
165 flash->command[1] = offset >> 16;
166 flash->command[2] = offset >> 8;
167 flash->command[3] = offset;
168
169 spi_write(flash->spi, flash->command, sizeof(flash->command));
170
171 return 0;
172}
173
174/****************************************************************************/
175
176/*
177 * MTD implementation
178 */
179
180/*
181 * Erase an address range on the flash chip. The address range may extend
182 * one or more erase sectors. Return an error is there is a problem erasing.
183 */
184static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
185{
186 struct m25p *flash = mtd_to_m25p(mtd);
187 u32 addr,len;
188
189 DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
190 flash->spi->dev.bus_id, __FUNCTION__, "at",
191 (u32)instr->addr, instr->len);
192
193 /* sanity checks */
194 if (instr->addr + instr->len > flash->mtd.size)
195 return -EINVAL;
196 if ((instr->addr % mtd->erasesize) != 0
197 || (instr->len % mtd->erasesize) != 0) {
198 return -EINVAL;
199 }
200
201 addr = instr->addr;
202 len = instr->len;
203
204 down(&flash->lock);
205
206 /* now erase those sectors */
207 while (len) {
208 if (erase_sector(flash, addr)) {
209 instr->state = MTD_ERASE_FAILED;
210 up(&flash->lock);
211 return -EIO;
212 }
213
214 addr += mtd->erasesize;
215 len -= mtd->erasesize;
216 }
217
218 up(&flash->lock);
219
220 instr->state = MTD_ERASE_DONE;
221 mtd_erase_callback(instr);
222
223 return 0;
224}
225
226/*
227 * Read an address range from the flash chip. The address range
228 * may be any size provided it is within the physical boundaries.
229 */
230static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
231 size_t *retlen, u_char *buf)
232{
233 struct m25p *flash = mtd_to_m25p(mtd);
234 struct spi_transfer t[2];
235 struct spi_message m;
236
237 DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
238 flash->spi->dev.bus_id, __FUNCTION__, "from",
239 (u32)from, len);
240
241 /* sanity checks */
242 if (!len)
243 return 0;
244
245 if (from + len > flash->mtd.size)
246 return -EINVAL;
247
248 spi_message_init(&m);
249 memset(t, 0, (sizeof t));
250
251 t[0].tx_buf = flash->command;
252 t[0].len = sizeof(flash->command);
253 spi_message_add_tail(&t[0], &m);
254
255 t[1].rx_buf = buf;
256 t[1].len = len;
257 spi_message_add_tail(&t[1], &m);
258
259 /* Byte count starts at zero. */
260 if (retlen)
261 *retlen = 0;
262
263 down(&flash->lock);
264
265 /* Wait till previous write/erase is done. */
266 if (wait_till_ready(flash)) {
267 /* REVISIT status return?? */
268 up(&flash->lock);
269 return 1;
270 }
271
272 /* NOTE: OPCODE_FAST_READ (if available) is faster... */
273
274 /* Set up the write data buffer. */
275 flash->command[0] = OPCODE_READ;
276 flash->command[1] = from >> 16;
277 flash->command[2] = from >> 8;
278 flash->command[3] = from;
279
280 spi_sync(flash->spi, &m);
281
282 *retlen = m.actual_length - sizeof(flash->command);
283
284 up(&flash->lock);
285
286 return 0;
287}
288
289/*
290 * Write an address range to the flash chip. Data must be written in
291 * FLASH_PAGESIZE chunks. The address range may be any size provided
292 * it is within the physical boundaries.
293 */
294static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
295 size_t *retlen, const u_char *buf)
296{
297 struct m25p *flash = mtd_to_m25p(mtd);
298 u32 page_offset, page_size;
299 struct spi_transfer t[2];
300 struct spi_message m;
301
302 DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
303 flash->spi->dev.bus_id, __FUNCTION__, "to",
304 (u32)to, len);
305
306 if (retlen)
307 *retlen = 0;
308
309 /* sanity checks */
310 if (!len)
311 return(0);
312
313 if (to + len > flash->mtd.size)
314 return -EINVAL;
315
316 spi_message_init(&m);
317 memset(t, 0, (sizeof t));
318
319 t[0].tx_buf = flash->command;
320 t[0].len = sizeof(flash->command);
321 spi_message_add_tail(&t[0], &m);
322
323 t[1].tx_buf = buf;
324 spi_message_add_tail(&t[1], &m);
325
326 down(&flash->lock);
327
328 /* Wait until finished previous write command. */
329 if (wait_till_ready(flash))
330 return 1;
331
332 write_enable(flash);
333
334 /* Set up the opcode in the write buffer. */
335 flash->command[0] = OPCODE_PP;
336 flash->command[1] = to >> 16;
337 flash->command[2] = to >> 8;
338 flash->command[3] = to;
339
340 /* what page do we start with? */
341 page_offset = to % FLASH_PAGESIZE;
342
343 /* do all the bytes fit onto one page? */
344 if (page_offset + len <= FLASH_PAGESIZE) {
345 t[1].len = len;
346
347 spi_sync(flash->spi, &m);
348
349 *retlen = m.actual_length - sizeof(flash->command);
350 } else {
351 u32 i;
352
353 /* the size of data remaining on the first page */
354 page_size = FLASH_PAGESIZE - page_offset;
355
356 t[1].len = page_size;
357 spi_sync(flash->spi, &m);
358
359 *retlen = m.actual_length - sizeof(flash->command);
360
361 /* write everything in PAGESIZE chunks */
362 for (i = page_size; i < len; i += page_size) {
363 page_size = len - i;
364 if (page_size > FLASH_PAGESIZE)
365 page_size = FLASH_PAGESIZE;
366
367 /* write the next page to flash */
368 flash->command[1] = (to + i) >> 16;
369 flash->command[2] = (to + i) >> 8;
370 flash->command[3] = (to + i);
371
372 t[1].tx_buf = buf + i;
373 t[1].len = page_size;
374
375 wait_till_ready(flash);
376
377 write_enable(flash);
378
379 spi_sync(flash->spi, &m);
380
381 if (retlen)
382 *retlen += m.actual_length
383 - sizeof(flash->command);
384 }
385 }
386
387 up(&flash->lock);
388
389 return 0;
390}
391
392
393/****************************************************************************/
394
395/*
396 * SPI device driver setup and teardown
397 */
398
399struct flash_info {
400 char *name;
401 u8 id;
402 u16 jedec_id;
403 unsigned sector_size;
404 unsigned n_sectors;
405};
406
407static struct flash_info __devinitdata m25p_data [] = {
408 /* REVISIT: fill in JEDEC ids, for parts that have them */
409 { "m25p05", 0x05, 0x0000, 32 * 1024, 2 },
410 { "m25p10", 0x10, 0x0000, 32 * 1024, 4 },
411 { "m25p20", 0x11, 0x0000, 64 * 1024, 4 },
412 { "m25p40", 0x12, 0x0000, 64 * 1024, 8 },
413 { "m25p80", 0x13, 0x0000, 64 * 1024, 16 },
414 { "m25p16", 0x14, 0x0000, 64 * 1024, 32 },
415 { "m25p32", 0x15, 0x0000, 64 * 1024, 64 },
416 { "m25p64", 0x16, 0x2017, 64 * 1024, 128 },
417};
418
419/*
420 * board specific setup should have ensured the SPI clock used here
421 * matches what the READ command supports, at least until this driver
422 * understands FAST_READ (for clocks over 25 MHz).
423 */
424static int __devinit m25p_probe(struct spi_device *spi)
425{
426 struct flash_platform_data *data;
427 struct m25p *flash;
428 struct flash_info *info;
429 unsigned i;
430
431 /* Platform data helps sort out which chip type we have, as
432 * well as how this board partitions it.
433 */
434 data = spi->dev.platform_data;
435 if (!data || !data->type) {
436 /* FIXME some chips can identify themselves with RES
437 * or JEDEC get-id commands. Try them ...
438 */
439 DEBUG(MTD_DEBUG_LEVEL1, "%s: no chip id\n",
440 flash->spi->dev.bus_id);
441 return -ENODEV;
442 }
443
444 for (i = 0, info = m25p_data; i < ARRAY_SIZE(m25p_data); i++, info++) {
445 if (strcmp(data->type, info->name) == 0)
446 break;
447 }
448 if (i == ARRAY_SIZE(m25p_data)) {
449 DEBUG(MTD_DEBUG_LEVEL1, "%s: unrecognized id %s\n",
450 flash->spi->dev.bus_id, data->type);
451 return -ENODEV;
452 }
453
454 flash = kzalloc(sizeof *flash, SLAB_KERNEL);
455 if (!flash)
456 return -ENOMEM;
457
458 flash->spi = spi;
459 init_MUTEX(&flash->lock);
460 dev_set_drvdata(&spi->dev, flash);
461
462 if (data->name)
463 flash->mtd.name = data->name;
464 else
465 flash->mtd.name = spi->dev.bus_id;
466
467 flash->mtd.type = MTD_NORFLASH;
468 flash->mtd.flags = MTD_CAP_NORFLASH;
469 flash->mtd.size = info->sector_size * info->n_sectors;
470 flash->mtd.erasesize = info->sector_size;
471 flash->mtd.erase = m25p80_erase;
472 flash->mtd.read = m25p80_read;
473 flash->mtd.write = m25p80_write;
474
475 dev_info(&spi->dev, "%s (%d Kbytes)\n", info->name,
476 flash->mtd.size / 1024);
477
478 DEBUG(MTD_DEBUG_LEVEL2,
479 "mtd .name = %s, .size = 0x%.8x (%uM) "
480 ".erasesize = 0x%.8x (%uK) .numeraseregions = %d\n",
481 flash->mtd.name,
482 flash->mtd.size, flash->mtd.size / (1024*1024),
483 flash->mtd.erasesize, flash->mtd.erasesize / 1024,
484 flash->mtd.numeraseregions);
485
486 if (flash->mtd.numeraseregions)
487 for (i = 0; i < flash->mtd.numeraseregions; i++)
488 DEBUG(MTD_DEBUG_LEVEL2,
489 "mtd.eraseregions[%d] = { .offset = 0x%.8x, "
490 ".erasesize = 0x%.8x (%uK), "
491 ".numblocks = %d }\n",
492 i, flash->mtd.eraseregions[i].offset,
493 flash->mtd.eraseregions[i].erasesize,
494 flash->mtd.eraseregions[i].erasesize / 1024,
495 flash->mtd.eraseregions[i].numblocks);
496
497
498 /* partitions should match sector boundaries; and it may be good to
499 * use readonly partitions for writeprotected sectors (BP2..BP0).
500 */
501 if (mtd_has_partitions()) {
502 struct mtd_partition *parts = NULL;
503 int nr_parts = 0;
504
505#ifdef CONFIG_MTD_CMDLINE_PARTS
506 static const char *part_probes[] = { "cmdlinepart", NULL, };
507
508 nr_parts = parse_mtd_partitions(&flash->mtd,
509 part_probes, &parts, 0);
510#endif
511
512 if (nr_parts <= 0 && data && data->parts) {
513 parts = data->parts;
514 nr_parts = data->nr_parts;
515 }
516
517 if (nr_parts > 0) {
518 for (i = 0; i < data->nr_parts; i++) {
519 DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
520 "{.name = %s, .offset = 0x%.8x, "
521 ".size = 0x%.8x (%uK) }\n",
522 i, data->parts[i].name,
523 data->parts[i].offset,
524 data->parts[i].size,
525 data->parts[i].size / 1024);
526 }
527 flash->partitioned = 1;
528 return add_mtd_partitions(&flash->mtd, parts, nr_parts);
529 }
530 } else if (data->nr_parts)
531 dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
532 data->nr_parts, data->name);
533
534 return add_mtd_device(&flash->mtd) == 1 ? -ENODEV : 0;
535}
536
537
538static int __devexit m25p_remove(struct spi_device *spi)
539{
540 struct m25p *flash = dev_get_drvdata(&spi->dev);
541 int status;
542
543 /* Clean up MTD stuff. */
544 if (mtd_has_partitions() && flash->partitioned)
545 status = del_mtd_partitions(&flash->mtd);
546 else
547 status = del_mtd_device(&flash->mtd);
548 if (status == 0)
549 kfree(flash);
550 return 0;
551}
552
553
554static struct spi_driver m25p80_driver = {
555 .driver = {
556 .name = "m25p80",
557 .bus = &spi_bus_type,
558 .owner = THIS_MODULE,
559 },
560 .probe = m25p_probe,
561 .remove = __devexit_p(m25p_remove),
562};
563
564
565static int m25p80_init(void)
566{
567 return spi_register_driver(&m25p80_driver);
568}
569
570
571static void m25p80_exit(void)
572{
573 spi_unregister_driver(&m25p80_driver);
574}
575
576
577module_init(m25p80_init);
578module_exit(m25p80_exit);
579
580MODULE_LICENSE("GPL");
581MODULE_AUTHOR("Mike Lavender");
582MODULE_DESCRIPTION("MTD SPI driver for ST M25Pxx flash chips");
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
new file mode 100644
index 000000000000..155737e7483f
--- /dev/null
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -0,0 +1,629 @@
1/*
2 * Atmel AT45xxx DataFlash MTD driver for lightweight SPI framework
3 *
4 * Largely derived from at91_dataflash.c:
5 * Copyright (C) 2003-2005 SAN People (Pty) Ltd
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11*/
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/slab.h>
16#include <linux/delay.h>
17#include <linux/device.h>
18#include <linux/spi/spi.h>
19#include <linux/spi/flash.h>
20
21#include <linux/mtd/mtd.h>
22#include <linux/mtd/partitions.h>
23
24
25/*
26 * DataFlash is a kind of SPI flash. Most AT45 chips have two buffers in
27 * each chip, which may be used for double buffered I/O; but this driver
28 * doesn't (yet) use these for any kind of i/o overlap or prefetching.
29 *
30 * Sometimes DataFlash is packaged in MMC-format cards, although the
31 * MMC stack can't use SPI (yet), or distinguish between MMC and DataFlash
32 * protocols during enumeration.
33 */
34
35#define CONFIG_DATAFLASH_WRITE_VERIFY
36
37/* reads can bypass the buffers */
38#define OP_READ_CONTINUOUS 0xE8
39#define OP_READ_PAGE 0xD2
40
41/* group B requests can run even while status reports "busy" */
42#define OP_READ_STATUS 0xD7 /* group B */
43
44/* move data between host and buffer */
45#define OP_READ_BUFFER1 0xD4 /* group B */
46#define OP_READ_BUFFER2 0xD6 /* group B */
47#define OP_WRITE_BUFFER1 0x84 /* group B */
48#define OP_WRITE_BUFFER2 0x87 /* group B */
49
50/* erasing flash */
51#define OP_ERASE_PAGE 0x81
52#define OP_ERASE_BLOCK 0x50
53
54/* move data between buffer and flash */
55#define OP_TRANSFER_BUF1 0x53
56#define OP_TRANSFER_BUF2 0x55
57#define OP_MREAD_BUFFER1 0xD4
58#define OP_MREAD_BUFFER2 0xD6
59#define OP_MWERASE_BUFFER1 0x83
60#define OP_MWERASE_BUFFER2 0x86
61#define OP_MWRITE_BUFFER1 0x88 /* sector must be pre-erased */
62#define OP_MWRITE_BUFFER2 0x89 /* sector must be pre-erased */
63
64/* write to buffer, then write-erase to flash */
65#define OP_PROGRAM_VIA_BUF1 0x82
66#define OP_PROGRAM_VIA_BUF2 0x85
67
68/* compare buffer to flash */
69#define OP_COMPARE_BUF1 0x60
70#define OP_COMPARE_BUF2 0x61
71
72/* read flash to buffer, then write-erase to flash */
73#define OP_REWRITE_VIA_BUF1 0x58
74#define OP_REWRITE_VIA_BUF2 0x59
75
76/* newer chips report JEDEC manufacturer and device IDs; chip
77 * serial number and OTP bits; and per-sector writeprotect.
78 */
79#define OP_READ_ID 0x9F
80#define OP_READ_SECURITY 0x77
81#define OP_WRITE_SECURITY 0x9A /* OTP bits */
82
83
84struct dataflash {
85 u8 command[4];
86 char name[24];
87
88 unsigned partitioned:1;
89
90 unsigned short page_offset; /* offset in flash address */
91 unsigned int page_size; /* of bytes per page */
92
93 struct semaphore lock;
94 struct spi_device *spi;
95
96 struct mtd_info mtd;
97};
98
99#ifdef CONFIG_MTD_PARTITIONS
100#define mtd_has_partitions() (1)
101#else
102#define mtd_has_partitions() (0)
103#endif
104
105/* ......................................................................... */
106
107/*
108 * Return the status of the DataFlash device.
109 */
110static inline int dataflash_status(struct spi_device *spi)
111{
112 /* NOTE: at45db321c over 25 MHz wants to write
113 * a dummy byte after the opcode...
114 */
115 return spi_w8r8(spi, OP_READ_STATUS);
116}
117
118/*
119 * Poll the DataFlash device until it is READY.
120 * This usually takes 5-20 msec or so; more for sector erase.
121 */
122static int dataflash_waitready(struct spi_device *spi)
123{
124 int status;
125
126 for (;;) {
127 status = dataflash_status(spi);
128 if (status < 0) {
129 DEBUG(MTD_DEBUG_LEVEL1, "%s: status %d?\n",
130 spi->dev.bus_id, status);
131 status = 0;
132 }
133
134 if (status & (1 << 7)) /* RDY/nBSY */
135 return status;
136
137 msleep(3);
138 }
139}
140
141/* ......................................................................... */
142
143/*
144 * Erase pages of flash.
145 */
146static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
147{
148 struct dataflash *priv = (struct dataflash *)mtd->priv;
149 struct spi_device *spi = priv->spi;
150 struct spi_transfer x = { .tx_dma = 0, };
151 struct spi_message msg;
152 unsigned blocksize = priv->page_size << 3;
153 u8 *command;
154
155 DEBUG(MTD_DEBUG_LEVEL2, "%s: erase addr=0x%x len 0x%x\n",
156 spi->dev.bus_id,
157 instr->addr, instr->len);
158
159 /* Sanity checks */
160 if ((instr->addr + instr->len) > mtd->size
161 || (instr->len % priv->page_size) != 0
162 || (instr->addr % priv->page_size) != 0)
163 return -EINVAL;
164
165 spi_message_init(&msg);
166
167 x.tx_buf = command = priv->command;
168 x.len = 4;
169 spi_message_add_tail(&x, &msg);
170
171 down(&priv->lock);
172 while (instr->len > 0) {
173 unsigned int pageaddr;
174 int status;
175 int do_block;
176
177 /* Calculate flash page address; use block erase (for speed) if
178 * we're at a block boundary and need to erase the whole block.
179 */
180 pageaddr = instr->addr / priv->page_size;
181 do_block = (pageaddr & 0x7) == 0 && instr->len <= blocksize;
182 pageaddr = pageaddr << priv->page_offset;
183
184 command[0] = do_block ? OP_ERASE_BLOCK : OP_ERASE_PAGE;
185 command[1] = (u8)(pageaddr >> 16);
186 command[2] = (u8)(pageaddr >> 8);
187 command[3] = 0;
188
189 DEBUG(MTD_DEBUG_LEVEL3, "ERASE %s: (%x) %x %x %x [%i]\n",
190 do_block ? "block" : "page",
191 command[0], command[1], command[2], command[3],
192 pageaddr);
193
194 status = spi_sync(spi, &msg);
195 (void) dataflash_waitready(spi);
196
197 if (status < 0) {
198 printk(KERN_ERR "%s: erase %x, err %d\n",
199 spi->dev.bus_id, pageaddr, status);
200 /* REVISIT: can retry instr->retries times; or
201 * giveup and instr->fail_addr = instr->addr;
202 */
203 continue;
204 }
205
206 if (do_block) {
207 instr->addr += blocksize;
208 instr->len -= blocksize;
209 } else {
210 instr->addr += priv->page_size;
211 instr->len -= priv->page_size;
212 }
213 }
214 up(&priv->lock);
215
216 /* Inform MTD subsystem that erase is complete */
217 instr->state = MTD_ERASE_DONE;
218 mtd_erase_callback(instr);
219
220 return 0;
221}
222
223/*
224 * Read from the DataFlash device.
225 * from : Start offset in flash device
226 * len : Amount to read
227 * retlen : About of data actually read
228 * buf : Buffer containing the data
229 */
230static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
231 size_t *retlen, u_char *buf)
232{
233 struct dataflash *priv = (struct dataflash *)mtd->priv;
234 struct spi_transfer x[2] = { { .tx_dma = 0, }, };
235 struct spi_message msg;
236 unsigned int addr;
237 u8 *command;
238 int status;
239
240 DEBUG(MTD_DEBUG_LEVEL2, "%s: read 0x%x..0x%x\n",
241 priv->spi->dev.bus_id, (unsigned)from, (unsigned)(from + len));
242
243 *retlen = 0;
244
245 /* Sanity checks */
246 if (!len)
247 return 0;
248 if (from + len > mtd->size)
249 return -EINVAL;
250
251 /* Calculate flash page/byte address */
252 addr = (((unsigned)from / priv->page_size) << priv->page_offset)
253 + ((unsigned)from % priv->page_size);
254
255 command = priv->command;
256
257 DEBUG(MTD_DEBUG_LEVEL3, "READ: (%x) %x %x %x\n",
258 command[0], command[1], command[2], command[3]);
259
260 spi_message_init(&msg);
261
262 x[0].tx_buf = command;
263 x[0].len = 8;
264 spi_message_add_tail(&x[0], &msg);
265
266 x[1].rx_buf = buf;
267 x[1].len = len;
268 spi_message_add_tail(&x[1], &msg);
269
270 down(&priv->lock);
271
272 /* Continuous read, max clock = f(car) which may be less than
273 * the peak rate available. Some chips support commands with
274 * fewer "don't care" bytes. Both buffers stay unchanged.
275 */
276 command[0] = OP_READ_CONTINUOUS;
277 command[1] = (u8)(addr >> 16);
278 command[2] = (u8)(addr >> 8);
279 command[3] = (u8)(addr >> 0);
280 /* plus 4 "don't care" bytes */
281
282 status = spi_sync(priv->spi, &msg);
283 up(&priv->lock);
284
285 if (status >= 0) {
286 *retlen = msg.actual_length - 8;
287 status = 0;
288 } else
289 DEBUG(MTD_DEBUG_LEVEL1, "%s: read %x..%x --> %d\n",
290 priv->spi->dev.bus_id,
291 (unsigned)from, (unsigned)(from + len),
292 status);
293 return status;
294}
295
296/*
297 * Write to the DataFlash device.
298 * to : Start offset in flash device
299 * len : Amount to write
300 * retlen : Amount of data actually written
301 * buf : Buffer containing the data
302 */
303static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
304 size_t * retlen, const u_char * buf)
305{
306 struct dataflash *priv = (struct dataflash *)mtd->priv;
307 struct spi_device *spi = priv->spi;
308 struct spi_transfer x[2] = { { .tx_dma = 0, }, };
309 struct spi_message msg;
310 unsigned int pageaddr, addr, offset, writelen;
311 size_t remaining = len;
312 u_char *writebuf = (u_char *) buf;
313 int status = -EINVAL;
314 u8 *command;
315
316 DEBUG(MTD_DEBUG_LEVEL2, "%s: write 0x%x..0x%x\n",
317 spi->dev.bus_id, (unsigned)to, (unsigned)(to + len));
318
319 *retlen = 0;
320
321 /* Sanity checks */
322 if (!len)
323 return 0;
324 if ((to + len) > mtd->size)
325 return -EINVAL;
326
327 spi_message_init(&msg);
328
329 x[0].tx_buf = command = priv->command;
330 x[0].len = 4;
331 spi_message_add_tail(&x[0], &msg);
332
333 pageaddr = ((unsigned)to / priv->page_size);
334 offset = ((unsigned)to % priv->page_size);
335 if (offset + len > priv->page_size)
336 writelen = priv->page_size - offset;
337 else
338 writelen = len;
339
340 down(&priv->lock);
341 while (remaining > 0) {
342 DEBUG(MTD_DEBUG_LEVEL3, "write @ %i:%i len=%i\n",
343 pageaddr, offset, writelen);
344
345 /* REVISIT:
346 * (a) each page in a sector must be rewritten at least
347 * once every 10K sibling erase/program operations.
348 * (b) for pages that are already erased, we could
349 * use WRITE+MWRITE not PROGRAM for ~30% speedup.
350 * (c) WRITE to buffer could be done while waiting for
351 * a previous MWRITE/MWERASE to complete ...
352 * (d) error handling here seems to be mostly missing.
353 *
354 * Two persistent bits per page, plus a per-sector counter,
355 * could support (a) and (b) ... we might consider using
356 * the second half of sector zero, which is just one block,
357 * to track that state. (On AT91, that sector should also
358 * support boot-from-DataFlash.)
359 */
360
361 addr = pageaddr << priv->page_offset;
362
363 /* (1) Maybe transfer partial page to Buffer1 */
364 if (writelen != priv->page_size) {
365 command[0] = OP_TRANSFER_BUF1;
366 command[1] = (addr & 0x00FF0000) >> 16;
367 command[2] = (addr & 0x0000FF00) >> 8;
368 command[3] = 0;
369
370 DEBUG(MTD_DEBUG_LEVEL3, "TRANSFER: (%x) %x %x %x\n",
371 command[0], command[1], command[2], command[3]);
372
373 status = spi_sync(spi, &msg);
374 if (status < 0)
375 DEBUG(MTD_DEBUG_LEVEL1, "%s: xfer %u -> %d \n",
376 spi->dev.bus_id, addr, status);
377
378 (void) dataflash_waitready(priv->spi);
379 }
380
381 /* (2) Program full page via Buffer1 */
382 addr += offset;
383 command[0] = OP_PROGRAM_VIA_BUF1;
384 command[1] = (addr & 0x00FF0000) >> 16;
385 command[2] = (addr & 0x0000FF00) >> 8;
386 command[3] = (addr & 0x000000FF);
387
388 DEBUG(MTD_DEBUG_LEVEL3, "PROGRAM: (%x) %x %x %x\n",
389 command[0], command[1], command[2], command[3]);
390
391 x[1].tx_buf = writebuf;
392 x[1].len = writelen;
393 spi_message_add_tail(x + 1, &msg);
394 status = spi_sync(spi, &msg);
395 spi_transfer_del(x + 1);
396 if (status < 0)
397 DEBUG(MTD_DEBUG_LEVEL1, "%s: pgm %u/%u -> %d \n",
398 spi->dev.bus_id, addr, writelen, status);
399
400 (void) dataflash_waitready(priv->spi);
401
402
403#ifdef CONFIG_DATAFLASH_WRITE_VERIFY
404
405 /* (3) Compare to Buffer1 */
406 addr = pageaddr << priv->page_offset;
407 command[0] = OP_COMPARE_BUF1;
408 command[1] = (addr & 0x00FF0000) >> 16;
409 command[2] = (addr & 0x0000FF00) >> 8;
410 command[3] = 0;
411
412 DEBUG(MTD_DEBUG_LEVEL3, "COMPARE: (%x) %x %x %x\n",
413 command[0], command[1], command[2], command[3]);
414
415 status = spi_sync(spi, &msg);
416 if (status < 0)
417 DEBUG(MTD_DEBUG_LEVEL1, "%s: compare %u -> %d \n",
418 spi->dev.bus_id, addr, status);
419
420 status = dataflash_waitready(priv->spi);
421
422 /* Check result of the compare operation */
423 if ((status & (1 << 6)) == 1) {
424 printk(KERN_ERR "%s: compare page %u, err %d\n",
425 spi->dev.bus_id, pageaddr, status);
426 remaining = 0;
427 status = -EIO;
428 break;
429 } else
430 status = 0;
431
432#endif /* CONFIG_DATAFLASH_WRITE_VERIFY */
433
434 remaining = remaining - writelen;
435 pageaddr++;
436 offset = 0;
437 writebuf += writelen;
438 *retlen += writelen;
439
440 if (remaining > priv->page_size)
441 writelen = priv->page_size;
442 else
443 writelen = remaining;
444 }
445 up(&priv->lock);
446
447 return status;
448}
449
450/* ......................................................................... */
451
452/*
453 * Register DataFlash device with MTD subsystem.
454 */
455static int __devinit
456add_dataflash(struct spi_device *spi, char *name,
457 int nr_pages, int pagesize, int pageoffset)
458{
459 struct dataflash *priv;
460 struct mtd_info *device;
461 struct flash_platform_data *pdata = spi->dev.platform_data;
462
463 priv = (struct dataflash *) kzalloc(sizeof *priv, GFP_KERNEL);
464 if (!priv)
465 return -ENOMEM;
466
467 init_MUTEX(&priv->lock);
468 priv->spi = spi;
469 priv->page_size = pagesize;
470 priv->page_offset = pageoffset;
471
472 /* name must be usable with cmdlinepart */
473 sprintf(priv->name, "spi%d.%d-%s",
474 spi->master->bus_num, spi->chip_select,
475 name);
476
477 device = &priv->mtd;
478 device->name = (pdata && pdata->name) ? pdata->name : priv->name;
479 device->size = nr_pages * pagesize;
480 device->erasesize = pagesize;
481 device->owner = THIS_MODULE;
482 device->type = MTD_DATAFLASH;
483 device->flags = MTD_CAP_NORFLASH;
484 device->erase = dataflash_erase;
485 device->read = dataflash_read;
486 device->write = dataflash_write;
487 device->priv = priv;
488
489 dev_info(&spi->dev, "%s (%d KBytes)\n", name, device->size/1024);
490 dev_set_drvdata(&spi->dev, priv);
491
492 if (mtd_has_partitions()) {
493 struct mtd_partition *parts;
494 int nr_parts = 0;
495
496#ifdef CONFIG_MTD_CMDLINE_PARTS
497 static const char *part_probes[] = { "cmdlinepart", NULL, };
498
499 nr_parts = parse_mtd_partitions(device, part_probes, &parts, 0);
500#endif
501
502 if (nr_parts <= 0 && pdata && pdata->parts) {
503 parts = pdata->parts;
504 nr_parts = pdata->nr_parts;
505 }
506
507 if (nr_parts > 0) {
508 priv->partitioned = 1;
509 return add_mtd_partitions(device, parts, nr_parts);
510 }
511 } else if (pdata && pdata->nr_parts)
512 dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
513 pdata->nr_parts, device->name);
514
515 return add_mtd_device(device) == 1 ? -ENODEV : 0;
516}
517
518/*
519 * Detect and initialize DataFlash device:
520 *
521 * Device Density ID code #Pages PageSize Offset
522 * AT45DB011B 1Mbit (128K) xx0011xx (0x0c) 512 264 9
523 * AT45DB021B 2Mbit (256K) xx0101xx (0x14) 1025 264 9
524 * AT45DB041B 4Mbit (512K) xx0111xx (0x1c) 2048 264 9
525 * AT45DB081B 8Mbit (1M) xx1001xx (0x24) 4096 264 9
526 * AT45DB0161B 16Mbit (2M) xx1011xx (0x2c) 4096 528 10
527 * AT45DB0321B 32Mbit (4M) xx1101xx (0x34) 8192 528 10
528 * AT45DB0642 64Mbit (8M) xx111xxx (0x3c) 8192 1056 11
529 * AT45DB1282 128Mbit (16M) xx0100xx (0x10) 16384 1056 11
530 */
531static int __devinit dataflash_probe(struct spi_device *spi)
532{
533 int status;
534
535 status = dataflash_status(spi);
536 if (status <= 0 || status == 0xff) {
537 DEBUG(MTD_DEBUG_LEVEL1, "%s: status error %d\n",
538 spi->dev.bus_id, status);
539 if (status == 0xff)
540 status = -ENODEV;
541 return status;
542 }
543
544 /* if there's a device there, assume it's dataflash.
545 * board setup should have set spi->max_speed_max to
546 * match f(car) for continuous reads, mode 0 or 3.
547 */
548 switch (status & 0x3c) {
549 case 0x0c: /* 0 0 1 1 x x */
550 status = add_dataflash(spi, "AT45DB011B", 512, 264, 9);
551 break;
552 case 0x14: /* 0 1 0 1 x x */
553 status = add_dataflash(spi, "AT45DB021B", 1025, 264, 9);
554 break;
555 case 0x1c: /* 0 1 1 1 x x */
556 status = add_dataflash(spi, "AT45DB041x", 2048, 264, 9);
557 break;
558 case 0x24: /* 1 0 0 1 x x */
559 status = add_dataflash(spi, "AT45DB081B", 4096, 264, 9);
560 break;
561 case 0x2c: /* 1 0 1 1 x x */
562 status = add_dataflash(spi, "AT45DB161x", 4096, 528, 10);
563 break;
564 case 0x34: /* 1 1 0 1 x x */
565 status = add_dataflash(spi, "AT45DB321x", 8192, 528, 10);
566 break;
567 case 0x38: /* 1 1 1 x x x */
568 case 0x3c:
569 status = add_dataflash(spi, "AT45DB642x", 8192, 1056, 11);
570 break;
571 /* obsolete AT45DB1282 not (yet?) supported */
572 default:
573 DEBUG(MTD_DEBUG_LEVEL1, "%s: unsupported device (%x)\n",
574 spi->dev.bus_id, status & 0x3c);
575 status = -ENODEV;
576 }
577
578 if (status < 0)
579 DEBUG(MTD_DEBUG_LEVEL1, "%s: add_dataflash --> %d\n",
580 spi->dev.bus_id, status);
581
582 return status;
583}
584
585static int __devexit dataflash_remove(struct spi_device *spi)
586{
587 struct dataflash *flash = dev_get_drvdata(&spi->dev);
588 int status;
589
590 DEBUG(MTD_DEBUG_LEVEL1, "%s: remove\n", spi->dev.bus_id);
591
592 if (mtd_has_partitions() && flash->partitioned)
593 status = del_mtd_partitions(&flash->mtd);
594 else
595 status = del_mtd_device(&flash->mtd);
596 if (status == 0)
597 kfree(flash);
598 return status;
599}
600
601static struct spi_driver dataflash_driver = {
602 .driver = {
603 .name = "mtd_dataflash",
604 .bus = &spi_bus_type,
605 .owner = THIS_MODULE,
606 },
607
608 .probe = dataflash_probe,
609 .remove = __devexit_p(dataflash_remove),
610
611 /* FIXME: investigate suspend and resume... */
612};
613
614static int __init dataflash_init(void)
615{
616 return spi_register_driver(&dataflash_driver);
617}
618module_init(dataflash_init);
619
620static void __exit dataflash_exit(void)
621{
622 spi_unregister_driver(&dataflash_driver);
623}
624module_exit(dataflash_exit);
625
626
627MODULE_LICENSE("GPL");
628MODULE_AUTHOR("Andrew Victor, David Brownell");
629MODULE_DESCRIPTION("MTD DataFlash driver");
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 854ddfb90da1..f2a63186ae05 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -169,9 +169,9 @@ static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_
169 index = next_index; 169 index = next_index;
170 } 170 }
171 171
172 _unlock_tx_hashtbl(bond);
173
174 tlb_init_slave(slave); 172 tlb_init_slave(slave);
173
174 _unlock_tx_hashtbl(bond);
175} 175}
176 176
177/* Must be called before starting the monitor timer */ 177/* Must be called before starting the monitor timer */
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index f20bb85c1ea5..3dd78d048c3e 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -22,8 +22,8 @@
22#include "bond_3ad.h" 22#include "bond_3ad.h"
23#include "bond_alb.h" 23#include "bond_alb.h"
24 24
25#define DRV_VERSION "3.0.0" 25#define DRV_VERSION "3.0.1"
26#define DRV_RELDATE "November 8, 2005" 26#define DRV_RELDATE "January 9, 2006"
27#define DRV_NAME "bonding" 27#define DRV_NAME "bonding"
28#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 28#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
29 29
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 22cd04556707..23de22631c64 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -132,6 +132,10 @@
132 * TODO: 132 * TODO:
133 * o several entry points race with dev->close 133 * o several entry points race with dev->close
134 * o check for tx-no-resources/stop Q races with tx clean/wake Q 134 * o check for tx-no-resources/stop Q races with tx clean/wake Q
135 *
136 * FIXES:
137 * 2005/12/02 - Michael O'Donnell <Michael.ODonnell at stratus dot com>
138 * - Stratus87247: protect MDI control register manipulations
135 */ 139 */
136 140
137#include <linux/config.h> 141#include <linux/config.h>
@@ -578,6 +582,7 @@ struct nic {
578 u16 leds; 582 u16 leds;
579 u16 eeprom_wc; 583 u16 eeprom_wc;
580 u16 eeprom[256]; 584 u16 eeprom[256];
585 spinlock_t mdio_lock;
581}; 586};
582 587
583static inline void e100_write_flush(struct nic *nic) 588static inline void e100_write_flush(struct nic *nic)
@@ -876,15 +881,35 @@ static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
876{ 881{
877 u32 data_out = 0; 882 u32 data_out = 0;
878 unsigned int i; 883 unsigned int i;
884 unsigned long flags;
879 885
886
887 /*
888 * Stratus87247: we shouldn't be writing the MDI control
889 * register until the Ready bit shows True. Also, since
890 * manipulation of the MDI control registers is a multi-step
891 * procedure it should be done under lock.
892 */
893 spin_lock_irqsave(&nic->mdio_lock, flags);
894 for (i = 100; i; --i) {
895 if (readl(&nic->csr->mdi_ctrl) & mdi_ready)
896 break;
897 udelay(20);
898 }
899 if (unlikely(!i)) {
900 printk("e100.mdio_ctrl(%s) won't go Ready\n",
901 nic->netdev->name );
902 spin_unlock_irqrestore(&nic->mdio_lock, flags);
903 return 0; /* No way to indicate timeout error */
904 }
880 writel((reg << 16) | (addr << 21) | dir | data, &nic->csr->mdi_ctrl); 905 writel((reg << 16) | (addr << 21) | dir | data, &nic->csr->mdi_ctrl);
881 906
882 for(i = 0; i < 100; i++) { 907 for (i = 0; i < 100; i++) {
883 udelay(20); 908 udelay(20);
884 if((data_out = readl(&nic->csr->mdi_ctrl)) & mdi_ready) 909 if ((data_out = readl(&nic->csr->mdi_ctrl)) & mdi_ready)
885 break; 910 break;
886 } 911 }
887 912 spin_unlock_irqrestore(&nic->mdio_lock, flags);
888 DPRINTK(HW, DEBUG, 913 DPRINTK(HW, DEBUG,
889 "%s:addr=%d, reg=%d, data_in=0x%04X, data_out=0x%04X\n", 914 "%s:addr=%d, reg=%d, data_in=0x%04X, data_out=0x%04X\n",
890 dir == mdi_read ? "READ" : "WRITE", addr, reg, data, data_out); 915 dir == mdi_read ? "READ" : "WRITE", addr, reg, data, data_out);
@@ -2562,6 +2587,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
2562 /* locks must be initialized before calling hw_reset */ 2587 /* locks must be initialized before calling hw_reset */
2563 spin_lock_init(&nic->cb_lock); 2588 spin_lock_init(&nic->cb_lock);
2564 spin_lock_init(&nic->cmd_lock); 2589 spin_lock_init(&nic->cmd_lock);
2590 spin_lock_init(&nic->mdio_lock);
2565 2591
2566 /* Reset the device before pci_set_master() in case device is in some 2592 /* Reset the device before pci_set_master() in case device is in some
2567 * funky state and has an interrupt pending - hint: we don't have the 2593 * funky state and has an interrupt pending - hint: we don't have the
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 146f9513aea5..0c18dbd67d3b 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -84,6 +84,7 @@
84#include <linux/ip.h> 84#include <linux/ip.h>
85#include <linux/tcp.h> 85#include <linux/tcp.h>
86#include <linux/udp.h> 86#include <linux/udp.h>
87#include <linux/in.h>
87 88
88#include <asm/io.h> 89#include <asm/io.h>
89#include <asm/irq.h> 90#include <asm/irq.h>
@@ -398,12 +399,15 @@ static int init_phy(struct net_device *dev)
398 priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ? 399 priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
399 SUPPORTED_1000baseT_Full : 0; 400 SUPPORTED_1000baseT_Full : 0;
400 struct phy_device *phydev; 401 struct phy_device *phydev;
402 char phy_id[BUS_ID_SIZE];
401 403
402 priv->oldlink = 0; 404 priv->oldlink = 0;
403 priv->oldspeed = 0; 405 priv->oldspeed = 0;
404 priv->oldduplex = -1; 406 priv->oldduplex = -1;
405 407
406 phydev = phy_connect(dev, priv->einfo->bus_id, &adjust_link, 0); 408 snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, priv->einfo->bus_id, priv->einfo->phy_id);
409
410 phydev = phy_connect(dev, phy_id, &adjust_link, 0);
407 411
408 if (IS_ERR(phydev)) { 412 if (IS_ERR(phydev)) {
409 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); 413 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index 04a462c2a5b7..74e52fcbf806 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -128,6 +128,7 @@ int gfar_mdio_probe(struct device *dev)
128 struct gianfar_mdio_data *pdata; 128 struct gianfar_mdio_data *pdata;
129 struct gfar_mii *regs; 129 struct gfar_mii *regs;
130 struct mii_bus *new_bus; 130 struct mii_bus *new_bus;
131 struct resource *r;
131 int err = 0; 132 int err = 0;
132 133
133 if (NULL == dev) 134 if (NULL == dev)
@@ -151,8 +152,10 @@ int gfar_mdio_probe(struct device *dev)
151 return -ENODEV; 152 return -ENODEV;
152 } 153 }
153 154
155 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
156
154 /* Set the PHY base address */ 157 /* Set the PHY base address */
155 regs = (struct gfar_mii *) ioremap(pdata->paddr, 158 regs = (struct gfar_mii *) ioremap(r->start,
156 sizeof (struct gfar_mii)); 159 sizeof (struct gfar_mii));
157 160
158 if (NULL == regs) { 161 if (NULL == regs) {
diff --git a/drivers/net/hplance.c b/drivers/net/hplance.c
index 08703d6f934c..d8410634bcaf 100644
--- a/drivers/net/hplance.c
+++ b/drivers/net/hplance.c
@@ -150,7 +150,7 @@ static void __init hplance_init(struct net_device *dev, struct dio_dev *d)
150 lp->lance.name = (char*)d->name; /* discards const, shut up gcc */ 150 lp->lance.name = (char*)d->name; /* discards const, shut up gcc */
151 lp->lance.base = va; 151 lp->lance.base = va;
152 lp->lance.init_block = (struct lance_init_block *)(va + HPLANCE_MEMOFF); /* CPU addr */ 152 lp->lance.init_block = (struct lance_init_block *)(va + HPLANCE_MEMOFF); /* CPU addr */
153 lp->lance.lance_init_block = 0; /* LANCE addr of same RAM */ 153 lp->lance.lance_init_block = NULL; /* LANCE addr of same RAM */
154 lp->lance.busmaster_regval = LE_C3_BSWP; /* we're bigendian */ 154 lp->lance.busmaster_regval = LE_C3_BSWP; /* we're bigendian */
155 lp->lance.irq = d->ipl; 155 lp->lance.irq = d->ipl;
156 lp->lance.writerap = hplance_writerap; 156 lp->lance.writerap = hplance_writerap;
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 77eadf84cb2c..f0f04be989d6 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -590,9 +590,9 @@ static void veth_handle_event(struct HvLpEvent *event, struct pt_regs *regs)
590{ 590{
591 struct veth_lpevent *veth_event = (struct veth_lpevent *)event; 591 struct veth_lpevent *veth_event = (struct veth_lpevent *)event;
592 592
593 if (event->xFlags.xFunction == HvLpEvent_Function_Ack) 593 if (hvlpevent_is_ack(event))
594 veth_handle_ack(veth_event); 594 veth_handle_ack(veth_event);
595 else if (event->xFlags.xFunction == HvLpEvent_Function_Int) 595 else
596 veth_handle_int(veth_event); 596 veth_handle_int(veth_event);
597} 597}
598 598
diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c
index d8c99f038fa0..06cb460361a8 100644
--- a/drivers/net/mac8390.c
+++ b/drivers/net/mac8390.c
@@ -559,55 +559,52 @@ static void mac8390_no_reset(struct net_device *dev)
559/* directly from daynaport.c by Alan Cox */ 559/* directly from daynaport.c by Alan Cox */
560static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count) 560static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count)
561{ 561{
562 volatile unsigned short *ptr; 562 volatile unsigned char *ptr;
563 unsigned short *target=to; 563 unsigned char *target=to;
564 from<<=1; /* word, skip overhead */ 564 from<<=1; /* word, skip overhead */
565 ptr=(unsigned short *)(dev->mem_start+from); 565 ptr=(unsigned char *)(dev->mem_start+from);
566 /* Leading byte? */ 566 /* Leading byte? */
567 if (from&2) { 567 if (from&2) {
568 *((char *)target)++ = *(((char *)ptr++)-1); 568 *target++ = ptr[-1];
569 ptr += 2;
569 count--; 570 count--;
570 } 571 }
571 while(count>=2) 572 while(count>=2)
572 { 573 {
573 *target++=*ptr++; /* Copy and */ 574 *(unsigned short *)target = *(unsigned short volatile *)ptr;
574 ptr++; /* skip cruft */ 575 ptr += 4; /* skip cruft */
576 target += 2;
575 count-=2; 577 count-=2;
576 } 578 }
577 /* Trailing byte? */ 579 /* Trailing byte? */
578 if(count) 580 if(count)
579 { 581 *target = *ptr;
580 /* Big endian */
581 unsigned short v=*ptr;
582 *((char *)target)=v>>8;
583 }
584} 582}
585 583
586static void dayna_memcpy_tocard(struct net_device *dev, int to, const void *from, int count) 584static void dayna_memcpy_tocard(struct net_device *dev, int to, const void *from, int count)
587{ 585{
588 volatile unsigned short *ptr; 586 volatile unsigned short *ptr;
589 const unsigned short *src=from; 587 const unsigned char *src=from;
590 to<<=1; /* word, skip overhead */ 588 to<<=1; /* word, skip overhead */
591 ptr=(unsigned short *)(dev->mem_start+to); 589 ptr=(unsigned short *)(dev->mem_start+to);
592 /* Leading byte? */ 590 /* Leading byte? */
593 if (to&2) { /* avoid a byte write (stomps on other data) */ 591 if (to&2) { /* avoid a byte write (stomps on other data) */
594 ptr[-1] = (ptr[-1]&0xFF00)|*((unsigned char *)src)++; 592 ptr[-1] = (ptr[-1]&0xFF00)|*src++;
595 ptr++; 593 ptr++;
596 count--; 594 count--;
597 } 595 }
598 while(count>=2) 596 while(count>=2)
599 { 597 {
600 *ptr++=*src++; /* Copy and */ 598 *ptr++=*(unsigned short *)src; /* Copy and */
601 ptr++; /* skip cruft */ 599 ptr++; /* skip cruft */
600 src += 2;
602 count-=2; 601 count-=2;
603 } 602 }
604 /* Trailing byte? */ 603 /* Trailing byte? */
605 if(count) 604 if(count)
606 { 605 {
607 /* Big endian */
608 unsigned short v=*src;
609 /* card doesn't like byte writes */ 606 /* card doesn't like byte writes */
610 *ptr=(*ptr&0x00FF)|(v&0xFF00); 607 *ptr=(*ptr&0x00FF)|(*src << 8);
611 } 608 }
612} 609}
613 610
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 02940c0fef68..459443b572ce 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -81,7 +81,7 @@ int mdiobus_register(struct mii_bus *bus)
81 81
82 phydev->dev.parent = bus->dev; 82 phydev->dev.parent = bus->dev;
83 phydev->dev.bus = &mdio_bus_type; 83 phydev->dev.bus = &mdio_bus_type;
84 sprintf(phydev->dev.bus_id, "phy%d:%d", bus->id, i); 84 snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, i);
85 85
86 phydev->bus = bus; 86 phydev->bus = bus;
87 87
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index b8686e47f899..1474b7c5ac0b 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -42,7 +42,7 @@
42 */ 42 */
43void phy_print_status(struct phy_device *phydev) 43void phy_print_status(struct phy_device *phydev)
44{ 44{
45 pr_info("%s: Link is %s", phydev->dev.bus_id, 45 pr_info("PHY: %s - Link is %s", phydev->dev.bus_id,
46 phydev->link ? "Up" : "Down"); 46 phydev->link ? "Up" : "Down");
47 if (phydev->link) 47 if (phydev->link)
48 printk(" - %d/%s", phydev->speed, 48 printk(" - %d/%s", phydev->speed,
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index 5c8fcd40ef4d..01bdb2334058 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -389,7 +389,7 @@ static int __init lance_probe( struct net_device *dev)
389 dev->stop = &lance_close; 389 dev->stop = &lance_close;
390 dev->get_stats = &lance_get_stats; 390 dev->get_stats = &lance_get_stats;
391 dev->set_multicast_list = &set_multicast_list; 391 dev->set_multicast_list = &set_multicast_list;
392 dev->set_mac_address = 0; 392 dev->set_mac_address = NULL;
393// KLUDGE -- REMOVE ME 393// KLUDGE -- REMOVE ME
394 set_bit(__LINK_STATE_PRESENT, &dev->state); 394 set_bit(__LINK_STATE_PRESENT, &dev->state);
395 395
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 1a4316336256..983981666800 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -1689,9 +1689,9 @@ MODULE_AUTHOR("Peer Chen, peer.chen@uli.com.tw");
1689MODULE_DESCRIPTION("ULi M5261/M5263 fast ethernet driver"); 1689MODULE_DESCRIPTION("ULi M5261/M5263 fast ethernet driver");
1690MODULE_LICENSE("GPL"); 1690MODULE_LICENSE("GPL");
1691 1691
1692MODULE_PARM(debug, "i"); 1692module_param(debug, int, 0644);
1693MODULE_PARM(mode, "i"); 1693module_param(mode, int, 0);
1694MODULE_PARM(cr6set, "i"); 1694module_param(cr6set, int, 0);
1695MODULE_PARM_DESC(debug, "ULi M5261/M5263 enable debugging (0-1)"); 1695MODULE_PARM_DESC(debug, "ULi M5261/M5263 enable debugging (0-1)");
1696MODULE_PARM_DESC(mode, "ULi M5261/M5263: Bit 0: 10/100Mbps, bit 2: duplex, bit 8: HomePNA"); 1696MODULE_PARM_DESC(mode, "ULi M5261/M5263: Bit 0: 10/100Mbps, bit 2: duplex, bit 8: HomePNA");
1697 1697
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 82c6b757d306..c2d5907dc8e0 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -791,7 +791,7 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
791#endif 791#endif
792 792
793 if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) { 793 if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) {
794 dev->features |= NETIF_F_HW_CSUM; 794 dev->features |= NETIF_F_IP_CSUM;
795 } 795 }
796 796
797 ret = register_netdev(dev); 797 ret = register_netdev(dev);
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 24f7967aab67..c1a6e69f7905 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -243,7 +243,7 @@ config IPW2200_DEBUG
243 243
244config AIRO 244config AIRO
245 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" 245 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
246 depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN) 246 depends on NET_RADIO && ISA_DMA_API && CRYPTO && (PCI || BROKEN)
247 ---help--- 247 ---help---
248 This is the standard Linux driver to support Cisco/Aironet ISA and 248 This is the standard Linux driver to support Cisco/Aironet ISA and
249 PCI 802.11 wireless cards. 249 PCI 802.11 wireless cards.
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index e4729ddf29fd..f0ccfef66445 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -1407,6 +1407,17 @@ static int atmel_close(struct net_device *dev)
1407{ 1407{
1408 struct atmel_private *priv = netdev_priv(dev); 1408 struct atmel_private *priv = netdev_priv(dev);
1409 1409
1410 /* Send event to userspace that we are disassociating */
1411 if (priv->station_state == STATION_STATE_READY) {
1412 union iwreq_data wrqu;
1413
1414 wrqu.data.length = 0;
1415 wrqu.data.flags = 0;
1416 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1417 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1418 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1419 }
1420
1410 atmel_enter_state(priv, STATION_STATE_DOWN); 1421 atmel_enter_state(priv, STATION_STATE_DOWN);
1411 1422
1412 if (priv->bus_type == BUS_TYPE_PCCARD) 1423 if (priv->bus_type == BUS_TYPE_PCCARD)
@@ -1780,10 +1791,10 @@ static int atmel_set_encode(struct net_device *dev,
1780 priv->wep_is_on = 1; 1791 priv->wep_is_on = 1;
1781 priv->exclude_unencrypted = 1; 1792 priv->exclude_unencrypted = 1;
1782 if (priv->wep_key_len[index] > 5) { 1793 if (priv->wep_key_len[index] > 5) {
1783 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64; 1794 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1784 priv->encryption_level = 2; 1795 priv->encryption_level = 2;
1785 } else { 1796 } else {
1786 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128; 1797 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1787 priv->encryption_level = 1; 1798 priv->encryption_level = 1;
1788 } 1799 }
1789 } 1800 }
@@ -1853,6 +1864,181 @@ static int atmel_get_encode(struct net_device *dev,
1853 return 0; 1864 return 0;
1854} 1865}
1855 1866
1867static int atmel_set_encodeext(struct net_device *dev,
1868 struct iw_request_info *info,
1869 union iwreq_data *wrqu,
1870 char *extra)
1871{
1872 struct atmel_private *priv = netdev_priv(dev);
1873 struct iw_point *encoding = &wrqu->encoding;
1874 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1875 int idx, key_len;
1876
1877 /* Determine and validate the key index */
1878 idx = encoding->flags & IW_ENCODE_INDEX;
1879 if (idx) {
1880 if (idx < 1 || idx > WEP_KEYS)
1881 return -EINVAL;
1882 idx--;
1883 } else
1884 idx = priv->default_key;
1885
1886 if ((encoding->flags & IW_ENCODE_DISABLED) ||
1887 ext->alg == IW_ENCODE_ALG_NONE) {
1888 priv->wep_is_on = 0;
1889 priv->encryption_level = 0;
1890 priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1891 }
1892
1893 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1894 priv->default_key = idx;
1895
1896 /* Set the requested key */
1897 switch (ext->alg) {
1898 case IW_ENCODE_ALG_NONE:
1899 break;
1900 case IW_ENCODE_ALG_WEP:
1901 if (ext->key_len > 5) {
1902 priv->wep_key_len[idx] = 13;
1903 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1904 priv->encryption_level = 2;
1905 } else if (ext->key_len > 0) {
1906 priv->wep_key_len[idx] = 5;
1907 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1908 priv->encryption_level = 1;
1909 } else {
1910 return -EINVAL;
1911 }
1912 priv->wep_is_on = 1;
1913 memset(priv->wep_keys[idx], 0, 13);
1914 key_len = min ((int)ext->key_len, priv->wep_key_len[idx]);
1915 memcpy(priv->wep_keys[idx], ext->key, key_len);
1916 break;
1917 default:
1918 return -EINVAL;
1919 }
1920
1921 return -EINPROGRESS;
1922}
1923
1924static int atmel_get_encodeext(struct net_device *dev,
1925 struct iw_request_info *info,
1926 union iwreq_data *wrqu,
1927 char *extra)
1928{
1929 struct atmel_private *priv = netdev_priv(dev);
1930 struct iw_point *encoding = &wrqu->encoding;
1931 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1932 int idx, max_key_len;
1933
1934 max_key_len = encoding->length - sizeof(*ext);
1935 if (max_key_len < 0)
1936 return -EINVAL;
1937
1938 idx = encoding->flags & IW_ENCODE_INDEX;
1939 if (idx) {
1940 if (idx < 1 || idx > WEP_KEYS)
1941 return -EINVAL;
1942 idx--;
1943 } else
1944 idx = priv->default_key;
1945
1946 encoding->flags = idx + 1;
1947 memset(ext, 0, sizeof(*ext));
1948
1949 if (!priv->wep_is_on) {
1950 ext->alg = IW_ENCODE_ALG_NONE;
1951 ext->key_len = 0;
1952 encoding->flags |= IW_ENCODE_DISABLED;
1953 } else {
1954 if (priv->encryption_level > 0)
1955 ext->alg = IW_ENCODE_ALG_WEP;
1956 else
1957 return -EINVAL;
1958
1959 ext->key_len = priv->wep_key_len[idx];
1960 memcpy(ext->key, priv->wep_keys[idx], ext->key_len);
1961 encoding->flags |= IW_ENCODE_ENABLED;
1962 }
1963
1964 return 0;
1965}
1966
1967static int atmel_set_auth(struct net_device *dev,
1968 struct iw_request_info *info,
1969 union iwreq_data *wrqu, char *extra)
1970{
1971 struct atmel_private *priv = netdev_priv(dev);
1972 struct iw_param *param = &wrqu->param;
1973
1974 switch (param->flags & IW_AUTH_INDEX) {
1975 case IW_AUTH_WPA_VERSION:
1976 case IW_AUTH_CIPHER_PAIRWISE:
1977 case IW_AUTH_CIPHER_GROUP:
1978 case IW_AUTH_KEY_MGMT:
1979 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1980 case IW_AUTH_PRIVACY_INVOKED:
1981 /*
1982 * atmel does not use these parameters
1983 */
1984 break;
1985
1986 case IW_AUTH_DROP_UNENCRYPTED:
1987 priv->exclude_unencrypted = param->value ? 1 : 0;
1988 break;
1989
1990 case IW_AUTH_80211_AUTH_ALG: {
1991 if (param->value & IW_AUTH_ALG_SHARED_KEY) {
1992 priv->exclude_unencrypted = 1;
1993 } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1994 priv->exclude_unencrypted = 0;
1995 } else
1996 return -EINVAL;
1997 break;
1998 }
1999
2000 case IW_AUTH_WPA_ENABLED:
2001 /* Silently accept disable of WPA */
2002 if (param->value > 0)
2003 return -EOPNOTSUPP;
2004 break;
2005
2006 default:
2007 return -EOPNOTSUPP;
2008 }
2009 return -EINPROGRESS;
2010}
2011
2012static int atmel_get_auth(struct net_device *dev,
2013 struct iw_request_info *info,
2014 union iwreq_data *wrqu, char *extra)
2015{
2016 struct atmel_private *priv = netdev_priv(dev);
2017 struct iw_param *param = &wrqu->param;
2018
2019 switch (param->flags & IW_AUTH_INDEX) {
2020 case IW_AUTH_DROP_UNENCRYPTED:
2021 param->value = priv->exclude_unencrypted;
2022 break;
2023
2024 case IW_AUTH_80211_AUTH_ALG:
2025 if (priv->exclude_unencrypted == 1)
2026 param->value = IW_AUTH_ALG_SHARED_KEY;
2027 else
2028 param->value = IW_AUTH_ALG_OPEN_SYSTEM;
2029 break;
2030
2031 case IW_AUTH_WPA_ENABLED:
2032 param->value = 0;
2033 break;
2034
2035 default:
2036 return -EOPNOTSUPP;
2037 }
2038 return 0;
2039}
2040
2041
1856static int atmel_get_name(struct net_device *dev, 2042static int atmel_get_name(struct net_device *dev,
1857 struct iw_request_info *info, 2043 struct iw_request_info *info,
1858 char *cwrq, 2044 char *cwrq,
@@ -2289,13 +2475,15 @@ static int atmel_set_wap(struct net_device *dev,
2289{ 2475{
2290 struct atmel_private *priv = netdev_priv(dev); 2476 struct atmel_private *priv = netdev_priv(dev);
2291 int i; 2477 int i;
2292 static const u8 bcast[] = { 255, 255, 255, 255, 255, 255 }; 2478 static const u8 any[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2479 static const u8 off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2293 unsigned long flags; 2480 unsigned long flags;
2294 2481
2295 if (awrq->sa_family != ARPHRD_ETHER) 2482 if (awrq->sa_family != ARPHRD_ETHER)
2296 return -EINVAL; 2483 return -EINVAL;
2297 2484
2298 if (memcmp(bcast, awrq->sa_data, 6) == 0) { 2485 if (!memcmp(any, awrq->sa_data, 6) ||
2486 !memcmp(off, awrq->sa_data, 6)) {
2299 del_timer_sync(&priv->management_timer); 2487 del_timer_sync(&priv->management_timer);
2300 spin_lock_irqsave(&priv->irqlock, flags); 2488 spin_lock_irqsave(&priv->irqlock, flags);
2301 atmel_scan(priv, 1); 2489 atmel_scan(priv, 1);
@@ -2378,6 +2566,15 @@ static const iw_handler atmel_handler[] =
2378 (iw_handler) atmel_get_encode, /* SIOCGIWENCODE */ 2566 (iw_handler) atmel_get_encode, /* SIOCGIWENCODE */
2379 (iw_handler) atmel_set_power, /* SIOCSIWPOWER */ 2567 (iw_handler) atmel_set_power, /* SIOCSIWPOWER */
2380 (iw_handler) atmel_get_power, /* SIOCGIWPOWER */ 2568 (iw_handler) atmel_get_power, /* SIOCGIWPOWER */
2569 (iw_handler) NULL, /* -- hole -- */
2570 (iw_handler) NULL, /* -- hole -- */
2571 (iw_handler) NULL, /* SIOCSIWGENIE */
2572 (iw_handler) NULL, /* SIOCGIWGENIE */
2573 (iw_handler) atmel_set_auth, /* SIOCSIWAUTH */
2574 (iw_handler) atmel_get_auth, /* SIOCGIWAUTH */
2575 (iw_handler) atmel_set_encodeext, /* SIOCSIWENCODEEXT */
2576 (iw_handler) atmel_get_encodeext, /* SIOCGIWENCODEEXT */
2577 (iw_handler) NULL, /* SIOCSIWPMKSA */
2381}; 2578};
2382 2579
2383static const iw_handler atmel_private_handler[] = 2580static const iw_handler atmel_private_handler[] =
@@ -2924,6 +3121,8 @@ static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
2924 u16 ass_id = le16_to_cpu(ass_resp->ass_id); 3121 u16 ass_id = le16_to_cpu(ass_resp->ass_id);
2925 u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length; 3122 u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
2926 3123
3124 union iwreq_data wrqu;
3125
2927 if (frame_len < 8 + rates_len) 3126 if (frame_len < 8 + rates_len)
2928 return; 3127 return;
2929 3128
@@ -2954,6 +3153,14 @@ static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
2954 priv->station_is_associated = 1; 3153 priv->station_is_associated = 1;
2955 priv->station_was_associated = 1; 3154 priv->station_was_associated = 1;
2956 atmel_enter_state(priv, STATION_STATE_READY); 3155 atmel_enter_state(priv, STATION_STATE_READY);
3156
3157 /* Send association event to userspace */
3158 wrqu.data.length = 0;
3159 wrqu.data.flags = 0;
3160 memcpy(wrqu.ap_addr.sa_data, priv->CurrentBSSID, ETH_ALEN);
3161 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3162 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
3163
2957 return; 3164 return;
2958 } 3165 }
2959 3166
@@ -3632,6 +3839,7 @@ static int reset_atmel_card(struct net_device *dev)
3632 3839
3633 struct atmel_private *priv = netdev_priv(dev); 3840 struct atmel_private *priv = netdev_priv(dev);
3634 u8 configuration; 3841 u8 configuration;
3842 int old_state = priv->station_state;
3635 3843
3636 /* data to add to the firmware names, in priority order 3844 /* data to add to the firmware names, in priority order
3637 this implemenents firmware versioning */ 3845 this implemenents firmware versioning */
@@ -3792,6 +4000,17 @@ static int reset_atmel_card(struct net_device *dev)
3792 else 4000 else
3793 build_wep_mib(priv); 4001 build_wep_mib(priv);
3794 4002
4003 if (old_state == STATION_STATE_READY)
4004 {
4005 union iwreq_data wrqu;
4006
4007 wrqu.data.length = 0;
4008 wrqu.data.flags = 0;
4009 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4010 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
4011 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
4012 }
4013
3795 return 1; 4014 return 1;
3796} 4015}
3797 4016
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 7146b69b812c..0aa14c92b570 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -380,8 +380,6 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner)
380 /* initialize common driver fields */ 380 /* initialize common driver fields */
381 drv->driver.name = drv->name; 381 drv->driver.name = drv->name;
382 drv->driver.bus = &pci_bus_type; 382 drv->driver.bus = &pci_bus_type;
383 drv->driver.probe = pci_device_probe;
384 drv->driver.remove = pci_device_remove;
385 /* FIXME, once all of the existing PCI drivers have been fixed to set 383 /* FIXME, once all of the existing PCI drivers have been fixed to set
386 * the pci shutdown function, this test can go away. */ 384 * the pci shutdown function, this test can go away. */
387 if (!drv->driver.shutdown) 385 if (!drv->driver.shutdown)
@@ -513,6 +511,8 @@ struct bus_type pci_bus_type = {
513 .name = "pci", 511 .name = "pci",
514 .match = pci_bus_match, 512 .match = pci_bus_match,
515 .uevent = pci_uevent, 513 .uevent = pci_uevent,
514 .probe = pci_device_probe,
515 .remove = pci_device_remove,
516 .suspend = pci_device_suspend, 516 .suspend = pci_device_suspend,
517 .resume = pci_device_resume, 517 .resume = pci_device_resume,
518 .dev_attrs = pci_dev_attrs, 518 .dev_attrs = pci_dev_attrs,
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 0252582b91cd..0a424a4e8187 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -311,8 +311,6 @@ int pcmcia_register_driver(struct pcmcia_driver *driver)
311 /* initialize common fields */ 311 /* initialize common fields */
312 driver->drv.bus = &pcmcia_bus_type; 312 driver->drv.bus = &pcmcia_bus_type;
313 driver->drv.owner = driver->owner; 313 driver->drv.owner = driver->owner;
314 driver->drv.probe = pcmcia_device_probe;
315 driver->drv.remove = pcmcia_device_remove;
316 314
317 return driver_register(&driver->drv); 315 return driver_register(&driver->drv);
318} 316}
@@ -920,6 +918,37 @@ pcmcia_device_stringattr(prod_id2, prod_id[1]);
920pcmcia_device_stringattr(prod_id3, prod_id[2]); 918pcmcia_device_stringattr(prod_id3, prod_id[2]);
921pcmcia_device_stringattr(prod_id4, prod_id[3]); 919pcmcia_device_stringattr(prod_id4, prod_id[3]);
922 920
921
922static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute *attr, char *buf)
923{
924 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
925
926 if (p_dev->dev.power.power_state.event != PM_EVENT_ON)
927 return sprintf(buf, "off\n");
928 else
929 return sprintf(buf, "on\n");
930}
931
932static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute *attr,
933 const char *buf, size_t count)
934{
935 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
936 int ret = 0;
937
938 if (!count)
939 return -EINVAL;
940
941 if ((p_dev->dev.power.power_state.event == PM_EVENT_ON) &&
942 (!strncmp(buf, "off", 3)))
943 ret = dpm_runtime_suspend(dev, PMSG_SUSPEND);
944 else if ((p_dev->dev.power.power_state.event != PM_EVENT_ON) &&
945 (!strncmp(buf, "on", 2)))
946 dpm_runtime_resume(dev);
947
948 return ret ? ret : count;
949}
950
951
923static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) 952static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
924{ 953{
925 struct pcmcia_device *p_dev = to_pcmcia_dev(dev); 954 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
@@ -945,8 +974,9 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
945 struct device_attribute *attr, const char *buf, size_t count) 974 struct device_attribute *attr, const char *buf, size_t count)
946{ 975{
947 struct pcmcia_device *p_dev = to_pcmcia_dev(dev); 976 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
948 if (!count) 977
949 return -EINVAL; 978 if (!count)
979 return -EINVAL;
950 980
951 down(&p_dev->socket->skt_sem); 981 down(&p_dev->socket->skt_sem);
952 p_dev->allow_func_id_match = 1; 982 p_dev->allow_func_id_match = 1;
@@ -959,6 +989,7 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
959 989
960static struct device_attribute pcmcia_dev_attrs[] = { 990static struct device_attribute pcmcia_dev_attrs[] = {
961 __ATTR(function, 0444, func_show, NULL), 991 __ATTR(function, 0444, func_show, NULL),
992 __ATTR(pm_state, 0644, pcmcia_show_pm_state, pcmcia_store_pm_state),
962 __ATTR_RO(func_id), 993 __ATTR_RO(func_id),
963 __ATTR_RO(manf_id), 994 __ATTR_RO(manf_id),
964 __ATTR_RO(card_id), 995 __ATTR_RO(card_id),
@@ -1167,6 +1198,8 @@ struct bus_type pcmcia_bus_type = {
1167 .uevent = pcmcia_bus_uevent, 1198 .uevent = pcmcia_bus_uevent,
1168 .match = pcmcia_bus_match, 1199 .match = pcmcia_bus_match,
1169 .dev_attrs = pcmcia_dev_attrs, 1200 .dev_attrs = pcmcia_dev_attrs,
1201 .probe = pcmcia_device_probe,
1202 .remove = pcmcia_device_remove,
1170 .suspend = pcmcia_dev_suspend, 1203 .suspend = pcmcia_dev_suspend,
1171 .resume = pcmcia_dev_resume, 1204 .resume = pcmcia_dev_resume,
1172}; 1205};
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index 5d957dfe23d9..fda06941e730 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -171,27 +171,22 @@ static int __init mst_pcmcia_init(void)
171{ 171{
172 int ret; 172 int ret;
173 173
174 mst_pcmcia_device = kzalloc(sizeof(*mst_pcmcia_device), GFP_KERNEL); 174 mst_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
175 if (!mst_pcmcia_device) 175 if (!mst_pcmcia_device)
176 return -ENOMEM; 176 return -ENOMEM;
177 mst_pcmcia_device->name = "pxa2xx-pcmcia"; 177
178 mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops; 178 mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops;
179 179
180 ret = platform_device_register(mst_pcmcia_device); 180 ret = platform_device_add(mst_pcmcia_device);
181
181 if (ret) 182 if (ret)
182 kfree(mst_pcmcia_device); 183 platform_device_put(mst_pcmcia_device);
183 184
184 return ret; 185 return ret;
185} 186}
186 187
187static void __exit mst_pcmcia_exit(void) 188static void __exit mst_pcmcia_exit(void)
188{ 189{
189 /*
190 * This call is supposed to free our mst_pcmcia_device.
191 * Unfortunately platform_device don't have a free method, and
192 * we can't assume it's free of any reference at this point so we
193 * can't free it either.
194 */
195 platform_device_unregister(mst_pcmcia_device); 190 platform_device_unregister(mst_pcmcia_device);
196} 191}
197 192
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index 12a7244a5ec8..fd3647368955 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -263,30 +263,25 @@ static int __init sharpsl_pcmcia_init(void)
263{ 263{
264 int ret; 264 int ret;
265 265
266 sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs; 266 sharpsl_pcmcia_ops.nr = platform_scoop_config->num_devs;
267 sharpsl_pcmcia_device = kzalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); 267 sharpsl_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
268
268 if (!sharpsl_pcmcia_device) 269 if (!sharpsl_pcmcia_device)
269 return -ENOMEM; 270 return -ENOMEM;
270 271
271 sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
272 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; 272 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
273 sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev; 273 sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev;
274
275 ret = platform_device_add(sharpsl_pcmcia_device);
274 276
275 ret = platform_device_register(sharpsl_pcmcia_device);
276 if (ret) 277 if (ret)
277 kfree(sharpsl_pcmcia_device); 278 platform_device_put(sharpsl_pcmcia_device);
278 279
279 return ret; 280 return ret;
280} 281}
281 282
282static void __exit sharpsl_pcmcia_exit(void) 283static void __exit sharpsl_pcmcia_exit(void)
283{ 284{
284 /*
285 * This call is supposed to free our sharpsl_pcmcia_device.
286 * Unfortunately platform_device don't have a free method, and
287 * we can't assume it's free of any reference at this point so we
288 * can't free it either.
289 */
290 platform_device_unregister(sharpsl_pcmcia_device); 285 platform_device_unregister(sharpsl_pcmcia_device);
291} 286}
292 287
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index 7a7744662d54..5ab1cdef7c48 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -98,6 +98,30 @@ static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, si
98} 98}
99static CLASS_DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert); 99static CLASS_DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert);
100 100
101
102static ssize_t pccard_show_card_pm_state(struct class_device *dev, char *buf)
103{
104 struct pcmcia_socket *s = to_socket(dev);
105 return sprintf(buf, "%s\n", s->state & SOCKET_SUSPEND ? "off" : "on");
106}
107
108static ssize_t pccard_store_card_pm_state(struct class_device *dev, const char *buf, size_t count)
109{
110 ssize_t ret = -EINVAL;
111 struct pcmcia_socket *s = to_socket(dev);
112
113 if (!count)
114 return -EINVAL;
115
116 if (!(s->state & SOCKET_SUSPEND) && !strncmp(buf, "off", 3))
117 ret = pcmcia_suspend_card(s);
118 else if ((s->state & SOCKET_SUSPEND) && !strncmp(buf, "on", 2))
119 ret = pcmcia_resume_card(s);
120
121 return ret ? -ENODEV : count;
122}
123static CLASS_DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state);
124
101static ssize_t pccard_store_eject(struct class_device *dev, const char *buf, size_t count) 125static ssize_t pccard_store_eject(struct class_device *dev, const char *buf, size_t count)
102{ 126{
103 ssize_t ret; 127 ssize_t ret;
@@ -320,6 +344,7 @@ static struct class_device_attribute *pccard_socket_attributes[] = {
320 &class_device_attr_card_vpp, 344 &class_device_attr_card_vpp,
321 &class_device_attr_card_vcc, 345 &class_device_attr_card_vcc,
322 &class_device_attr_card_insert, 346 &class_device_attr_card_insert,
347 &class_device_attr_card_pm_state,
323 &class_device_attr_card_eject, 348 &class_device_attr_card_eject,
324 &class_device_attr_card_irq_mask, 349 &class_device_attr_card_irq_mask,
325 &class_device_attr_available_resources_setup_done, 350 &class_device_attr_available_resources_setup_done,
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index 15fb758a9e52..7cafacdd12b0 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -195,6 +195,8 @@ static int pnp_bus_resume(struct device *dev)
195struct bus_type pnp_bus_type = { 195struct bus_type pnp_bus_type = {
196 .name = "pnp", 196 .name = "pnp",
197 .match = pnp_bus_match, 197 .match = pnp_bus_match,
198 .probe = pnp_device_probe,
199 .remove = pnp_device_remove,
198 .suspend = pnp_bus_suspend, 200 .suspend = pnp_bus_suspend,
199 .resume = pnp_bus_resume, 201 .resume = pnp_bus_resume,
200}; 202};
@@ -215,8 +217,6 @@ int pnp_register_driver(struct pnp_driver *drv)
215 217
216 drv->driver.name = drv->name; 218 drv->driver.name = drv->name;
217 drv->driver.bus = &pnp_bus_type; 219 drv->driver.bus = &pnp_bus_type;
218 drv->driver.probe = pnp_device_probe;
219 drv->driver.remove = pnp_device_remove;
220 220
221 count = driver_register(&drv->driver); 221 count = driver_register(&drv->driver);
222 222
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index dc749609699a..5480119ff9d3 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -147,8 +147,6 @@ int rio_register_driver(struct rio_driver *rdrv)
147 /* initialize common driver fields */ 147 /* initialize common driver fields */
148 rdrv->driver.name = rdrv->name; 148 rdrv->driver.name = rdrv->name;
149 rdrv->driver.bus = &rio_bus_type; 149 rdrv->driver.bus = &rio_bus_type;
150 rdrv->driver.probe = rio_device_probe;
151 rdrv->driver.remove = rio_device_remove;
152 150
153 /* register with core */ 151 /* register with core */
154 return driver_register(&rdrv->driver); 152 return driver_register(&rdrv->driver);
@@ -204,7 +202,9 @@ static struct device rio_bus = {
204struct bus_type rio_bus_type = { 202struct bus_type rio_bus_type = {
205 .name = "rapidio", 203 .name = "rapidio",
206 .match = rio_match_bus, 204 .match = rio_match_bus,
207 .dev_attrs = rio_dev_attrs 205 .dev_attrs = rio_dev_attrs,
206 .probe = rio_device_probe,
207 .remove = rio_device_remove,
208}; 208};
209 209
210/** 210/**
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index e849289d4f3c..503a568e47c3 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -52,11 +52,7 @@ ccwgroup_uevent (struct device *dev, char **envp, int num_envp, char *buffer,
52 return 0; 52 return 0;
53} 53}
54 54
55static struct bus_type ccwgroup_bus_type = { 55static struct bus_type ccwgroup_bus_type;
56 .name = "ccwgroup",
57 .match = ccwgroup_bus_match,
58 .uevent = ccwgroup_uevent,
59};
60 56
61static inline void 57static inline void
62__ccwgroup_remove_symlinks(struct ccwgroup_device *gdev) 58__ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
@@ -389,6 +385,14 @@ ccwgroup_remove (struct device *dev)
389 return 0; 385 return 0;
390} 386}
391 387
388static struct bus_type ccwgroup_bus_type = {
389 .name = "ccwgroup",
390 .match = ccwgroup_bus_match,
391 .uevent = ccwgroup_uevent,
392 .probe = ccwgroup_probe,
393 .remove = ccwgroup_remove,
394};
395
392int 396int
393ccwgroup_driver_register (struct ccwgroup_driver *cdriver) 397ccwgroup_driver_register (struct ccwgroup_driver *cdriver)
394{ 398{
@@ -396,8 +400,6 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver)
396 cdriver->driver = (struct device_driver) { 400 cdriver->driver = (struct device_driver) {
397 .bus = &ccwgroup_bus_type, 401 .bus = &ccwgroup_bus_type,
398 .name = cdriver->name, 402 .name = cdriver->name,
399 .probe = ccwgroup_probe,
400 .remove = ccwgroup_remove,
401 }; 403 };
402 404
403 return driver_register(&cdriver->driver); 405 return driver_register(&cdriver->driver);
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index e565193650c7..2d319fb812ca 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -542,9 +542,41 @@ css_bus_match (struct device *dev, struct device_driver *drv)
542 return 0; 542 return 0;
543} 543}
544 544
545static int
546css_probe (struct device *dev)
547{
548 struct subchannel *sch;
549
550 sch = to_subchannel(dev);
551 sch->driver = container_of (dev->driver, struct css_driver, drv);
552 return (sch->driver->probe ? sch->driver->probe(sch) : 0);
553}
554
555static int
556css_remove (struct device *dev)
557{
558 struct subchannel *sch;
559
560 sch = to_subchannel(dev);
561 return (sch->driver->remove ? sch->driver->remove(sch) : 0);
562}
563
564static void
565css_shutdown (struct device *dev)
566{
567 struct subchannel *sch;
568
569 sch = to_subchannel(dev);
570 if (sch->driver->shutdown)
571 sch->driver->shutdown(sch);
572}
573
545struct bus_type css_bus_type = { 574struct bus_type css_bus_type = {
546 .name = "css", 575 .name = "css",
547 .match = &css_bus_match, 576 .match = css_bus_match,
577 .probe = css_probe,
578 .remove = css_remove,
579 .shutdown = css_shutdown,
548}; 580};
549 581
550subsys_initcall(init_channel_subsystem); 582subsys_initcall(init_channel_subsystem);
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 251ebd7a7d3a..aa5ab5d4547c 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -115,6 +115,7 @@ struct ccw_device_private {
115 * Currently, we only care about I/O subchannels (type 0), these 115 * Currently, we only care about I/O subchannels (type 0), these
116 * have a ccw_device connected to them. 116 * have a ccw_device connected to them.
117 */ 117 */
118struct subchannel;
118struct css_driver { 119struct css_driver {
119 unsigned int subchannel_type; 120 unsigned int subchannel_type;
120 struct device_driver drv; 121 struct device_driver drv;
@@ -122,6 +123,9 @@ struct css_driver {
122 int (*notify)(struct device *, int); 123 int (*notify)(struct device *, int);
123 void (*verify)(struct device *); 124 void (*verify)(struct device *);
124 void (*termination)(struct device *); 125 void (*termination)(struct device *);
126 int (*probe)(struct subchannel *);
127 int (*remove)(struct subchannel *);
128 void (*shutdown)(struct subchannel *);
125}; 129};
126 130
127/* 131/*
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index fa3e4c0a2536..eb73605a0527 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -107,33 +107,29 @@ ccw_uevent (struct device *dev, char **envp, int num_envp,
107 return 0; 107 return 0;
108} 108}
109 109
110struct bus_type ccw_bus_type = { 110struct bus_type ccw_bus_type;
111 .name = "ccw",
112 .match = &ccw_bus_match,
113 .uevent = &ccw_uevent,
114};
115 111
116static int io_subchannel_probe (struct device *); 112static int io_subchannel_probe (struct subchannel *);
117static int io_subchannel_remove (struct device *); 113static int io_subchannel_remove (struct subchannel *);
118void io_subchannel_irq (struct device *); 114void io_subchannel_irq (struct device *);
119static int io_subchannel_notify(struct device *, int); 115static int io_subchannel_notify(struct device *, int);
120static void io_subchannel_verify(struct device *); 116static void io_subchannel_verify(struct device *);
121static void io_subchannel_ioterm(struct device *); 117static void io_subchannel_ioterm(struct device *);
122static void io_subchannel_shutdown(struct device *); 118static void io_subchannel_shutdown(struct subchannel *);
123 119
124struct css_driver io_subchannel_driver = { 120struct css_driver io_subchannel_driver = {
125 .subchannel_type = SUBCHANNEL_TYPE_IO, 121 .subchannel_type = SUBCHANNEL_TYPE_IO,
126 .drv = { 122 .drv = {
127 .name = "io_subchannel", 123 .name = "io_subchannel",
128 .bus = &css_bus_type, 124 .bus = &css_bus_type,
129 .probe = &io_subchannel_probe,
130 .remove = &io_subchannel_remove,
131 .shutdown = &io_subchannel_shutdown,
132 }, 125 },
133 .irq = io_subchannel_irq, 126 .irq = io_subchannel_irq,
134 .notify = io_subchannel_notify, 127 .notify = io_subchannel_notify,
135 .verify = io_subchannel_verify, 128 .verify = io_subchannel_verify,
136 .termination = io_subchannel_ioterm, 129 .termination = io_subchannel_ioterm,
130 .probe = io_subchannel_probe,
131 .remove = io_subchannel_remove,
132 .shutdown = io_subchannel_shutdown,
137}; 133};
138 134
139struct workqueue_struct *ccw_device_work; 135struct workqueue_struct *ccw_device_work;
@@ -803,14 +799,12 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
803} 799}
804 800
805static int 801static int
806io_subchannel_probe (struct device *pdev) 802io_subchannel_probe (struct subchannel *sch)
807{ 803{
808 struct subchannel *sch;
809 struct ccw_device *cdev; 804 struct ccw_device *cdev;
810 int rc; 805 int rc;
811 unsigned long flags; 806 unsigned long flags;
812 807
813 sch = to_subchannel(pdev);
814 if (sch->dev.driver_data) { 808 if (sch->dev.driver_data) {
815 /* 809 /*
816 * This subchannel already has an associated ccw_device. 810 * This subchannel already has an associated ccw_device.
@@ -846,7 +840,7 @@ io_subchannel_probe (struct device *pdev)
846 memset(cdev->private, 0, sizeof(struct ccw_device_private)); 840 memset(cdev->private, 0, sizeof(struct ccw_device_private));
847 atomic_set(&cdev->private->onoff, 0); 841 atomic_set(&cdev->private->onoff, 0);
848 cdev->dev = (struct device) { 842 cdev->dev = (struct device) {
849 .parent = pdev, 843 .parent = &sch->dev,
850 .release = ccw_device_release, 844 .release = ccw_device_release,
851 }; 845 };
852 INIT_LIST_HEAD(&cdev->private->kick_work.entry); 846 INIT_LIST_HEAD(&cdev->private->kick_work.entry);
@@ -859,7 +853,7 @@ io_subchannel_probe (struct device *pdev)
859 return -ENODEV; 853 return -ENODEV;
860 } 854 }
861 855
862 rc = io_subchannel_recog(cdev, to_subchannel(pdev)); 856 rc = io_subchannel_recog(cdev, sch);
863 if (rc) { 857 if (rc) {
864 spin_lock_irqsave(&sch->lock, flags); 858 spin_lock_irqsave(&sch->lock, flags);
865 sch->dev.driver_data = NULL; 859 sch->dev.driver_data = NULL;
@@ -883,17 +877,17 @@ ccw_device_unregister(void *data)
883} 877}
884 878
885static int 879static int
886io_subchannel_remove (struct device *dev) 880io_subchannel_remove (struct subchannel *sch)
887{ 881{
888 struct ccw_device *cdev; 882 struct ccw_device *cdev;
889 unsigned long flags; 883 unsigned long flags;
890 884
891 if (!dev->driver_data) 885 if (!sch->dev.driver_data)
892 return 0; 886 return 0;
893 cdev = dev->driver_data; 887 cdev = sch->dev.driver_data;
894 /* Set ccw device to not operational and drop reference. */ 888 /* Set ccw device to not operational and drop reference. */
895 spin_lock_irqsave(cdev->ccwlock, flags); 889 spin_lock_irqsave(cdev->ccwlock, flags);
896 dev->driver_data = NULL; 890 sch->dev.driver_data = NULL;
897 cdev->private->state = DEV_STATE_NOT_OPER; 891 cdev->private->state = DEV_STATE_NOT_OPER;
898 spin_unlock_irqrestore(cdev->ccwlock, flags); 892 spin_unlock_irqrestore(cdev->ccwlock, flags);
899 /* 893 /*
@@ -948,14 +942,12 @@ io_subchannel_ioterm(struct device *dev)
948} 942}
949 943
950static void 944static void
951io_subchannel_shutdown(struct device *dev) 945io_subchannel_shutdown(struct subchannel *sch)
952{ 946{
953 struct subchannel *sch;
954 struct ccw_device *cdev; 947 struct ccw_device *cdev;
955 int ret; 948 int ret;
956 949
957 sch = to_subchannel(dev); 950 cdev = sch->dev.driver_data;
958 cdev = dev->driver_data;
959 951
960 if (cio_is_console(sch->schid)) 952 if (cio_is_console(sch->schid))
961 return; 953 return;
@@ -1129,6 +1121,14 @@ ccw_device_remove (struct device *dev)
1129 return 0; 1121 return 0;
1130} 1122}
1131 1123
1124struct bus_type ccw_bus_type = {
1125 .name = "ccw",
1126 .match = ccw_bus_match,
1127 .uevent = ccw_uevent,
1128 .probe = ccw_device_probe,
1129 .remove = ccw_device_remove,
1130};
1131
1132int 1132int
1133ccw_driver_register (struct ccw_driver *cdriver) 1133ccw_driver_register (struct ccw_driver *cdriver)
1134{ 1134{
@@ -1136,8 +1136,6 @@ ccw_driver_register (struct ccw_driver *cdriver)
1136 1136
1137 drv->bus = &ccw_bus_type; 1137 drv->bus = &ccw_bus_type;
1138 drv->name = cdriver->name; 1138 drv->name = cdriver->name;
1139 drv->probe = ccw_device_probe;
1140 drv->remove = ccw_device_remove;
1141 1139
1142 return driver_register(drv); 1140 return driver_register(drv);
1143} 1141}
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
index 92e6c5639dd3..015db40ad8a4 100644
--- a/drivers/sbus/char/aurora.c
+++ b/drivers/sbus/char/aurora.c
@@ -92,7 +92,6 @@ static struct Aurora_port aurora_port[AURORA_TNPORTS] = {
92 92
93/* no longer used. static struct Aurora_board * IRQ_to_board[16] = { NULL, } ;*/ 93/* no longer used. static struct Aurora_board * IRQ_to_board[16] = { NULL, } ;*/
94static unsigned char * tmp_buf = NULL; 94static unsigned char * tmp_buf = NULL;
95static DECLARE_MUTEX(tmp_buf_sem);
96 95
97DECLARE_TASK_QUEUE(tq_aurora); 96DECLARE_TASK_QUEUE(tq_aurora);
98 97
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index b9d2bb88787a..320e765fa0cd 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -45,7 +45,7 @@ obj-$(CONFIG_CYBERSTORMII_SCSI) += NCR53C9x.o cyberstormII.o
45obj-$(CONFIG_BLZ2060_SCSI) += NCR53C9x.o blz2060.o 45obj-$(CONFIG_BLZ2060_SCSI) += NCR53C9x.o blz2060.o
46obj-$(CONFIG_BLZ1230_SCSI) += NCR53C9x.o blz1230.o 46obj-$(CONFIG_BLZ1230_SCSI) += NCR53C9x.o blz1230.o
47obj-$(CONFIG_FASTLANE_SCSI) += NCR53C9x.o fastlane.o 47obj-$(CONFIG_FASTLANE_SCSI) += NCR53C9x.o fastlane.o
48obj-$(CONFIG_OKTAGON_SCSI) += NCR53C9x.o oktagon_esp.o oktagon_io.o 48obj-$(CONFIG_OKTAGON_SCSI) += NCR53C9x.o oktagon_esp_mod.o
49obj-$(CONFIG_ATARI_SCSI) += atari_scsi.o 49obj-$(CONFIG_ATARI_SCSI) += atari_scsi.o
50obj-$(CONFIG_MAC_SCSI) += mac_scsi.o 50obj-$(CONFIG_MAC_SCSI) += mac_scsi.o
51obj-$(CONFIG_SCSI_MAC_ESP) += mac_esp.o NCR53C9x.o 51obj-$(CONFIG_SCSI_MAC_ESP) += mac_esp.o NCR53C9x.o
@@ -164,6 +164,7 @@ CFLAGS_ncr53c8xx.o := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m)
164zalon7xx-objs := zalon.o ncr53c8xx.o 164zalon7xx-objs := zalon.o ncr53c8xx.o
165NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o 165NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o
166libata-objs := libata-core.o libata-scsi.o 166libata-objs := libata-core.o libata-scsi.o
167oktagon_esp_mod-objs := oktagon_esp.o oktagon_io.o
167 168
168# Files generated that shall be removed upon make clean 169# Files generated that shall be removed upon make clean
169clean-files := 53c7xx_d.h 53c700_d.h \ 170clean-files := 53c7xx_d.h 53c700_d.h \
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
index 640590bd014a..c7dd0154d012 100644
--- a/drivers/scsi/NCR53C9x.c
+++ b/drivers/scsi/NCR53C9x.c
@@ -1799,6 +1799,7 @@ static int esp_do_data(struct NCR_ESP *esp, struct ESP_regs *eregs)
1799 */ 1799 */
1800 int oldphase, i = 0; /* or where we left off last time ?? esp->current_data ?? */ 1800 int oldphase, i = 0; /* or where we left off last time ?? esp->current_data ?? */
1801 int fifocnt = 0; 1801 int fifocnt = 0;
1802 unsigned char *p = phys_to_virt((unsigned long)SCptr->SCp.ptr);
1802 1803
1803 oldphase = esp_read(eregs->esp_status) & ESP_STAT_PMASK; 1804 oldphase = esp_read(eregs->esp_status) & ESP_STAT_PMASK;
1804 1805
@@ -1860,7 +1861,7 @@ static int esp_do_data(struct NCR_ESP *esp, struct ESP_regs *eregs)
1860 1861
1861 /* read fifo */ 1862 /* read fifo */
1862 for(j=0;j<fifocnt;j++) 1863 for(j=0;j<fifocnt;j++)
1863 SCptr->SCp.ptr[i++] = esp_read(eregs->esp_fdata); 1864 p[i++] = esp_read(eregs->esp_fdata);
1864 1865
1865 ESPDATA(("(%d) ", i)); 1866 ESPDATA(("(%d) ", i));
1866 1867
@@ -1882,7 +1883,7 @@ static int esp_do_data(struct NCR_ESP *esp, struct ESP_regs *eregs)
1882 1883
1883 /* fill fifo */ 1884 /* fill fifo */
1884 for(j=0;j<this_count;j++) 1885 for(j=0;j<this_count;j++)
1885 esp_write(eregs->esp_fdata, SCptr->SCp.ptr[i++]); 1886 esp_write(eregs->esp_fdata, p[i++]);
1886 1887
1887 /* how many left if this goes out ?? */ 1888 /* how many left if this goes out ?? */
1888 hmuch -= this_count; 1889 hmuch -= this_count;
diff --git a/drivers/scsi/blz1230.c b/drivers/scsi/blz1230.c
index 763e409a1ff3..3867ac2de4c2 100644
--- a/drivers/scsi/blz1230.c
+++ b/drivers/scsi/blz1230.c
@@ -224,7 +224,7 @@ static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp)
224static void dma_dump_state(struct NCR_ESP *esp) 224static void dma_dump_state(struct NCR_ESP *esp)
225{ 225{
226 ESPLOG(("intreq:<%04x>, intena:<%04x>\n", 226 ESPLOG(("intreq:<%04x>, intena:<%04x>\n",
227 custom.intreqr, custom.intenar)); 227 amiga_custom.intreqr, amiga_custom.intenar));
228} 228}
229 229
230void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length) 230void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length)
@@ -298,7 +298,7 @@ static int dma_irq_p(struct NCR_ESP *esp)
298 298
299static int dma_ports_p(struct NCR_ESP *esp) 299static int dma_ports_p(struct NCR_ESP *esp)
300{ 300{
301 return ((custom.intenar) & IF_PORTS); 301 return ((amiga_custom.intenar) & IF_PORTS);
302} 302}
303 303
304static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) 304static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
diff --git a/drivers/scsi/blz2060.c b/drivers/scsi/blz2060.c
index d72d05fffdfa..4ebe69e32756 100644
--- a/drivers/scsi/blz2060.c
+++ b/drivers/scsi/blz2060.c
@@ -190,7 +190,7 @@ static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp)
190static void dma_dump_state(struct NCR_ESP *esp) 190static void dma_dump_state(struct NCR_ESP *esp)
191{ 191{
192 ESPLOG(("intreq:<%04x>, intena:<%04x>\n", 192 ESPLOG(("intreq:<%04x>, intena:<%04x>\n",
193 custom.intreqr, custom.intenar)); 193 amiga_custom.intreqr, amiga_custom.intenar));
194} 194}
195 195
196static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length) 196static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length)
@@ -251,7 +251,7 @@ static void dma_led_on(struct NCR_ESP *esp)
251 251
252static int dma_ports_p(struct NCR_ESP *esp) 252static int dma_ports_p(struct NCR_ESP *esp)
253{ 253{
254 return ((custom.intenar) & IF_PORTS); 254 return ((amiga_custom.intenar) & IF_PORTS);
255} 255}
256 256
257static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) 257static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
diff --git a/drivers/scsi/cyberstorm.c b/drivers/scsi/cyberstorm.c
index f9b940e56430..a4a4fac5c0a1 100644
--- a/drivers/scsi/cyberstorm.c
+++ b/drivers/scsi/cyberstorm.c
@@ -223,7 +223,7 @@ static void dma_dump_state(struct NCR_ESP *esp)
223 esp->esp_id, ((struct cyber_dma_registers *) 223 esp->esp_id, ((struct cyber_dma_registers *)
224 (esp->dregs))->cond_reg)); 224 (esp->dregs))->cond_reg));
225 ESPLOG(("intreq:<%04x>, intena:<%04x>\n", 225 ESPLOG(("intreq:<%04x>, intena:<%04x>\n",
226 custom.intreqr, custom.intenar)); 226 amiga_custom.intreqr, amiga_custom.intenar));
227} 227}
228 228
229static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length) 229static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length)
@@ -322,7 +322,7 @@ static void dma_led_on(struct NCR_ESP *esp)
322 322
323static int dma_ports_p(struct NCR_ESP *esp) 323static int dma_ports_p(struct NCR_ESP *esp)
324{ 324{
325 return ((custom.intenar) & IF_PORTS); 325 return ((amiga_custom.intenar) & IF_PORTS);
326} 326}
327 327
328static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) 328static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
diff --git a/drivers/scsi/cyberstormII.c b/drivers/scsi/cyberstormII.c
index a3caabfd7557..3a803d73bc5f 100644
--- a/drivers/scsi/cyberstormII.c
+++ b/drivers/scsi/cyberstormII.c
@@ -200,7 +200,7 @@ static void dma_dump_state(struct NCR_ESP *esp)
200 esp->esp_id, ((struct cyberII_dma_registers *) 200 esp->esp_id, ((struct cyberII_dma_registers *)
201 (esp->dregs))->cond_reg)); 201 (esp->dregs))->cond_reg));
202 ESPLOG(("intreq:<%04x>, intena:<%04x>\n", 202 ESPLOG(("intreq:<%04x>, intena:<%04x>\n",
203 custom.intreqr, custom.intenar)); 203 amiga_custom.intreqr, amiga_custom.intenar));
204} 204}
205 205
206static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length) 206static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length)
@@ -259,7 +259,7 @@ static void dma_led_on(struct NCR_ESP *esp)
259 259
260static int dma_ports_p(struct NCR_ESP *esp) 260static int dma_ports_p(struct NCR_ESP *esp)
261{ 261{
262 return ((custom.intenar) & IF_PORTS); 262 return ((amiga_custom.intenar) & IF_PORTS);
263} 263}
264 264
265static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) 265static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
diff --git a/drivers/scsi/fastlane.c b/drivers/scsi/fastlane.c
index ccee68b52f7e..8ae9c406a83b 100644
--- a/drivers/scsi/fastlane.c
+++ b/drivers/scsi/fastlane.c
@@ -268,7 +268,7 @@ static void dma_dump_state(struct NCR_ESP *esp)
268 esp->esp_id, ((struct fastlane_dma_registers *) 268 esp->esp_id, ((struct fastlane_dma_registers *)
269 (esp->dregs))->cond_reg)); 269 (esp->dregs))->cond_reg));
270 ESPLOG(("intreq:<%04x>, intena:<%04x>\n", 270 ESPLOG(("intreq:<%04x>, intena:<%04x>\n",
271 custom.intreqr, custom.intenar)); 271 amiga_custom.intreqr, amiga_custom.intenar));
272} 272}
273 273
274static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length) 274static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length)
@@ -368,7 +368,7 @@ static void dma_led_on(struct NCR_ESP *esp)
368 368
369static int dma_ports_p(struct NCR_ESP *esp) 369static int dma_ports_p(struct NCR_ESP *esp)
370{ 370{
371 return ((custom.intenar) & IF_PORTS); 371 return ((amiga_custom.intenar) & IF_PORTS);
372} 372}
373 373
374static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) 374static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
diff --git a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c
index 5d9c9ada814f..dee426f8c07b 100644
--- a/drivers/scsi/oktagon_esp.c
+++ b/drivers/scsi/oktagon_esp.c
@@ -490,7 +490,7 @@ static void dma_led_on(struct NCR_ESP *esp)
490 490
491static int dma_ports_p(struct NCR_ESP *esp) 491static int dma_ports_p(struct NCR_ESP *esp)
492{ 492{
493 return ((custom.intenar) & IF_PORTS); 493 return ((amiga_custom.intenar) & IF_PORTS);
494} 494}
495 495
496static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) 496static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 3ded9daaf4a0..0e529f8171c4 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -221,8 +221,6 @@ static struct bus_type pseudo_lld_bus;
221static struct device_driver sdebug_driverfs_driver = { 221static struct device_driver sdebug_driverfs_driver = {
222 .name = sdebug_proc_name, 222 .name = sdebug_proc_name,
223 .bus = &pseudo_lld_bus, 223 .bus = &pseudo_lld_bus,
224 .probe = sdebug_driver_probe,
225 .remove = sdebug_driver_remove,
226}; 224};
227 225
228static const int check_condition_result = 226static const int check_condition_result =
@@ -1796,6 +1794,8 @@ static int pseudo_lld_bus_match(struct device *dev,
1796static struct bus_type pseudo_lld_bus = { 1794static struct bus_type pseudo_lld_bus = {
1797 .name = "pseudo", 1795 .name = "pseudo",
1798 .match = pseudo_lld_bus_match, 1796 .match = pseudo_lld_bus_match,
1797 .probe = sdebug_driver_probe,
1798 .remove = sdebug_driver_remove,
1799}; 1799};
1800 1800
1801static void sdebug_release_adapter(struct device * dev) 1801static void sdebug_release_adapter(struct device * dev)
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index fd63add6a577..fb53eeaee617 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -465,7 +465,7 @@ wd33c93_execute(struct Scsi_Host *instance)
465 */ 465 */
466 466
467 cmd = (struct scsi_cmnd *) hostdata->input_Q; 467 cmd = (struct scsi_cmnd *) hostdata->input_Q;
468 prev = 0; 468 prev = NULL;
469 while (cmd) { 469 while (cmd) {
470 if (!(hostdata->busy[cmd->device->id] & (1 << cmd->device->lun))) 470 if (!(hostdata->busy[cmd->device->id] & (1 << cmd->device->lun)))
471 break; 471 break;
@@ -1569,7 +1569,7 @@ wd33c93_abort(struct scsi_cmnd * cmd)
1569 */ 1569 */
1570 1570
1571 tmp = (struct scsi_cmnd *) hostdata->input_Q; 1571 tmp = (struct scsi_cmnd *) hostdata->input_Q;
1572 prev = 0; 1572 prev = NULL;
1573 while (tmp) { 1573 while (tmp) {
1574 if (tmp == cmd) { 1574 if (tmp == cmd) {
1575 if (prev) 1575 if (prev)
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 4dd5c3f98167..8cbf0fc5a225 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -143,7 +143,6 @@ static int m68328_console_cbaud = DEFAULT_CBAUD;
143 * memory if large numbers of serial ports are open. 143 * memory if large numbers of serial ports are open.
144 */ 144 */
145static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */ 145static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */
146DECLARE_MUTEX(tmp_buf_sem);
147 146
148static inline int serial_paranoia_check(struct m68k_serial *info, 147static inline int serial_paranoia_check(struct m68k_serial *info,
149 char *name, const char *routine) 148 char *name, const char *routine)
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 54e5cc0dd5f8..fb610c3634a4 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -41,6 +41,7 @@
41#include <linux/serial.h> 41#include <linux/serial.h>
42#include <linux/serial_8250.h> 42#include <linux/serial_8250.h>
43#include <linux/nmi.h> 43#include <linux/nmi.h>
44#include <linux/mutex.h>
44 45
45#include <asm/io.h> 46#include <asm/io.h>
46#include <asm/irq.h> 47#include <asm/irq.h>
@@ -2467,7 +2468,7 @@ static struct platform_device *serial8250_isa_devs;
2467 * 16x50 serial ports to be configured at run-time, to support PCMCIA 2468 * 16x50 serial ports to be configured at run-time, to support PCMCIA
2468 * modems and PCI multiport cards. 2469 * modems and PCI multiport cards.
2469 */ 2470 */
2470static DECLARE_MUTEX(serial_sem); 2471static DEFINE_MUTEX(serial_mutex);
2471 2472
2472static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port) 2473static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port)
2473{ 2474{
@@ -2522,7 +2523,7 @@ int serial8250_register_port(struct uart_port *port)
2522 if (port->uartclk == 0) 2523 if (port->uartclk == 0)
2523 return -EINVAL; 2524 return -EINVAL;
2524 2525
2525 down(&serial_sem); 2526 mutex_lock(&serial_mutex);
2526 2527
2527 uart = serial8250_find_match_or_unused(port); 2528 uart = serial8250_find_match_or_unused(port);
2528 if (uart) { 2529 if (uart) {
@@ -2544,7 +2545,7 @@ int serial8250_register_port(struct uart_port *port)
2544 if (ret == 0) 2545 if (ret == 0)
2545 ret = uart->port.line; 2546 ret = uart->port.line;
2546 } 2547 }
2547 up(&serial_sem); 2548 mutex_unlock(&serial_mutex);
2548 2549
2549 return ret; 2550 return ret;
2550} 2551}
@@ -2561,7 +2562,7 @@ void serial8250_unregister_port(int line)
2561{ 2562{
2562 struct uart_8250_port *uart = &serial8250_ports[line]; 2563 struct uart_8250_port *uart = &serial8250_ports[line];
2563 2564
2564 down(&serial_sem); 2565 mutex_lock(&serial_mutex);
2565 uart_remove_one_port(&serial8250_reg, &uart->port); 2566 uart_remove_one_port(&serial8250_reg, &uart->port);
2566 if (serial8250_isa_devs) { 2567 if (serial8250_isa_devs) {
2567 uart->port.flags &= ~UPF_BOOT_AUTOCONF; 2568 uart->port.flags &= ~UPF_BOOT_AUTOCONF;
@@ -2571,7 +2572,7 @@ void serial8250_unregister_port(int line)
2571 } else { 2572 } else {
2572 uart->port.dev = NULL; 2573 uart->port.dev = NULL;
2573 } 2574 }
2574 up(&serial_sem); 2575 mutex_unlock(&serial_mutex);
2575} 2576}
2576EXPORT_SYMBOL(serial8250_unregister_port); 2577EXPORT_SYMBOL(serial8250_unregister_port);
2577 2578
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 698cb76819d9..843717275d49 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -280,6 +280,40 @@ config SERIAL_AMBA_PL011_CONSOLE
280 your boot loader (lilo or loadlin) about how to pass options to the 280 your boot loader (lilo or loadlin) about how to pass options to the
281 kernel at boot time.) 281 kernel at boot time.)
282 282
283config SERIAL_AT91
284 bool "AT91RM9200 serial port support"
285 depends on ARM && ARCH_AT91RM9200
286 select SERIAL_CORE
287 help
288 This enables the driver for the on-chip UARTs of the AT91RM9200
289 processor.
290
291config SERIAL_AT91_CONSOLE
292 bool "Support for console on AT91RM9200 serial port"
293 depends on SERIAL_AT91=y
294 select SERIAL_CORE_CONSOLE
295 help
296 Say Y here if you wish to use a UART on the AT91RM9200 as the system
297 console (the system console is the device which receives all kernel
298 messages and warnings and which allows logins in single user mode).
299
300config SERIAL_AT91_TTYAT
301 bool "Install as device ttyAT0-4 instead of ttyS0-4"
302 depends on SERIAL_AT91=y
303 help
304 Say Y here if you wish to have the five internal AT91RM9200 UARTs
305 appear as /dev/ttyAT0-4 (major 240, minor 0-4) instead of the
306 normal /dev/ttyS0-4 (major 4, minor 64-68). This is necessary if
307 you also want other UARTs, such as external 8250/16C550 compatible
308 UARTs.
309 The ttySn nodes are legally reserved for the 8250 serial driver
310 but are often misused by other serial drivers.
311
312 To use this, you should create suitable ttyATn device nodes in
313 /dev/, and pass "console=ttyATn" to the kernel.
314
315 Say Y if you have an external 8250/16C550 UART. If unsure, say N.
316
283config SERIAL_CLPS711X 317config SERIAL_CLPS711X
284 tristate "CLPS711X serial port support" 318 tristate "CLPS711X serial port support"
285 depends on ARM && ARCH_CLPS711X 319 depends on ARM && ARCH_CLPS711X
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 137148bba4fa..24a583e482bb 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -56,3 +56,4 @@ obj-$(CONFIG_SERIAL_JSM) += jsm/
56obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o 56obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
57obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o 57obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
58obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o 58obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o
59obj-$(CONFIG_SERIAL_AT91) += at91_serial.o
diff --git a/drivers/serial/at91_serial.c b/drivers/serial/at91_serial.c
new file mode 100644
index 000000000000..0e206063d685
--- /dev/null
+++ b/drivers/serial/at91_serial.c
@@ -0,0 +1,894 @@
1/*
2 * linux/drivers/char/at91_serial.c
3 *
4 * Driver for Atmel AT91RM9200 Serial ports
5 *
6 * Copyright (C) 2003 Rick Bronson
7 *
8 * Based on drivers/char/serial_sa1100.c, by Deep Blue Solutions Ltd.
9 * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26#include <linux/config.h>
27#include <linux/module.h>
28#include <linux/tty.h>
29#include <linux/ioport.h>
30#include <linux/slab.h>
31#include <linux/init.h>
32#include <linux/serial.h>
33#include <linux/console.h>
34#include <linux/sysrq.h>
35#include <linux/tty_flip.h>
36
37#include <asm/io.h>
38
39#include <asm/arch/at91rm9200_usart.h>
40#include <asm/mach/serial_at91rm9200.h>
41#include <asm/arch/board.h>
42#include <asm/arch/pio.h>
43
44
45#if defined(CONFIG_SERIAL_AT91_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
46#define SUPPORT_SYSRQ
47#endif
48
49#include <linux/serial_core.h>
50
51#ifdef CONFIG_SERIAL_AT91_TTYAT
52
53/* Use device name ttyAT, major 204 and minor 154-169. This is necessary if we
54 * should coexist with the 8250 driver, such as if we have an external 16C550
55 * UART. */
56#define SERIAL_AT91_MAJOR 204
57#define MINOR_START 154
58#define AT91_DEVICENAME "ttyAT"
59
60#else
61
62/* Use device name ttyS, major 4, minor 64-68. This is the usual serial port
63 * name, but it is legally reserved for the 8250 driver. */
64#define SERIAL_AT91_MAJOR TTY_MAJOR
65#define MINOR_START 64
66#define AT91_DEVICENAME "ttyS"
67
68#endif
69
70#define AT91_VA_BASE_DBGU ((unsigned long) AT91_VA_BASE_SYS + AT91_DBGU)
71#define AT91_ISR_PASS_LIMIT 256
72
73#define UART_PUT_CR(port,v) writel(v, (port)->membase + AT91_US_CR)
74#define UART_GET_MR(port) readl((port)->membase + AT91_US_MR)
75#define UART_PUT_MR(port,v) writel(v, (port)->membase + AT91_US_MR)
76#define UART_PUT_IER(port,v) writel(v, (port)->membase + AT91_US_IER)
77#define UART_PUT_IDR(port,v) writel(v, (port)->membase + AT91_US_IDR)
78#define UART_GET_IMR(port) readl((port)->membase + AT91_US_IMR)
79#define UART_GET_CSR(port) readl((port)->membase + AT91_US_CSR)
80#define UART_GET_CHAR(port) readl((port)->membase + AT91_US_RHR)
81#define UART_PUT_CHAR(port,v) writel(v, (port)->membase + AT91_US_THR)
82#define UART_GET_BRGR(port) readl((port)->membase + AT91_US_BRGR)
83#define UART_PUT_BRGR(port,v) writel(v, (port)->membase + AT91_US_BRGR)
84#define UART_PUT_RTOR(port,v) writel(v, (port)->membase + AT91_US_RTOR)
85
86// #define UART_GET_CR(port) readl((port)->membase + AT91_US_CR) // is write-only
87
88 /* PDC registers */
89#define UART_PUT_PTCR(port,v) writel(v, (port)->membase + AT91_PDC_PTCR)
90#define UART_PUT_RPR(port,v) writel(v, (port)->membase + AT91_PDC_RPR)
91#define UART_PUT_RCR(port,v) writel(v, (port)->membase + AT91_PDC_RCR)
92#define UART_GET_RCR(port) readl((port)->membase + AT91_PDC_RCR)
93#define UART_PUT_RNPR(port,v) writel(v, (port)->membase + AT91_PDC_RNPR)
94#define UART_PUT_RNCR(port,v) writel(v, (port)->membase + AT91_PDC_RNCR)
95
96
97static int (*at91_open)(struct uart_port *);
98static void (*at91_close)(struct uart_port *);
99
100#ifdef SUPPORT_SYSRQ
101static struct console at91_console;
102#endif
103
104/*
105 * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty.
106 */
107static u_int at91_tx_empty(struct uart_port *port)
108{
109 return (UART_GET_CSR(port) & AT91_US_TXEMPTY) ? TIOCSER_TEMT : 0;
110}
111
112/*
113 * Set state of the modem control output lines
114 */
115static void at91_set_mctrl(struct uart_port *port, u_int mctrl)
116{
117 unsigned int control = 0;
118
119 /*
120 * Errata #39: RTS0 is not internally connected to PA21. We need to drive
121 * the pin manually.
122 */
123 if (port->mapbase == AT91_VA_BASE_US0) {
124 if (mctrl & TIOCM_RTS)
125 at91_sys_write(AT91_PIOA + PIO_CODR, AT91_PA21_RTS0);
126 else
127 at91_sys_write(AT91_PIOA + PIO_SODR, AT91_PA21_RTS0);
128 }
129
130 if (mctrl & TIOCM_RTS)
131 control |= AT91_US_RTSEN;
132 else
133 control |= AT91_US_RTSDIS;
134
135 if (mctrl & TIOCM_DTR)
136 control |= AT91_US_DTREN;
137 else
138 control |= AT91_US_DTRDIS;
139
140 UART_PUT_CR(port,control);
141}
142
143/*
144 * Get state of the modem control input lines
145 */
146static u_int at91_get_mctrl(struct uart_port *port)
147{
148 unsigned int status, ret = 0;
149
150 status = UART_GET_CSR(port);
151
152 /*
153 * The control signals are active low.
154 */
155 if (!(status & AT91_US_DCD))
156 ret |= TIOCM_CD;
157 if (!(status & AT91_US_CTS))
158 ret |= TIOCM_CTS;
159 if (!(status & AT91_US_DSR))
160 ret |= TIOCM_DSR;
161 if (!(status & AT91_US_RI))
162 ret |= TIOCM_RI;
163
164 return ret;
165}
166
167/*
168 * Stop transmitting.
169 */
170static void at91_stop_tx(struct uart_port *port)
171{
172 UART_PUT_IDR(port, AT91_US_TXRDY);
173 port->read_status_mask &= ~AT91_US_TXRDY;
174}
175
176/*
177 * Start transmitting.
178 */
179static void at91_start_tx(struct uart_port *port)
180{
181 port->read_status_mask |= AT91_US_TXRDY;
182 UART_PUT_IER(port, AT91_US_TXRDY);
183}
184
185/*
186 * Stop receiving - port is in process of being closed.
187 */
188static void at91_stop_rx(struct uart_port *port)
189{
190 UART_PUT_IDR(port, AT91_US_RXRDY);
191}
192
193/*
194 * Enable modem status interrupts
195 */
196static void at91_enable_ms(struct uart_port *port)
197{
198 port->read_status_mask |= (AT91_US_RIIC | AT91_US_DSRIC | AT91_US_DCDIC | AT91_US_CTSIC);
199 UART_PUT_IER(port, AT91_US_RIIC | AT91_US_DSRIC | AT91_US_DCDIC | AT91_US_CTSIC);
200}
201
202/*
203 * Control the transmission of a break signal
204 */
205static void at91_break_ctl(struct uart_port *port, int break_state)
206{
207 if (break_state != 0)
208 UART_PUT_CR(port, AT91_US_STTBRK); /* start break */
209 else
210 UART_PUT_CR(port, AT91_US_STPBRK); /* stop break */
211}
212
213/*
214 * Characters received (called from interrupt handler)
215 */
216static void at91_rx_chars(struct uart_port *port, struct pt_regs *regs)
217{
218 struct tty_struct *tty = port->info->tty;
219 unsigned int status, ch, flg;
220
221 status = UART_GET_CSR(port) & port->read_status_mask;
222 while (status & (AT91_US_RXRDY)) {
223 ch = UART_GET_CHAR(port);
224
225 if (tty->flip.count >= TTY_FLIPBUF_SIZE)
226 goto ignore_char;
227 port->icount.rx++;
228
229 flg = TTY_NORMAL;
230
231 /*
232 * note that the error handling code is
233 * out of the main execution path
234 */
235 if (unlikely(status & (AT91_US_PARE | AT91_US_FRAME | AT91_US_OVRE))) {
236 UART_PUT_CR(port, AT91_US_RSTSTA); /* clear error */
237 if (status & (AT91_US_PARE))
238 port->icount.parity++;
239 if (status & (AT91_US_FRAME))
240 port->icount.frame++;
241 if (status & (AT91_US_OVRE))
242 port->icount.overrun++;
243
244 if (status & AT91_US_PARE)
245 flg = TTY_PARITY;
246 else if (status & AT91_US_FRAME)
247 flg = TTY_FRAME;
248 if (status & AT91_US_OVRE) {
249 /*
250 * overrun does *not* affect the character
251 * we read from the FIFO
252 */
253 tty_insert_flip_char(tty, ch, flg);
254 ch = 0;
255 flg = TTY_OVERRUN;
256 }
257#ifdef SUPPORT_SYSRQ
258 port->sysrq = 0;
259#endif
260 }
261
262 if (uart_handle_sysrq_char(port, ch, regs))
263 goto ignore_char;
264
265 tty_insert_flip_char(tty, ch, flg);
266
267 ignore_char:
268 status = UART_GET_CSR(port) & port->read_status_mask;
269 }
270
271 tty_flip_buffer_push(tty);
272}
273
274/*
275 * Transmit characters (called from interrupt handler)
276 */
277static void at91_tx_chars(struct uart_port *port)
278{
279 struct circ_buf *xmit = &port->info->xmit;
280
281 if (port->x_char) {
282 UART_PUT_CHAR(port, port->x_char);
283 port->icount.tx++;
284 port->x_char = 0;
285 return;
286 }
287 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
288 at91_stop_tx(port);
289 return;
290 }
291
292 while (UART_GET_CSR(port) & AT91_US_TXRDY) {
293 UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
294 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
295 port->icount.tx++;
296 if (uart_circ_empty(xmit))
297 break;
298 }
299
300 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
301 uart_write_wakeup(port);
302
303 if (uart_circ_empty(xmit))
304 at91_stop_tx(port);
305}
306
307/*
308 * Interrupt handler
309 */
310static irqreturn_t at91_interrupt(int irq, void *dev_id, struct pt_regs *regs)
311{
312 struct uart_port *port = dev_id;
313 unsigned int status, pending, pass_counter = 0;
314
315 status = UART_GET_CSR(port);
316 pending = status & port->read_status_mask;
317 if (pending) {
318 do {
319 if (pending & AT91_US_RXRDY)
320 at91_rx_chars(port, regs);
321
322 /* Clear the relevent break bits */
323 if (pending & AT91_US_RXBRK) {
324 UART_PUT_CR(port, AT91_US_RSTSTA);
325 port->icount.brk++;
326 uart_handle_break(port);
327 }
328
329 // TODO: All reads to CSR will clear these interrupts!
330 if (pending & AT91_US_RIIC) port->icount.rng++;
331 if (pending & AT91_US_DSRIC) port->icount.dsr++;
332 if (pending & AT91_US_DCDIC)
333 uart_handle_dcd_change(port, !(status & AT91_US_DCD));
334 if (pending & AT91_US_CTSIC)
335 uart_handle_cts_change(port, !(status & AT91_US_CTS));
336 if (pending & (AT91_US_RIIC | AT91_US_DSRIC | AT91_US_DCDIC | AT91_US_CTSIC))
337 wake_up_interruptible(&port->info->delta_msr_wait);
338
339 if (pending & AT91_US_TXRDY)
340 at91_tx_chars(port);
341 if (pass_counter++ > AT91_ISR_PASS_LIMIT)
342 break;
343
344 status = UART_GET_CSR(port);
345 pending = status & port->read_status_mask;
346 } while (pending);
347 }
348 return IRQ_HANDLED;
349}
350
351/*
352 * Perform initialization and enable port for reception
353 */
354static int at91_startup(struct uart_port *port)
355{
356 int retval;
357
358 /*
359 * Ensure that no interrupts are enabled otherwise when
360 * request_irq() is called we could get stuck trying to
361 * handle an unexpected interrupt
362 */
363 UART_PUT_IDR(port, -1);
364
365 /*
366 * Allocate the IRQ
367 */
368 retval = request_irq(port->irq, at91_interrupt, SA_SHIRQ, "at91_serial", port);
369 if (retval) {
370 printk("at91_serial: at91_startup - Can't get irq\n");
371 return retval;
372 }
373
374 /*
375 * If there is a specific "open" function (to register
376 * control line interrupts)
377 */
378 if (at91_open) {
379 retval = at91_open(port);
380 if (retval) {
381 free_irq(port->irq, port);
382 return retval;
383 }
384 }
385
386 port->read_status_mask = AT91_US_RXRDY | AT91_US_TXRDY | AT91_US_OVRE
387 | AT91_US_FRAME | AT91_US_PARE | AT91_US_RXBRK;
388 /*
389 * Finally, enable the serial port
390 */
391 UART_PUT_CR(port, AT91_US_RSTSTA | AT91_US_RSTRX);
392 UART_PUT_CR(port, AT91_US_TXEN | AT91_US_RXEN); /* enable xmit & rcvr */
393 UART_PUT_IER(port, AT91_US_RXRDY); /* do receive only */
394 return 0;
395}
396
397/*
398 * Disable the port
399 */
400static void at91_shutdown(struct uart_port *port)
401{
402 /*
403 * Disable all interrupts, port and break condition.
404 */
405 UART_PUT_CR(port, AT91_US_RSTSTA);
406 UART_PUT_IDR(port, -1);
407
408 /*
409 * Free the interrupt
410 */
411 free_irq(port->irq, port);
412
413 /*
414 * If there is a specific "close" function (to unregister
415 * control line interrupts)
416 */
417 if (at91_close)
418 at91_close(port);
419}
420
421/*
422 * Power / Clock management.
423 */
424static void at91_serial_pm(struct uart_port *port, unsigned int state, unsigned int oldstate)
425{
426 switch (state) {
427 case 0:
428 /*
429 * Enable the peripheral clock for this serial port.
430 * This is called on uart_open() or a resume event.
431 */
432 at91_sys_write(AT91_PMC_PCER, 1 << port->irq);
433 break;
434 case 3:
435 /*
436 * Disable the peripheral clock for this serial port.
437 * This is called on uart_close() or a suspend event.
438 */
439 if (port->irq != AT91_ID_SYS) /* is this a shared clock? */
440 at91_sys_write(AT91_PMC_PCDR, 1 << port->irq);
441 break;
442 default:
443 printk(KERN_ERR "at91_serial: unknown pm %d\n", state);
444 }
445}
446
447/*
448 * Change the port parameters
449 */
450static void at91_set_termios(struct uart_port *port, struct termios * termios, struct termios * old)
451{
452 unsigned long flags;
453 unsigned int mode, imr, quot, baud;
454
455 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
456 quot = uart_get_divisor(port, baud);
457
458 /* Get current mode register */
459 mode = UART_GET_MR(port) & ~(AT91_US_CHRL | AT91_US_NBSTOP | AT91_US_PAR);
460
461 /* byte size */
462 switch (termios->c_cflag & CSIZE) {
463 case CS5:
464 mode |= AT91_US_CHRL_5;
465 break;
466 case CS6:
467 mode |= AT91_US_CHRL_6;
468 break;
469 case CS7:
470 mode |= AT91_US_CHRL_7;
471 break;
472 default:
473 mode |= AT91_US_CHRL_8;
474 break;
475 }
476
477 /* stop bits */
478 if (termios->c_cflag & CSTOPB)
479 mode |= AT91_US_NBSTOP_2;
480
481 /* parity */
482 if (termios->c_cflag & PARENB) {
483 if (termios->c_cflag & CMSPAR) { /* Mark or Space parity */
484 if (termios->c_cflag & PARODD)
485 mode |= AT91_US_PAR_MARK;
486 else
487 mode |= AT91_US_PAR_SPACE;
488 }
489 else if (termios->c_cflag & PARODD)
490 mode |= AT91_US_PAR_ODD;
491 else
492 mode |= AT91_US_PAR_EVEN;
493 }
494 else
495 mode |= AT91_US_PAR_NONE;
496
497 spin_lock_irqsave(&port->lock, flags);
498
499 port->read_status_mask |= AT91_US_OVRE;
500 if (termios->c_iflag & INPCK)
501 port->read_status_mask |= AT91_US_FRAME | AT91_US_PARE;
502 if (termios->c_iflag & (BRKINT | PARMRK))
503 port->read_status_mask |= AT91_US_RXBRK;
504
505 /*
506 * Characters to ignore
507 */
508 port->ignore_status_mask = 0;
509 if (termios->c_iflag & IGNPAR)
510 port->ignore_status_mask |= (AT91_US_FRAME | AT91_US_PARE);
511 if (termios->c_iflag & IGNBRK) {
512 port->ignore_status_mask |= AT91_US_RXBRK;
513 /*
514 * If we're ignoring parity and break indicators,
515 * ignore overruns too (for real raw support).
516 */
517 if (termios->c_iflag & IGNPAR)
518 port->ignore_status_mask |= AT91_US_OVRE;
519 }
520
521 // TODO: Ignore all characters if CREAD is set.
522
523 /* update the per-port timeout */
524 uart_update_timeout(port, termios->c_cflag, baud);
525
526 /* disable interrupts and drain transmitter */
527 imr = UART_GET_IMR(port); /* get interrupt mask */
528 UART_PUT_IDR(port, -1); /* disable all interrupts */
529 while (!(UART_GET_CSR(port) & AT91_US_TXEMPTY)) { barrier(); }
530
531 /* disable receiver and transmitter */
532 UART_PUT_CR(port, AT91_US_TXDIS | AT91_US_RXDIS);
533
534 /* set the parity, stop bits and data size */
535 UART_PUT_MR(port, mode);
536
537 /* set the baud rate */
538 UART_PUT_BRGR(port, quot);
539 UART_PUT_CR(port, AT91_US_RSTSTA | AT91_US_RSTRX);
540 UART_PUT_CR(port, AT91_US_TXEN | AT91_US_RXEN);
541
542 /* restore interrupts */
543 UART_PUT_IER(port, imr);
544
545 /* CTS flow-control and modem-status interrupts */
546 if (UART_ENABLE_MS(port, termios->c_cflag))
547 port->ops->enable_ms(port);
548
549 spin_unlock_irqrestore(&port->lock, flags);
550}
551
552/*
553 * Return string describing the specified port
554 */
555static const char *at91_type(struct uart_port *port)
556{
557 return (port->type == PORT_AT91RM9200) ? "AT91_SERIAL" : NULL;
558}
559
560/*
561 * Release the memory region(s) being used by 'port'.
562 */
563static void at91_release_port(struct uart_port *port)
564{
565 release_mem_region(port->mapbase,
566 (port->mapbase == AT91_VA_BASE_DBGU) ? 512 : SZ_16K);
567}
568
569/*
570 * Request the memory region(s) being used by 'port'.
571 */
572static int at91_request_port(struct uart_port *port)
573{
574 return request_mem_region(port->mapbase,
575 (port->mapbase == AT91_VA_BASE_DBGU) ? 512 : SZ_16K,
576 "at91_serial") != NULL ? 0 : -EBUSY;
577
578}
579
580/*
581 * Configure/autoconfigure the port.
582 */
583static void at91_config_port(struct uart_port *port, int flags)
584{
585 if (flags & UART_CONFIG_TYPE) {
586 port->type = PORT_AT91RM9200;
587 at91_request_port(port);
588 }
589}
590
591/*
592 * Verify the new serial_struct (for TIOCSSERIAL).
593 */
594static int at91_verify_port(struct uart_port *port, struct serial_struct *ser)
595{
596 int ret = 0;
597 if (ser->type != PORT_UNKNOWN && ser->type != PORT_AT91RM9200)
598 ret = -EINVAL;
599 if (port->irq != ser->irq)
600 ret = -EINVAL;
601 if (ser->io_type != SERIAL_IO_MEM)
602 ret = -EINVAL;
603 if (port->uartclk / 16 != ser->baud_base)
604 ret = -EINVAL;
605 if ((void *)port->mapbase != ser->iomem_base)
606 ret = -EINVAL;
607 if (port->iobase != ser->port)
608 ret = -EINVAL;
609 if (ser->hub6 != 0)
610 ret = -EINVAL;
611 return ret;
612}
613
614static struct uart_ops at91_pops = {
615 .tx_empty = at91_tx_empty,
616 .set_mctrl = at91_set_mctrl,
617 .get_mctrl = at91_get_mctrl,
618 .stop_tx = at91_stop_tx,
619 .start_tx = at91_start_tx,
620 .stop_rx = at91_stop_rx,
621 .enable_ms = at91_enable_ms,
622 .break_ctl = at91_break_ctl,
623 .startup = at91_startup,
624 .shutdown = at91_shutdown,
625 .set_termios = at91_set_termios,
626 .type = at91_type,
627 .release_port = at91_release_port,
628 .request_port = at91_request_port,
629 .config_port = at91_config_port,
630 .verify_port = at91_verify_port,
631 .pm = at91_serial_pm,
632};
633
634static struct uart_port at91_ports[AT91_NR_UART];
635
636void __init at91_init_ports(void)
637{
638 static int first = 1;
639 int i;
640
641 if (!first)
642 return;
643 first = 0;
644
645 for (i = 0; i < AT91_NR_UART; i++) {
646 at91_ports[i].iotype = UPIO_MEM;
647 at91_ports[i].flags = UPF_BOOT_AUTOCONF;
648 at91_ports[i].uartclk = at91_master_clock;
649 at91_ports[i].ops = &at91_pops;
650 at91_ports[i].fifosize = 1;
651 at91_ports[i].line = i;
652 }
653}
654
655void __init at91_register_uart_fns(struct at91rm9200_port_fns *fns)
656{
657 if (fns->enable_ms)
658 at91_pops.enable_ms = fns->enable_ms;
659 if (fns->get_mctrl)
660 at91_pops.get_mctrl = fns->get_mctrl;
661 if (fns->set_mctrl)
662 at91_pops.set_mctrl = fns->set_mctrl;
663 at91_open = fns->open;
664 at91_close = fns->close;
665 at91_pops.pm = fns->pm;
666 at91_pops.set_wake = fns->set_wake;
667}
668
669/*
670 * Setup ports.
671 */
672void __init at91_register_uart(int idx, int port)
673{
674 if ((idx < 0) || (idx >= AT91_NR_UART)) {
675 printk(KERN_ERR "%s: bad index number %d\n", __FUNCTION__, idx);
676 return;
677 }
678
679 switch (port) {
680 case 0:
681 at91_ports[idx].membase = (void __iomem *) AT91_VA_BASE_US0;
682 at91_ports[idx].mapbase = AT91_VA_BASE_US0;
683 at91_ports[idx].irq = AT91_ID_US0;
684 AT91_CfgPIO_USART0();
685 break;
686 case 1:
687 at91_ports[idx].membase = (void __iomem *) AT91_VA_BASE_US1;
688 at91_ports[idx].mapbase = AT91_VA_BASE_US1;
689 at91_ports[idx].irq = AT91_ID_US1;
690 AT91_CfgPIO_USART1();
691 break;
692 case 2:
693 at91_ports[idx].membase = (void __iomem *) AT91_VA_BASE_US2;
694 at91_ports[idx].mapbase = AT91_VA_BASE_US2;
695 at91_ports[idx].irq = AT91_ID_US2;
696 AT91_CfgPIO_USART2();
697 break;
698 case 3:
699 at91_ports[idx].membase = (void __iomem *) AT91_VA_BASE_US3;
700 at91_ports[idx].mapbase = AT91_VA_BASE_US3;
701 at91_ports[idx].irq = AT91_ID_US3;
702 AT91_CfgPIO_USART3();
703 break;
704 case 4:
705 at91_ports[idx].membase = (void __iomem *) AT91_VA_BASE_DBGU;
706 at91_ports[idx].mapbase = AT91_VA_BASE_DBGU;
707 at91_ports[idx].irq = AT91_ID_SYS;
708 AT91_CfgPIO_DBGU();
709 break;
710 default:
711 printk(KERN_ERR "%s : bad port number %d\n", __FUNCTION__, port);
712 }
713}
714
715#ifdef CONFIG_SERIAL_AT91_CONSOLE
716
717/*
718 * Interrupts are disabled on entering
719 */
720static void at91_console_write(struct console *co, const char *s, u_int count)
721{
722 struct uart_port *port = at91_ports + co->index;
723 unsigned int status, i, imr;
724
725 /*
726 * First, save IMR and then disable interrupts
727 */
728 imr = UART_GET_IMR(port); /* get interrupt mask */
729 UART_PUT_IDR(port, AT91_US_RXRDY | AT91_US_TXRDY);
730
731 /*
732 * Now, do each character
733 */
734 for (i = 0; i < count; i++) {
735 do {
736 status = UART_GET_CSR(port);
737 } while (!(status & AT91_US_TXRDY));
738 UART_PUT_CHAR(port, s[i]);
739 if (s[i] == '\n') {
740 do {
741 status = UART_GET_CSR(port);
742 } while (!(status & AT91_US_TXRDY));
743 UART_PUT_CHAR(port, '\r');
744 }
745 }
746
747 /*
748 * Finally, wait for transmitter to become empty
749 * and restore IMR
750 */
751 do {
752 status = UART_GET_CSR(port);
753 } while (!(status & AT91_US_TXRDY));
754 UART_PUT_IER(port, imr); /* set interrupts back the way they were */
755}
756
757/*
758 * If the port was already initialised (eg, by a boot loader), try to determine
759 * the current setup.
760 */
761static void __init at91_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
762{
763 unsigned int mr, quot;
764
765// TODO: CR is a write-only register
766// unsigned int cr;
767//
768// cr = UART_GET_CR(port) & (AT91_US_RXEN | AT91_US_TXEN);
769// if (cr == (AT91_US_RXEN | AT91_US_TXEN)) {
770// /* ok, the port was enabled */
771// }
772
773 mr = UART_GET_MR(port) & AT91_US_CHRL;
774 if (mr == AT91_US_CHRL_8)
775 *bits = 8;
776 else
777 *bits = 7;
778
779 mr = UART_GET_MR(port) & AT91_US_PAR;
780 if (mr == AT91_US_PAR_EVEN)
781 *parity = 'e';
782 else if (mr == AT91_US_PAR_ODD)
783 *parity = 'o';
784
785 quot = UART_GET_BRGR(port);
786 *baud = port->uartclk / (16 * (quot));
787}
788
789static int __init at91_console_setup(struct console *co, char *options)
790{
791 struct uart_port *port;
792 int baud = 115200;
793 int bits = 8;
794 int parity = 'n';
795 int flow = 'n';
796
797 /*
798 * Check whether an invalid uart number has been specified, and
799 * if so, search for the first available port that does have
800 * console support.
801 */
802 port = uart_get_console(at91_ports, AT91_NR_UART, co);
803
804 /*
805 * Enable the serial console, in-case bootloader did not do it.
806 */
807 at91_sys_write(AT91_PMC_PCER, 1 << port->irq); /* enable clock */
808 UART_PUT_IDR(port, -1); /* disable interrupts */
809 UART_PUT_CR(port, AT91_US_RSTSTA | AT91_US_RSTRX);
810 UART_PUT_CR(port, AT91_US_TXEN | AT91_US_RXEN);
811
812 if (options)
813 uart_parse_options(options, &baud, &parity, &bits, &flow);
814 else
815 at91_console_get_options(port, &baud, &parity, &bits);
816
817 return uart_set_options(port, co, baud, parity, bits, flow);
818}
819
820static struct uart_driver at91_uart;
821
822static struct console at91_console = {
823 .name = AT91_DEVICENAME,
824 .write = at91_console_write,
825 .device = uart_console_device,
826 .setup = at91_console_setup,
827 .flags = CON_PRINTBUFFER,
828 .index = -1,
829 .data = &at91_uart,
830};
831
832#define AT91_CONSOLE_DEVICE &at91_console
833
834static int __init at91_console_init(void)
835{
836 at91_init_ports();
837
838 at91_console.index = at91_console_port;
839 register_console(&at91_console);
840 return 0;
841}
842console_initcall(at91_console_init);
843
844#else
845#define AT91_CONSOLE_DEVICE NULL
846#endif
847
848static struct uart_driver at91_uart = {
849 .owner = THIS_MODULE,
850 .driver_name = AT91_DEVICENAME,
851 .dev_name = AT91_DEVICENAME,
852 .devfs_name = AT91_DEVICENAME,
853 .major = SERIAL_AT91_MAJOR,
854 .minor = MINOR_START,
855 .nr = AT91_NR_UART,
856 .cons = AT91_CONSOLE_DEVICE,
857};
858
859static int __init at91_serial_init(void)
860{
861 int ret, i;
862
863 at91_init_ports();
864
865 ret = uart_register_driver(&at91_uart);
866 if (ret)
867 return ret;
868
869 for (i = 0; i < AT91_NR_UART; i++) {
870 if (at91_serial_map[i] >= 0)
871 uart_add_one_port(&at91_uart, &at91_ports[i]);
872 }
873
874 return 0;
875}
876
877static void __exit at91_serial_exit(void)
878{
879 int i;
880
881 for (i = 0; i < AT91_NR_UART; i++) {
882 if (at91_serial_map[i] >= 0)
883 uart_remove_one_port(&at91_uart, &at91_ports[i]);
884 }
885
886 uart_unregister_driver(&at91_uart);
887}
888
889module_init(at91_serial_init);
890module_exit(at91_serial_exit);
891
892MODULE_AUTHOR("Rick Bronson");
893MODULE_DESCRIPTION("AT91 generic serial port driver");
894MODULE_LICENSE("GPL");
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 08c42c000188..be12623d8544 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -442,6 +442,7 @@ static char *serial_version = "$Revision: 1.25 $";
442#include <linux/init.h> 442#include <linux/init.h>
443#include <asm/uaccess.h> 443#include <asm/uaccess.h>
444#include <linux/kernel.h> 444#include <linux/kernel.h>
445#include <linux/mutex.h>
445 446
446#include <asm/io.h> 447#include <asm/io.h>
447#include <asm/irq.h> 448#include <asm/irq.h>
@@ -1315,11 +1316,7 @@ static const struct control_pins e100_modem_pins[NR_PORTS] =
1315 * memory if large numbers of serial ports are open. 1316 * memory if large numbers of serial ports are open.
1316 */ 1317 */
1317static unsigned char *tmp_buf; 1318static unsigned char *tmp_buf;
1318#ifdef DECLARE_MUTEX 1319static DEFINE_MUTEX(tmp_buf_mutex);
1319static DECLARE_MUTEX(tmp_buf_sem);
1320#else
1321static struct semaphore tmp_buf_sem = MUTEX;
1322#endif
1323 1320
1324/* Calculate the chartime depending on baudrate, numbor of bits etc. */ 1321/* Calculate the chartime depending on baudrate, numbor of bits etc. */
1325static void update_char_time(struct e100_serial * info) 1322static void update_char_time(struct e100_serial * info)
@@ -3661,7 +3658,7 @@ rs_raw_write(struct tty_struct * tty, int from_user,
3661 * design. 3658 * design.
3662 */ 3659 */
3663 if (from_user) { 3660 if (from_user) {
3664 down(&tmp_buf_sem); 3661 mutex_lock(&tmp_buf_mutex);
3665 while (1) { 3662 while (1) {
3666 int c1; 3663 int c1;
3667 c = CIRC_SPACE_TO_END(info->xmit.head, 3664 c = CIRC_SPACE_TO_END(info->xmit.head,
@@ -3692,7 +3689,7 @@ rs_raw_write(struct tty_struct * tty, int from_user,
3692 count -= c; 3689 count -= c;
3693 ret += c; 3690 ret += c;
3694 } 3691 }
3695 up(&tmp_buf_sem); 3692 mutex_unlock(&tmp_buf_mutex);
3696 } else { 3693 } else {
3697 cli(); 3694 cli();
3698 while (count) { 3695 while (count) {
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index f330d6c0e0df..5f52883e64d2 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -60,6 +60,7 @@
60#include <linux/pmu.h> 60#include <linux/pmu.h>
61#include <linux/bitops.h> 61#include <linux/bitops.h>
62#include <linux/sysrq.h> 62#include <linux/sysrq.h>
63#include <linux/mutex.h>
63#include <asm/sections.h> 64#include <asm/sections.h>
64#include <asm/io.h> 65#include <asm/io.h>
65#include <asm/irq.h> 66#include <asm/irq.h>
@@ -96,7 +97,7 @@ MODULE_LICENSE("GPL");
96 */ 97 */
97static struct uart_pmac_port pmz_ports[MAX_ZS_PORTS]; 98static struct uart_pmac_port pmz_ports[MAX_ZS_PORTS];
98static int pmz_ports_count; 99static int pmz_ports_count;
99static DECLARE_MUTEX(pmz_irq_sem); 100static DEFINE_MUTEX(pmz_irq_mutex);
100 101
101static struct uart_driver pmz_uart_reg = { 102static struct uart_driver pmz_uart_reg = {
102 .owner = THIS_MODULE, 103 .owner = THIS_MODULE,
@@ -922,7 +923,7 @@ static int pmz_startup(struct uart_port *port)
922 if (uap->node == NULL) 923 if (uap->node == NULL)
923 return -ENODEV; 924 return -ENODEV;
924 925
925 down(&pmz_irq_sem); 926 mutex_lock(&pmz_irq_mutex);
926 927
927 uap->flags |= PMACZILOG_FLAG_IS_OPEN; 928 uap->flags |= PMACZILOG_FLAG_IS_OPEN;
928 929
@@ -940,11 +941,11 @@ static int pmz_startup(struct uart_port *port)
940 dev_err(&uap->dev->ofdev.dev, 941 dev_err(&uap->dev->ofdev.dev,
941 "Unable to register zs interrupt handler.\n"); 942 "Unable to register zs interrupt handler.\n");
942 pmz_set_scc_power(uap, 0); 943 pmz_set_scc_power(uap, 0);
943 up(&pmz_irq_sem); 944 mutex_unlock(&pmz_irq_mutex);
944 return -ENXIO; 945 return -ENXIO;
945 } 946 }
946 947
947 up(&pmz_irq_sem); 948 mutex_unlock(&pmz_irq_mutex);
948 949
949 /* Right now, we deal with delay by blocking here, I'll be 950 /* Right now, we deal with delay by blocking here, I'll be
950 * smarter later on 951 * smarter later on
@@ -981,7 +982,7 @@ static void pmz_shutdown(struct uart_port *port)
981 if (uap->node == NULL) 982 if (uap->node == NULL)
982 return; 983 return;
983 984
984 down(&pmz_irq_sem); 985 mutex_lock(&pmz_irq_mutex);
985 986
986 /* Release interrupt handler */ 987 /* Release interrupt handler */
987 free_irq(uap->port.irq, uap); 988 free_irq(uap->port.irq, uap);
@@ -1002,7 +1003,7 @@ static void pmz_shutdown(struct uart_port *port)
1002 1003
1003 if (ZS_IS_CONS(uap) || ZS_IS_ASLEEP(uap)) { 1004 if (ZS_IS_CONS(uap) || ZS_IS_ASLEEP(uap)) {
1004 spin_unlock_irqrestore(&port->lock, flags); 1005 spin_unlock_irqrestore(&port->lock, flags);
1005 up(&pmz_irq_sem); 1006 mutex_unlock(&pmz_irq_mutex);
1006 return; 1007 return;
1007 } 1008 }
1008 1009
@@ -1019,7 +1020,7 @@ static void pmz_shutdown(struct uart_port *port)
1019 1020
1020 spin_unlock_irqrestore(&port->lock, flags); 1021 spin_unlock_irqrestore(&port->lock, flags);
1021 1022
1022 up(&pmz_irq_sem); 1023 mutex_unlock(&pmz_irq_mutex);
1023 1024
1024 pmz_debug("pmz: shutdown() done.\n"); 1025 pmz_debug("pmz: shutdown() done.\n");
1025} 1026}
@@ -1591,7 +1592,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
1591 1592
1592 state = pmz_uart_reg.state + uap->port.line; 1593 state = pmz_uart_reg.state + uap->port.line;
1593 1594
1594 down(&pmz_irq_sem); 1595 mutex_lock(&pmz_irq_mutex);
1595 down(&state->sem); 1596 down(&state->sem);
1596 1597
1597 spin_lock_irqsave(&uap->port.lock, flags); 1598 spin_lock_irqsave(&uap->port.lock, flags);
@@ -1624,7 +1625,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
1624 pmz_set_scc_power(uap, 0); 1625 pmz_set_scc_power(uap, 0);
1625 1626
1626 up(&state->sem); 1627 up(&state->sem);
1627 up(&pmz_irq_sem); 1628 mutex_unlock(&pmz_irq_mutex);
1628 1629
1629 pmz_debug("suspend, switching complete\n"); 1630 pmz_debug("suspend, switching complete\n");
1630 1631
@@ -1651,7 +1652,7 @@ static int pmz_resume(struct macio_dev *mdev)
1651 1652
1652 state = pmz_uart_reg.state + uap->port.line; 1653 state = pmz_uart_reg.state + uap->port.line;
1653 1654
1654 down(&pmz_irq_sem); 1655 mutex_lock(&pmz_irq_mutex);
1655 down(&state->sem); 1656 down(&state->sem);
1656 1657
1657 spin_lock_irqsave(&uap->port.lock, flags); 1658 spin_lock_irqsave(&uap->port.lock, flags);
@@ -1685,7 +1686,7 @@ static int pmz_resume(struct macio_dev *mdev)
1685 1686
1686 bail: 1687 bail:
1687 up(&state->sem); 1688 up(&state->sem);
1688 up(&pmz_irq_sem); 1689 mutex_unlock(&pmz_irq_mutex);
1689 1690
1690 /* Right now, we deal with delay by blocking here, I'll be 1691 /* Right now, we deal with delay by blocking here, I'll be
1691 * smarter later on 1692 * smarter later on
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 9589509fc5bd..2ca620900bcc 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -33,6 +33,7 @@
33#include <linux/device.h> 33#include <linux/device.h>
34#include <linux/serial.h> /* for serial_state and serial_icounter_struct */ 34#include <linux/serial.h> /* for serial_state and serial_icounter_struct */
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/mutex.h>
36 37
37#include <asm/irq.h> 38#include <asm/irq.h>
38#include <asm/uaccess.h> 39#include <asm/uaccess.h>
@@ -47,7 +48,7 @@
47/* 48/*
48 * This is used to lock changes in serial line configuration. 49 * This is used to lock changes in serial line configuration.
49 */ 50 */
50static DECLARE_MUTEX(port_sem); 51static DEFINE_MUTEX(port_mutex);
51 52
52#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) 53#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
53 54
@@ -1472,7 +1473,7 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line)
1472{ 1473{
1473 struct uart_state *state; 1474 struct uart_state *state;
1474 1475
1475 down(&port_sem); 1476 mutex_lock(&port_mutex);
1476 state = drv->state + line; 1477 state = drv->state + line;
1477 if (down_interruptible(&state->sem)) { 1478 if (down_interruptible(&state->sem)) {
1478 state = ERR_PTR(-ERESTARTSYS); 1479 state = ERR_PTR(-ERESTARTSYS);
@@ -1509,7 +1510,7 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line)
1509 } 1510 }
1510 1511
1511 out: 1512 out:
1512 up(&port_sem); 1513 mutex_unlock(&port_mutex);
1513 return state; 1514 return state;
1514} 1515}
1515 1516
@@ -2219,7 +2220,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
2219 2220
2220 state = drv->state + port->line; 2221 state = drv->state + port->line;
2221 2222
2222 down(&port_sem); 2223 mutex_lock(&port_mutex);
2223 if (state->port) { 2224 if (state->port) {
2224 ret = -EINVAL; 2225 ret = -EINVAL;
2225 goto out; 2226 goto out;
@@ -2255,7 +2256,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
2255 register_console(port->cons); 2256 register_console(port->cons);
2256 2257
2257 out: 2258 out:
2258 up(&port_sem); 2259 mutex_unlock(&port_mutex);
2259 2260
2260 return ret; 2261 return ret;
2261} 2262}
@@ -2279,7 +2280,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
2279 printk(KERN_ALERT "Removing wrong port: %p != %p\n", 2280 printk(KERN_ALERT "Removing wrong port: %p != %p\n",
2280 state->port, port); 2281 state->port, port);
2281 2282
2282 down(&port_sem); 2283 mutex_lock(&port_mutex);
2283 2284
2284 /* 2285 /*
2285 * Remove the devices from devfs 2286 * Remove the devices from devfs
@@ -2288,7 +2289,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
2288 2289
2289 uart_unconfigure_port(drv, state); 2290 uart_unconfigure_port(drv, state);
2290 state->port = NULL; 2291 state->port = NULL;
2291 up(&port_sem); 2292 mutex_unlock(&port_mutex);
2292 2293
2293 return 0; 2294 return 0;
2294} 2295}
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 96969cb960a9..c30333694fde 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -785,6 +785,8 @@ static struct pcmcia_device_id serial_ids[] = {
785 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"), 785 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"),
786 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"), 786 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"),
787 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ 787 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
788 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
789 PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
788 PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"), 790 PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"),
789 PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"), 791 PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"),
790 PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), 792 PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index fdd1f1915a42..ee98a867bc6d 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -52,6 +52,7 @@
52#include <linux/tty_flip.h> 52#include <linux/tty_flip.h>
53#include <linux/serial_core.h> 53#include <linux/serial_core.h>
54#include <linux/serial.h> 54#include <linux/serial.h>
55#include <linux/mutex.h>
55 56
56#include <asm/io.h> 57#include <asm/io.h>
57#include <asm/irq.h> 58#include <asm/irq.h>
@@ -1018,7 +1019,7 @@ static void serial_txx9_resume_port(int line)
1018 uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port); 1019 uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
1019} 1020}
1020 1021
1021static DECLARE_MUTEX(serial_txx9_sem); 1022static DEFINE_MUTEX(serial_txx9_mutex);
1022 1023
1023/** 1024/**
1024 * serial_txx9_register_port - register a serial port 1025 * serial_txx9_register_port - register a serial port
@@ -1037,7 +1038,7 @@ static int __devinit serial_txx9_register_port(struct uart_port *port)
1037 struct uart_txx9_port *uart; 1038 struct uart_txx9_port *uart;
1038 int ret = -ENOSPC; 1039 int ret = -ENOSPC;
1039 1040
1040 down(&serial_txx9_sem); 1041 mutex_lock(&serial_txx9_mutex);
1041 for (i = 0; i < UART_NR; i++) { 1042 for (i = 0; i < UART_NR; i++) {
1042 uart = &serial_txx9_ports[i]; 1043 uart = &serial_txx9_ports[i];
1043 if (uart->port.type == PORT_UNKNOWN) 1044 if (uart->port.type == PORT_UNKNOWN)
@@ -1058,7 +1059,7 @@ static int __devinit serial_txx9_register_port(struct uart_port *port)
1058 if (ret == 0) 1059 if (ret == 0)
1059 ret = uart->port.line; 1060 ret = uart->port.line;
1060 } 1061 }
1061 up(&serial_txx9_sem); 1062 mutex_unlock(&serial_txx9_mutex);
1062 return ret; 1063 return ret;
1063} 1064}
1064 1065
@@ -1073,7 +1074,7 @@ static void __devexit serial_txx9_unregister_port(int line)
1073{ 1074{
1074 struct uart_txx9_port *uart = &serial_txx9_ports[line]; 1075 struct uart_txx9_port *uart = &serial_txx9_ports[line];
1075 1076
1076 down(&serial_txx9_sem); 1077 mutex_lock(&serial_txx9_mutex);
1077 uart_remove_one_port(&serial_txx9_reg, &uart->port); 1078 uart_remove_one_port(&serial_txx9_reg, &uart->port);
1078 uart->port.flags = 0; 1079 uart->port.flags = 0;
1079 uart->port.type = PORT_UNKNOWN; 1080 uart->port.type = PORT_UNKNOWN;
@@ -1082,7 +1083,7 @@ static void __devexit serial_txx9_unregister_port(int line)
1082 uart->port.membase = 0; 1083 uart->port.membase = 0;
1083 uart->port.dev = NULL; 1084 uart->port.dev = NULL;
1084 uart_add_one_port(&serial_txx9_reg, &uart->port); 1085 uart_add_one_port(&serial_txx9_reg, &uart->port);
1085 up(&serial_txx9_sem); 1086 mutex_unlock(&serial_txx9_mutex);
1086} 1087}
1087 1088
1088/* 1089/*
diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c
index 7bdab2a7f59c..94b229031198 100644
--- a/drivers/sh/superhyway/superhyway.c
+++ b/drivers/sh/superhyway/superhyway.c
@@ -175,8 +175,6 @@ int superhyway_register_driver(struct superhyway_driver *drv)
175{ 175{
176 drv->drv.name = drv->name; 176 drv->drv.name = drv->name;
177 drv->drv.bus = &superhyway_bus_type; 177 drv->drv.bus = &superhyway_bus_type;
178 drv->drv.probe = superhyway_device_probe;
179 drv->drv.remove = superhyway_device_remove;
180 178
181 return driver_register(&drv->drv); 179 return driver_register(&drv->drv);
182} 180}
@@ -213,6 +211,8 @@ struct bus_type superhyway_bus_type = {
213#ifdef CONFIG_SYSFS 211#ifdef CONFIG_SYSFS
214 .dev_attrs = superhyway_dev_attrs, 212 .dev_attrs = superhyway_dev_attrs,
215#endif 213#endif
214 .probe = superhyway_device_probe,
215 .remove = superhyway_device_remove,
216}; 216};
217 217
218static int __init superhyway_bus_init(void) 218static int __init superhyway_bus_init(void)
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
new file mode 100644
index 000000000000..b77dbd63e596
--- /dev/null
+++ b/drivers/spi/Kconfig
@@ -0,0 +1,109 @@
1#
2# SPI driver configuration
3#
4# NOTE: the reason this doesn't show SPI slave support is mostly that
5# nobody's needed a slave side API yet. The master-role API is not
6# fully appropriate there, so it'd need some thought to do well.
7#
8menu "SPI support"
9
10config SPI
11 bool "SPI support"
12 help
13 The "Serial Peripheral Interface" is a low level synchronous
14 protocol. Chips that support SPI can have data transfer rates
15 up to several tens of Mbit/sec. Chips are addressed with a
16 controller and a chipselect. Most SPI slaves don't support
17 dynamic device discovery; some are even write-only or read-only.
18
19 SPI is widely used by microcontollers to talk with sensors,
20 eeprom and flash memory, codecs and various other controller
21 chips, analog to digital (and d-to-a) converters, and more.
22 MMC and SD cards can be accessed using SPI protocol; and for
23 DataFlash cards used in MMC sockets, SPI must always be used.
24
25 SPI is one of a family of similar protocols using a four wire
26 interface (select, clock, data in, data out) including Microwire
27 (half duplex), SSP, SSI, and PSP. This driver framework should
28 work with most such devices and controllers.
29
30config SPI_DEBUG
31 boolean "Debug support for SPI drivers"
32 depends on SPI && DEBUG_KERNEL
33 help
34 Say "yes" to enable debug messaging (like dev_dbg and pr_debug),
35 sysfs, and debugfs support in SPI controller and protocol drivers.
36
37#
38# MASTER side ... talking to discrete SPI slave chips including microcontrollers
39#
40
41config SPI_MASTER
42# boolean "SPI Master Support"
43 boolean
44 default SPI
45 help
46 If your system has an master-capable SPI controller (which
47 provides the clock and chipselect), you can enable that
48 controller and the protocol drivers for the SPI slave chips
49 that are connected.
50
51comment "SPI Master Controller Drivers"
52 depends on SPI_MASTER
53
54config SPI_BITBANG
55 tristate "Bitbanging SPI master"
56 depends on SPI_MASTER && EXPERIMENTAL
57 help
58 With a few GPIO pins, your system can bitbang the SPI protocol.
59 Select this to get SPI support through I/O pins (GPIO, parallel
60 port, etc). Or, some systems' SPI master controller drivers use
61 this code to manage the per-word or per-transfer accesses to the
62 hardware shift registers.
63
64 This is library code, and is automatically selected by drivers that
65 need it. You only need to select this explicitly to support driver
66 modules that aren't part of this kernel tree.
67
68config SPI_BUTTERFLY
69 tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)"
70 depends on SPI_MASTER && PARPORT && EXPERIMENTAL
71 select SPI_BITBANG
72 help
73 This uses a custom parallel port cable to connect to an AVR
74 Butterfly <http://www.atmel.com/products/avr/butterfly>, an
75 inexpensive battery powered microcontroller evaluation board.
76 This same cable can be used to flash new firmware.
77
78config SPI_BUTTERFLY
79 tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)"
80 depends on SPI_MASTER && PARPORT && EXPERIMENTAL
81 select SPI_BITBANG
82 help
83 This uses a custom parallel port cable to connect to an AVR
84 Butterfly <http://www.atmel.com/products/avr/butterfly>, an
85 inexpensive battery powered microcontroller evaluation board.
86 This same cable can be used to flash new firmware.
87
88#
89# Add new SPI master controllers in alphabetical order above this line
90#
91
92
93#
94# There are lots of SPI device types, with sensors and memory
95# being probably the most widely used ones.
96#
97comment "SPI Protocol Masters"
98 depends on SPI_MASTER
99
100
101#
102# Add new SPI protocol masters in alphabetical order above this line
103#
104
105
106# (slave support would go here)
107
108endmenu # "SPI support"
109
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
new file mode 100644
index 000000000000..c2c87e845abf
--- /dev/null
+++ b/drivers/spi/Makefile
@@ -0,0 +1,25 @@
1#
2# Makefile for kernel SPI drivers.
3#
4
5ifeq ($(CONFIG_SPI_DEBUG),y)
6EXTRA_CFLAGS += -DDEBUG
7endif
8
9# small core, mostly translating board-specific
10# config declarations into driver model code
11obj-$(CONFIG_SPI_MASTER) += spi.o
12
13# SPI master controller drivers (bus)
14obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
15obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
16# ... add above this line ...
17
18# SPI protocol drivers (device/link on bus)
19# ... add above this line ...
20
21# SPI slave controller drivers (upstream link)
22# ... add above this line ...
23
24# SPI slave drivers (protocol for that link)
25# ... add above this line ...
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
new file mode 100644
index 000000000000..791c4dc550ae
--- /dev/null
+++ b/drivers/spi/spi.c
@@ -0,0 +1,642 @@
1/*
2 * spi.c - SPI init/core code
3 *
4 * Copyright (C) 2005 David Brownell
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/autoconf.h>
22#include <linux/kernel.h>
23#include <linux/device.h>
24#include <linux/init.h>
25#include <linux/cache.h>
26#include <linux/spi/spi.h>
27
28
29/* SPI bustype and spi_master class are registered after board init code
30 * provides the SPI device tables, ensuring that both are present by the
31 * time controller driver registration causes spi_devices to "enumerate".
32 */
33static void spidev_release(struct device *dev)
34{
35 const struct spi_device *spi = to_spi_device(dev);
36
37 /* spi masters may cleanup for released devices */
38 if (spi->master->cleanup)
39 spi->master->cleanup(spi);
40
41 spi_master_put(spi->master);
42 kfree(dev);
43}
44
45static ssize_t
46modalias_show(struct device *dev, struct device_attribute *a, char *buf)
47{
48 const struct spi_device *spi = to_spi_device(dev);
49
50 return snprintf(buf, BUS_ID_SIZE + 1, "%s\n", spi->modalias);
51}
52
53static struct device_attribute spi_dev_attrs[] = {
54 __ATTR_RO(modalias),
55 __ATTR_NULL,
56};
57
58/* modalias support makes "modprobe $MODALIAS" new-style hotplug work,
59 * and the sysfs version makes coldplug work too.
60 */
61
62static int spi_match_device(struct device *dev, struct device_driver *drv)
63{
64 const struct spi_device *spi = to_spi_device(dev);
65
66 return strncmp(spi->modalias, drv->name, BUS_ID_SIZE) == 0;
67}
68
69static int spi_uevent(struct device *dev, char **envp, int num_envp,
70 char *buffer, int buffer_size)
71{
72 const struct spi_device *spi = to_spi_device(dev);
73
74 envp[0] = buffer;
75 snprintf(buffer, buffer_size, "MODALIAS=%s", spi->modalias);
76 envp[1] = NULL;
77 return 0;
78}
79
80#ifdef CONFIG_PM
81
82/*
83 * NOTE: the suspend() method for an spi_master controller driver
84 * should verify that all its child devices are marked as suspended;
85 * suspend requests delivered through sysfs power/state files don't
86 * enforce such constraints.
87 */
88static int spi_suspend(struct device *dev, pm_message_t message)
89{
90 int value;
91 struct spi_driver *drv = to_spi_driver(dev->driver);
92
93 if (!drv->suspend)
94 return 0;
95
96 /* suspend will stop irqs and dma; no more i/o */
97 value = drv->suspend(to_spi_device(dev), message);
98 if (value == 0)
99 dev->power.power_state = message;
100 return value;
101}
102
103static int spi_resume(struct device *dev)
104{
105 int value;
106 struct spi_driver *drv = to_spi_driver(dev->driver);
107
108 if (!drv->resume)
109 return 0;
110
111 /* resume may restart the i/o queue */
112 value = drv->resume(to_spi_device(dev));
113 if (value == 0)
114 dev->power.power_state = PMSG_ON;
115 return value;
116}
117
118#else
119#define spi_suspend NULL
120#define spi_resume NULL
121#endif
122
123struct bus_type spi_bus_type = {
124 .name = "spi",
125 .dev_attrs = spi_dev_attrs,
126 .match = spi_match_device,
127 .uevent = spi_uevent,
128 .suspend = spi_suspend,
129 .resume = spi_resume,
130};
131EXPORT_SYMBOL_GPL(spi_bus_type);
132
133
134static int spi_drv_probe(struct device *dev)
135{
136 const struct spi_driver *sdrv = to_spi_driver(dev->driver);
137
138 return sdrv->probe(to_spi_device(dev));
139}
140
141static int spi_drv_remove(struct device *dev)
142{
143 const struct spi_driver *sdrv = to_spi_driver(dev->driver);
144
145 return sdrv->remove(to_spi_device(dev));
146}
147
148static void spi_drv_shutdown(struct device *dev)
149{
150 const struct spi_driver *sdrv = to_spi_driver(dev->driver);
151
152 sdrv->shutdown(to_spi_device(dev));
153}
154
155int spi_register_driver(struct spi_driver *sdrv)
156{
157 sdrv->driver.bus = &spi_bus_type;
158 if (sdrv->probe)
159 sdrv->driver.probe = spi_drv_probe;
160 if (sdrv->remove)
161 sdrv->driver.remove = spi_drv_remove;
162 if (sdrv->shutdown)
163 sdrv->driver.shutdown = spi_drv_shutdown;
164 return driver_register(&sdrv->driver);
165}
166EXPORT_SYMBOL_GPL(spi_register_driver);
167
168/*-------------------------------------------------------------------------*/
169
170/* SPI devices should normally not be created by SPI device drivers; that
171 * would make them board-specific. Similarly with SPI master drivers.
172 * Device registration normally goes into like arch/.../mach.../board-YYY.c
173 * with other readonly (flashable) information about mainboard devices.
174 */
175
176struct boardinfo {
177 struct list_head list;
178 unsigned n_board_info;
179 struct spi_board_info board_info[0];
180};
181
182static LIST_HEAD(board_list);
183static DECLARE_MUTEX(board_lock);
184
185
186/* On typical mainboards, this is purely internal; and it's not needed
187 * after board init creates the hard-wired devices. Some development
188 * platforms may not be able to use spi_register_board_info though, and
189 * this is exported so that for example a USB or parport based adapter
190 * driver could add devices (which it would learn about out-of-band).
191 */
192struct spi_device *__init_or_module
193spi_new_device(struct spi_master *master, struct spi_board_info *chip)
194{
195 struct spi_device *proxy;
196 struct device *dev = master->cdev.dev;
197 int status;
198
199 /* NOTE: caller did any chip->bus_num checks necessary */
200
201 if (!spi_master_get(master))
202 return NULL;
203
204 proxy = kzalloc(sizeof *proxy, GFP_KERNEL);
205 if (!proxy) {
206 dev_err(dev, "can't alloc dev for cs%d\n",
207 chip->chip_select);
208 goto fail;
209 }
210 proxy->master = master;
211 proxy->chip_select = chip->chip_select;
212 proxy->max_speed_hz = chip->max_speed_hz;
213 proxy->irq = chip->irq;
214 proxy->modalias = chip->modalias;
215
216 snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id,
217 "%s.%u", master->cdev.class_id,
218 chip->chip_select);
219 proxy->dev.parent = dev;
220 proxy->dev.bus = &spi_bus_type;
221 proxy->dev.platform_data = (void *) chip->platform_data;
222 proxy->controller_data = chip->controller_data;
223 proxy->controller_state = NULL;
224 proxy->dev.release = spidev_release;
225
226 /* drivers may modify this default i/o setup */
227 status = master->setup(proxy);
228 if (status < 0) {
229 dev_dbg(dev, "can't %s %s, status %d\n",
230 "setup", proxy->dev.bus_id, status);
231 goto fail;
232 }
233
234 /* driver core catches callers that misbehave by defining
235 * devices that already exist.
236 */
237 status = device_register(&proxy->dev);
238 if (status < 0) {
239 dev_dbg(dev, "can't %s %s, status %d\n",
240 "add", proxy->dev.bus_id, status);
241 goto fail;
242 }
243 dev_dbg(dev, "registered child %s\n", proxy->dev.bus_id);
244 return proxy;
245
246fail:
247 spi_master_put(master);
248 kfree(proxy);
249 return NULL;
250}
251EXPORT_SYMBOL_GPL(spi_new_device);
252
253/*
254 * Board-specific early init code calls this (probably during arch_initcall)
255 * with segments of the SPI device table. Any device nodes are created later,
256 * after the relevant parent SPI controller (bus_num) is defined. We keep
257 * this table of devices forever, so that reloading a controller driver will
258 * not make Linux forget about these hard-wired devices.
259 *
260 * Other code can also call this, e.g. a particular add-on board might provide
261 * SPI devices through its expansion connector, so code initializing that board
262 * would naturally declare its SPI devices.
263 *
264 * The board info passed can safely be __initdata ... but be careful of
265 * any embedded pointers (platform_data, etc), they're copied as-is.
266 */
267int __init
268spi_register_board_info(struct spi_board_info const *info, unsigned n)
269{
270 struct boardinfo *bi;
271
272 bi = kmalloc(sizeof(*bi) + n * sizeof *info, GFP_KERNEL);
273 if (!bi)
274 return -ENOMEM;
275 bi->n_board_info = n;
276 memcpy(bi->board_info, info, n * sizeof *info);
277
278 down(&board_lock);
279 list_add_tail(&bi->list, &board_list);
280 up(&board_lock);
281 return 0;
282}
283EXPORT_SYMBOL_GPL(spi_register_board_info);
284
285/* FIXME someone should add support for a __setup("spi", ...) that
286 * creates board info from kernel command lines
287 */
288
289static void __init_or_module
290scan_boardinfo(struct spi_master *master)
291{
292 struct boardinfo *bi;
293 struct device *dev = master->cdev.dev;
294
295 down(&board_lock);
296 list_for_each_entry(bi, &board_list, list) {
297 struct spi_board_info *chip = bi->board_info;
298 unsigned n;
299
300 for (n = bi->n_board_info; n > 0; n--, chip++) {
301 if (chip->bus_num != master->bus_num)
302 continue;
303 /* some controllers only have one chip, so they
304 * might not use chipselects. otherwise, the
305 * chipselects are numbered 0..max.
306 */
307 if (chip->chip_select >= master->num_chipselect
308 && master->num_chipselect) {
309 dev_dbg(dev, "cs%d > max %d\n",
310 chip->chip_select,
311 master->num_chipselect);
312 continue;
313 }
314 (void) spi_new_device(master, chip);
315 }
316 }
317 up(&board_lock);
318}
319
320/*-------------------------------------------------------------------------*/
321
322static void spi_master_release(struct class_device *cdev)
323{
324 struct spi_master *master;
325
326 master = container_of(cdev, struct spi_master, cdev);
327 kfree(master);
328}
329
330static struct class spi_master_class = {
331 .name = "spi_master",
332 .owner = THIS_MODULE,
333 .release = spi_master_release,
334};
335
336
337/**
338 * spi_alloc_master - allocate SPI master controller
339 * @dev: the controller, possibly using the platform_bus
340 * @size: how much driver-private data to preallocate; the pointer to this
341 * memory is in the class_data field of the returned class_device,
342 * accessible with spi_master_get_devdata().
343 *
344 * This call is used only by SPI master controller drivers, which are the
345 * only ones directly touching chip registers. It's how they allocate
346 * an spi_master structure, prior to calling spi_add_master().
347 *
348 * This must be called from context that can sleep. It returns the SPI
349 * master structure on success, else NULL.
350 *
351 * The caller is responsible for assigning the bus number and initializing
352 * the master's methods before calling spi_add_master(); and (after errors
353 * adding the device) calling spi_master_put() to prevent a memory leak.
354 */
355struct spi_master * __init_or_module
356spi_alloc_master(struct device *dev, unsigned size)
357{
358 struct spi_master *master;
359
360 if (!dev)
361 return NULL;
362
363 master = kzalloc(size + sizeof *master, SLAB_KERNEL);
364 if (!master)
365 return NULL;
366
367 class_device_initialize(&master->cdev);
368 master->cdev.class = &spi_master_class;
369 master->cdev.dev = get_device(dev);
370 spi_master_set_devdata(master, &master[1]);
371
372 return master;
373}
374EXPORT_SYMBOL_GPL(spi_alloc_master);
375
376/**
377 * spi_register_master - register SPI master controller
378 * @master: initialized master, originally from spi_alloc_master()
379 *
380 * SPI master controllers connect to their drivers using some non-SPI bus,
381 * such as the platform bus. The final stage of probe() in that code
382 * includes calling spi_register_master() to hook up to this SPI bus glue.
383 *
384 * SPI controllers use board specific (often SOC specific) bus numbers,
385 * and board-specific addressing for SPI devices combines those numbers
386 * with chip select numbers. Since SPI does not directly support dynamic
387 * device identification, boards need configuration tables telling which
388 * chip is at which address.
389 *
390 * This must be called from context that can sleep. It returns zero on
391 * success, else a negative error code (dropping the master's refcount).
392 * After a successful return, the caller is responsible for calling
393 * spi_unregister_master().
394 */
395int __init_or_module
396spi_register_master(struct spi_master *master)
397{
398 static atomic_t dyn_bus_id = ATOMIC_INIT(0);
399 struct device *dev = master->cdev.dev;
400 int status = -ENODEV;
401 int dynamic = 0;
402
403 if (!dev)
404 return -ENODEV;
405
406 /* convention: dynamically assigned bus IDs count down from the max */
407 if (master->bus_num == 0) {
408 master->bus_num = atomic_dec_return(&dyn_bus_id);
409 dynamic = 1;
410 }
411
412 /* register the device, then userspace will see it.
413 * registration fails if the bus ID is in use.
414 */
415 snprintf(master->cdev.class_id, sizeof master->cdev.class_id,
416 "spi%u", master->bus_num);
417 status = class_device_add(&master->cdev);
418 if (status < 0)
419 goto done;
420 dev_dbg(dev, "registered master %s%s\n", master->cdev.class_id,
421 dynamic ? " (dynamic)" : "");
422
423 /* populate children from any spi device tables */
424 scan_boardinfo(master);
425 status = 0;
426done:
427 return status;
428}
429EXPORT_SYMBOL_GPL(spi_register_master);
430
431
432static int __unregister(struct device *dev, void *unused)
433{
434 /* note: before about 2.6.14-rc1 this would corrupt memory: */
435 spi_unregister_device(to_spi_device(dev));
436 return 0;
437}
438
439/**
440 * spi_unregister_master - unregister SPI master controller
441 * @master: the master being unregistered
442 *
443 * This call is used only by SPI master controller drivers, which are the
444 * only ones directly touching chip registers.
445 *
446 * This must be called from context that can sleep.
447 */
448void spi_unregister_master(struct spi_master *master)
449{
450 (void) device_for_each_child(master->cdev.dev, NULL, __unregister);
451 class_device_unregister(&master->cdev);
452 master->cdev.dev = NULL;
453}
454EXPORT_SYMBOL_GPL(spi_unregister_master);
455
456/**
457 * spi_busnum_to_master - look up master associated with bus_num
458 * @bus_num: the master's bus number
459 *
460 * This call may be used with devices that are registered after
461 * arch init time. It returns a refcounted pointer to the relevant
462 * spi_master (which the caller must release), or NULL if there is
463 * no such master registered.
464 */
465struct spi_master *spi_busnum_to_master(u16 bus_num)
466{
467 if (bus_num) {
468 char name[8];
469 struct kobject *bus;
470
471 snprintf(name, sizeof name, "spi%u", bus_num);
472 bus = kset_find_obj(&spi_master_class.subsys.kset, name);
473 if (bus)
474 return container_of(bus, struct spi_master, cdev.kobj);
475 }
476 return NULL;
477}
478EXPORT_SYMBOL_GPL(spi_busnum_to_master);
479
480
481/*-------------------------------------------------------------------------*/
482
483static void spi_complete(void *arg)
484{
485 complete(arg);
486}
487
488/**
489 * spi_sync - blocking/synchronous SPI data transfers
490 * @spi: device with which data will be exchanged
491 * @message: describes the data transfers
492 *
493 * This call may only be used from a context that may sleep. The sleep
494 * is non-interruptible, and has no timeout. Low-overhead controller
495 * drivers may DMA directly into and out of the message buffers.
496 *
497 * Note that the SPI device's chip select is active during the message,
498 * and then is normally disabled between messages. Drivers for some
499 * frequently-used devices may want to minimize costs of selecting a chip,
500 * by leaving it selected in anticipation that the next message will go
501 * to the same chip. (That may increase power usage.)
502 *
503 * Also, the caller is guaranteeing that the memory associated with the
504 * message will not be freed before this call returns.
505 *
506 * The return value is a negative error code if the message could not be
507 * submitted, else zero. When the value is zero, then message->status is
508 * also defined: it's the completion code for the transfer, either zero
509 * or a negative error code from the controller driver.
510 */
511int spi_sync(struct spi_device *spi, struct spi_message *message)
512{
513 DECLARE_COMPLETION(done);
514 int status;
515
516 message->complete = spi_complete;
517 message->context = &done;
518 status = spi_async(spi, message);
519 if (status == 0)
520 wait_for_completion(&done);
521 message->context = NULL;
522 return status;
523}
524EXPORT_SYMBOL_GPL(spi_sync);
525
526#define SPI_BUFSIZ (SMP_CACHE_BYTES)
527
528static u8 *buf;
529
530/**
531 * spi_write_then_read - SPI synchronous write followed by read
532 * @spi: device with which data will be exchanged
533 * @txbuf: data to be written (need not be dma-safe)
534 * @n_tx: size of txbuf, in bytes
535 * @rxbuf: buffer into which data will be read
536 * @n_rx: size of rxbuf, in bytes (need not be dma-safe)
537 *
538 * This performs a half duplex MicroWire style transaction with the
539 * device, sending txbuf and then reading rxbuf. The return value
540 * is zero for success, else a negative errno status code.
541 * This call may only be used from a context that may sleep.
542 *
543 * Parameters to this routine are always copied using a small buffer;
544 * performance-sensitive or bulk transfer code should instead use
545 * spi_{async,sync}() calls with dma-safe buffers.
546 */
547int spi_write_then_read(struct spi_device *spi,
548 const u8 *txbuf, unsigned n_tx,
549 u8 *rxbuf, unsigned n_rx)
550{
551 static DECLARE_MUTEX(lock);
552
553 int status;
554 struct spi_message message;
555 struct spi_transfer x[2];
556 u8 *local_buf;
557
558 /* Use preallocated DMA-safe buffer. We can't avoid copying here,
559 * (as a pure convenience thing), but we can keep heap costs
560 * out of the hot path ...
561 */
562 if ((n_tx + n_rx) > SPI_BUFSIZ)
563 return -EINVAL;
564
565 spi_message_init(&message);
566 memset(x, 0, sizeof x);
567 if (n_tx) {
568 x[0].len = n_tx;
569 spi_message_add_tail(&x[0], &message);
570 }
571 if (n_rx) {
572 x[1].len = n_rx;
573 spi_message_add_tail(&x[1], &message);
574 }
575
576 /* ... unless someone else is using the pre-allocated buffer */
577 if (down_trylock(&lock)) {
578 local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
579 if (!local_buf)
580 return -ENOMEM;
581 } else
582 local_buf = buf;
583
584 memcpy(local_buf, txbuf, n_tx);
585 x[0].tx_buf = local_buf;
586 x[1].rx_buf = local_buf + n_tx;
587
588 /* do the i/o */
589 status = spi_sync(spi, &message);
590 if (status == 0) {
591 memcpy(rxbuf, x[1].rx_buf, n_rx);
592 status = message.status;
593 }
594
595 if (x[0].tx_buf == buf)
596 up(&lock);
597 else
598 kfree(local_buf);
599
600 return status;
601}
602EXPORT_SYMBOL_GPL(spi_write_then_read);
603
604/*-------------------------------------------------------------------------*/
605
606static int __init spi_init(void)
607{
608 int status;
609
610 buf = kmalloc(SPI_BUFSIZ, SLAB_KERNEL);
611 if (!buf) {
612 status = -ENOMEM;
613 goto err0;
614 }
615
616 status = bus_register(&spi_bus_type);
617 if (status < 0)
618 goto err1;
619
620 status = class_register(&spi_master_class);
621 if (status < 0)
622 goto err2;
623 return 0;
624
625err2:
626 bus_unregister(&spi_bus_type);
627err1:
628 kfree(buf);
629 buf = NULL;
630err0:
631 return status;
632}
633
634/* board_info is normally registered in arch_initcall(),
635 * but even essential drivers wait till later
636 *
637 * REVISIT only boardinfo really needs static linking. the rest (device and
638 * driver registration) _could_ be dynamically linked (modular) ... costs
639 * include needing to have boardinfo data structures be much more public.
640 */
641subsys_initcall(spi_init);
642
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c
new file mode 100644
index 000000000000..f037e5593269
--- /dev/null
+++ b/drivers/spi/spi_bitbang.c
@@ -0,0 +1,472 @@
1/*
2 * spi_bitbang.c - polling/bitbanging SPI master controller driver utilities
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#include <linux/config.h>
20#include <linux/init.h>
21#include <linux/spinlock.h>
22#include <linux/workqueue.h>
23#include <linux/interrupt.h>
24#include <linux/delay.h>
25#include <linux/errno.h>
26#include <linux/platform_device.h>
27
28#include <linux/spi/spi.h>
29#include <linux/spi/spi_bitbang.h>
30
31
32/*----------------------------------------------------------------------*/
33
34/*
35 * FIRST PART (OPTIONAL): word-at-a-time spi_transfer support.
36 * Use this for GPIO or shift-register level hardware APIs.
37 *
38 * spi_bitbang_cs is in spi_device->controller_state, which is unavailable
39 * to glue code. These bitbang setup() and cleanup() routines are always
40 * used, though maybe they're called from controller-aware code.
41 *
42 * chipselect() and friends may use use spi_device->controller_data and
43 * controller registers as appropriate.
44 *
45 *
46 * NOTE: SPI controller pins can often be used as GPIO pins instead,
47 * which means you could use a bitbang driver either to get hardware
48 * working quickly, or testing for differences that aren't speed related.
49 */
50
51struct spi_bitbang_cs {
52 unsigned nsecs; /* (clock cycle time)/2 */
53 u32 (*txrx_word)(struct spi_device *spi, unsigned nsecs,
54 u32 word, u8 bits);
55 unsigned (*txrx_bufs)(struct spi_device *,
56 u32 (*txrx_word)(
57 struct spi_device *spi,
58 unsigned nsecs,
59 u32 word, u8 bits),
60 unsigned, struct spi_transfer *);
61};
62
63static unsigned bitbang_txrx_8(
64 struct spi_device *spi,
65 u32 (*txrx_word)(struct spi_device *spi,
66 unsigned nsecs,
67 u32 word, u8 bits),
68 unsigned ns,
69 struct spi_transfer *t
70) {
71 unsigned bits = spi->bits_per_word;
72 unsigned count = t->len;
73 const u8 *tx = t->tx_buf;
74 u8 *rx = t->rx_buf;
75
76 while (likely(count > 0)) {
77 u8 word = 0;
78
79 if (tx)
80 word = *tx++;
81 word = txrx_word(spi, ns, word, bits);
82 if (rx)
83 *rx++ = word;
84 count -= 1;
85 }
86 return t->len - count;
87}
88
89static unsigned bitbang_txrx_16(
90 struct spi_device *spi,
91 u32 (*txrx_word)(struct spi_device *spi,
92 unsigned nsecs,
93 u32 word, u8 bits),
94 unsigned ns,
95 struct spi_transfer *t
96) {
97 unsigned bits = spi->bits_per_word;
98 unsigned count = t->len;
99 const u16 *tx = t->tx_buf;
100 u16 *rx = t->rx_buf;
101
102 while (likely(count > 1)) {
103 u16 word = 0;
104
105 if (tx)
106 word = *tx++;
107 word = txrx_word(spi, ns, word, bits);
108 if (rx)
109 *rx++ = word;
110 count -= 2;
111 }
112 return t->len - count;
113}
114
115static unsigned bitbang_txrx_32(
116 struct spi_device *spi,
117 u32 (*txrx_word)(struct spi_device *spi,
118 unsigned nsecs,
119 u32 word, u8 bits),
120 unsigned ns,
121 struct spi_transfer *t
122) {
123 unsigned bits = spi->bits_per_word;
124 unsigned count = t->len;
125 const u32 *tx = t->tx_buf;
126 u32 *rx = t->rx_buf;
127
128 while (likely(count > 3)) {
129 u32 word = 0;
130
131 if (tx)
132 word = *tx++;
133 word = txrx_word(spi, ns, word, bits);
134 if (rx)
135 *rx++ = word;
136 count -= 4;
137 }
138 return t->len - count;
139}
140
141/**
142 * spi_bitbang_setup - default setup for per-word I/O loops
143 */
144int spi_bitbang_setup(struct spi_device *spi)
145{
146 struct spi_bitbang_cs *cs = spi->controller_state;
147 struct spi_bitbang *bitbang;
148
149 if (!spi->max_speed_hz)
150 return -EINVAL;
151
152 if (!cs) {
153 cs = kzalloc(sizeof *cs, SLAB_KERNEL);
154 if (!cs)
155 return -ENOMEM;
156 spi->controller_state = cs;
157 }
158 bitbang = spi_master_get_devdata(spi->master);
159
160 if (!spi->bits_per_word)
161 spi->bits_per_word = 8;
162
163 /* spi_transfer level calls that work per-word */
164 if (spi->bits_per_word <= 8)
165 cs->txrx_bufs = bitbang_txrx_8;
166 else if (spi->bits_per_word <= 16)
167 cs->txrx_bufs = bitbang_txrx_16;
168 else if (spi->bits_per_word <= 32)
169 cs->txrx_bufs = bitbang_txrx_32;
170 else
171 return -EINVAL;
172
173 /* per-word shift register access, in hardware or bitbanging */
174 cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)];
175 if (!cs->txrx_word)
176 return -EINVAL;
177
178 /* nsecs = (clock period)/2 */
179 cs->nsecs = (1000000000/2) / (spi->max_speed_hz);
180 if (cs->nsecs > MAX_UDELAY_MS * 1000)
181 return -EINVAL;
182
183 dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n",
184 __FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA),
185 spi->bits_per_word, 2 * cs->nsecs);
186
187 /* NOTE we _need_ to call chipselect() early, ideally with adapter
188 * setup, unless the hardware defaults cooperate to avoid confusion
189 * between normal (active low) and inverted chipselects.
190 */
191
192 /* deselect chip (low or high) */
193 spin_lock(&bitbang->lock);
194 if (!bitbang->busy) {
195 bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
196 ndelay(cs->nsecs);
197 }
198 spin_unlock(&bitbang->lock);
199
200 return 0;
201}
202EXPORT_SYMBOL_GPL(spi_bitbang_setup);
203
204/**
205 * spi_bitbang_cleanup - default cleanup for per-word I/O loops
206 */
207void spi_bitbang_cleanup(const struct spi_device *spi)
208{
209 kfree(spi->controller_state);
210}
211EXPORT_SYMBOL_GPL(spi_bitbang_cleanup);
212
213static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
214{
215 struct spi_bitbang_cs *cs = spi->controller_state;
216 unsigned nsecs = cs->nsecs;
217
218 return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t);
219}
220
221/*----------------------------------------------------------------------*/
222
223/*
224 * SECOND PART ... simple transfer queue runner.
225 *
226 * This costs a task context per controller, running the queue by
227 * performing each transfer in sequence. Smarter hardware can queue
228 * several DMA transfers at once, and process several controller queues
229 * in parallel; this driver doesn't match such hardware very well.
230 *
231 * Drivers can provide word-at-a-time i/o primitives, or provide
232 * transfer-at-a-time ones to leverage dma or fifo hardware.
233 */
234static void bitbang_work(void *_bitbang)
235{
236 struct spi_bitbang *bitbang = _bitbang;
237 unsigned long flags;
238
239 spin_lock_irqsave(&bitbang->lock, flags);
240 bitbang->busy = 1;
241 while (!list_empty(&bitbang->queue)) {
242 struct spi_message *m;
243 struct spi_device *spi;
244 unsigned nsecs;
245 struct spi_transfer *t = NULL;
246 unsigned tmp;
247 unsigned cs_change;
248 int status;
249
250 m = container_of(bitbang->queue.next, struct spi_message,
251 queue);
252 list_del_init(&m->queue);
253 spin_unlock_irqrestore(&bitbang->lock, flags);
254
255 /* FIXME this is made-up ... the correct value is known to
256 * word-at-a-time bitbang code, and presumably chipselect()
257 * should enforce these requirements too?
258 */
259 nsecs = 100;
260
261 spi = m->spi;
262 tmp = 0;
263 cs_change = 1;
264 status = 0;
265
266 list_for_each_entry (t, &m->transfers, transfer_list) {
267 if (bitbang->shutdown) {
268 status = -ESHUTDOWN;
269 break;
270 }
271
272 /* set up default clock polarity, and activate chip;
273 * this implicitly updates clock and spi modes as
274 * previously recorded for this device via setup().
275 * (and also deselects any other chip that might be
276 * selected ...)
277 */
278 if (cs_change) {
279 bitbang->chipselect(spi, BITBANG_CS_ACTIVE);
280 ndelay(nsecs);
281 }
282 cs_change = t->cs_change;
283 if (!t->tx_buf && !t->rx_buf && t->len) {
284 status = -EINVAL;
285 break;
286 }
287
288 /* transfer data. the lower level code handles any
289 * new dma mappings it needs. our caller always gave
290 * us dma-safe buffers.
291 */
292 if (t->len) {
293 /* REVISIT dma API still needs a designated
294 * DMA_ADDR_INVALID; ~0 might be better.
295 */
296 if (!m->is_dma_mapped)
297 t->rx_dma = t->tx_dma = 0;
298 status = bitbang->txrx_bufs(spi, t);
299 }
300 if (status != t->len) {
301 if (status > 0)
302 status = -EMSGSIZE;
303 break;
304 }
305 m->actual_length += status;
306 status = 0;
307
308 /* protocol tweaks before next transfer */
309 if (t->delay_usecs)
310 udelay(t->delay_usecs);
311
312 if (!cs_change)
313 continue;
314 if (t->transfer_list.next == &m->transfers)
315 break;
316
317 /* sometimes a short mid-message deselect of the chip
318 * may be needed to terminate a mode or command
319 */
320 ndelay(nsecs);
321 bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
322 ndelay(nsecs);
323 }
324
325 m->status = status;
326 m->complete(m->context);
327
328 /* normally deactivate chipselect ... unless no error and
329 * cs_change has hinted that the next message will probably
330 * be for this chip too.
331 */
332 if (!(status == 0 && cs_change)) {
333 ndelay(nsecs);
334 bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
335 ndelay(nsecs);
336 }
337
338 spin_lock_irqsave(&bitbang->lock, flags);
339 }
340 bitbang->busy = 0;
341 spin_unlock_irqrestore(&bitbang->lock, flags);
342}
343
344/**
345 * spi_bitbang_transfer - default submit to transfer queue
346 */
347int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m)
348{
349 struct spi_bitbang *bitbang;
350 unsigned long flags;
351
352 m->actual_length = 0;
353 m->status = -EINPROGRESS;
354
355 bitbang = spi_master_get_devdata(spi->master);
356 if (bitbang->shutdown)
357 return -ESHUTDOWN;
358
359 spin_lock_irqsave(&bitbang->lock, flags);
360 list_add_tail(&m->queue, &bitbang->queue);
361 queue_work(bitbang->workqueue, &bitbang->work);
362 spin_unlock_irqrestore(&bitbang->lock, flags);
363
364 return 0;
365}
366EXPORT_SYMBOL_GPL(spi_bitbang_transfer);
367
368/*----------------------------------------------------------------------*/
369
370/**
371 * spi_bitbang_start - start up a polled/bitbanging SPI master driver
372 * @bitbang: driver handle
373 *
374 * Caller should have zero-initialized all parts of the structure, and then
375 * provided callbacks for chip selection and I/O loops. If the master has
376 * a transfer method, its final step should call spi_bitbang_transfer; or,
377 * that's the default if the transfer routine is not initialized. It should
378 * also set up the bus number and number of chipselects.
379 *
380 * For i/o loops, provide callbacks either per-word (for bitbanging, or for
381 * hardware that basically exposes a shift register) or per-spi_transfer
382 * (which takes better advantage of hardware like fifos or DMA engines).
383 *
384 * Drivers using per-word I/O loops should use (or call) spi_bitbang_setup and
385 * spi_bitbang_cleanup to handle those spi master methods. Those methods are
386 * the defaults if the bitbang->txrx_bufs routine isn't initialized.
387 *
388 * This routine registers the spi_master, which will process requests in a
389 * dedicated task, keeping IRQs unblocked most of the time. To stop
390 * processing those requests, call spi_bitbang_stop().
391 */
392int spi_bitbang_start(struct spi_bitbang *bitbang)
393{
394 int status;
395
396 if (!bitbang->master || !bitbang->chipselect)
397 return -EINVAL;
398
399 INIT_WORK(&bitbang->work, bitbang_work, bitbang);
400 spin_lock_init(&bitbang->lock);
401 INIT_LIST_HEAD(&bitbang->queue);
402
403 if (!bitbang->master->transfer)
404 bitbang->master->transfer = spi_bitbang_transfer;
405 if (!bitbang->txrx_bufs) {
406 bitbang->use_dma = 0;
407 bitbang->txrx_bufs = spi_bitbang_bufs;
408 if (!bitbang->master->setup) {
409 bitbang->master->setup = spi_bitbang_setup;
410 bitbang->master->cleanup = spi_bitbang_cleanup;
411 }
412 } else if (!bitbang->master->setup)
413 return -EINVAL;
414
415 /* this task is the only thing to touch the SPI bits */
416 bitbang->busy = 0;
417 bitbang->workqueue = create_singlethread_workqueue(
418 bitbang->master->cdev.dev->bus_id);
419 if (bitbang->workqueue == NULL) {
420 status = -EBUSY;
421 goto err1;
422 }
423
424 /* driver may get busy before register() returns, especially
425 * if someone registered boardinfo for devices
426 */
427 status = spi_register_master(bitbang->master);
428 if (status < 0)
429 goto err2;
430
431 return status;
432
433err2:
434 destroy_workqueue(bitbang->workqueue);
435err1:
436 return status;
437}
438EXPORT_SYMBOL_GPL(spi_bitbang_start);
439
440/**
441 * spi_bitbang_stop - stops the task providing spi communication
442 */
443int spi_bitbang_stop(struct spi_bitbang *bitbang)
444{
445 unsigned limit = 500;
446
447 spin_lock_irq(&bitbang->lock);
448 bitbang->shutdown = 0;
449 while (!list_empty(&bitbang->queue) && limit--) {
450 spin_unlock_irq(&bitbang->lock);
451
452 dev_dbg(bitbang->master->cdev.dev, "wait for queue\n");
453 msleep(10);
454
455 spin_lock_irq(&bitbang->lock);
456 }
457 spin_unlock_irq(&bitbang->lock);
458 if (!list_empty(&bitbang->queue)) {
459 dev_err(bitbang->master->cdev.dev, "queue didn't empty\n");
460 return -EBUSY;
461 }
462
463 destroy_workqueue(bitbang->workqueue);
464
465 spi_unregister_master(bitbang->master);
466
467 return 0;
468}
469EXPORT_SYMBOL_GPL(spi_bitbang_stop);
470
471MODULE_LICENSE("GPL");
472
diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c
new file mode 100644
index 000000000000..79a3c59615ab
--- /dev/null
+++ b/drivers/spi/spi_butterfly.c
@@ -0,0 +1,423 @@
1/*
2 * spi_butterfly.c - parport-to-butterfly adapter
3 *
4 * Copyright (C) 2005 David Brownell
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20#include <linux/config.h>
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/platform_device.h>
25#include <linux/parport.h>
26
27#include <linux/spi/spi.h>
28#include <linux/spi/spi_bitbang.h>
29#include <linux/spi/flash.h>
30
31#include <linux/mtd/partitions.h>
32
33
34/*
35 * This uses SPI to talk with an "AVR Butterfly", which is a $US20 card
36 * with a battery powered AVR microcontroller and lots of goodies. You
37 * can use GCC to develop firmware for this.
38 *
39 * See Documentation/spi/butterfly for information about how to build
40 * and use this custom parallel port cable.
41 */
42
43#undef HAVE_USI /* nyet */
44
45
46/* DATA output bits (pins 2..9 == D0..D7) */
47#define butterfly_nreset (1 << 1) /* pin 3 */
48
49#define spi_sck_bit (1 << 0) /* pin 2 */
50#define spi_mosi_bit (1 << 7) /* pin 9 */
51
52#define usi_sck_bit (1 << 3) /* pin 5 */
53#define usi_mosi_bit (1 << 4) /* pin 6 */
54
55#define vcc_bits ((1 << 6) | (1 << 5)) /* pins 7, 8 */
56
57/* STATUS input bits */
58#define spi_miso_bit PARPORT_STATUS_BUSY /* pin 11 */
59
60#define usi_miso_bit PARPORT_STATUS_PAPEROUT /* pin 12 */
61
62/* CONTROL output bits */
63#define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */
64/* USI uses no chipselect */
65
66
67
68static inline struct butterfly *spidev_to_pp(struct spi_device *spi)
69{
70 return spi->controller_data;
71}
72
73static inline int is_usidev(struct spi_device *spi)
74{
75#ifdef HAVE_USI
76 return spi->chip_select != 1;
77#else
78 return 0;
79#endif
80}
81
82
83struct butterfly {
84 /* REVISIT ... for now, this must be first */
85 struct spi_bitbang bitbang;
86
87 struct parport *port;
88 struct pardevice *pd;
89
90 u8 lastbyte;
91
92 struct spi_device *dataflash;
93 struct spi_device *butterfly;
94 struct spi_board_info info[2];
95
96};
97
98/*----------------------------------------------------------------------*/
99
100/*
101 * these routines may be slower than necessary because they're hiding
102 * the fact that there are two different SPI busses on this cable: one
103 * to the DataFlash chip (or AVR SPI controller), the other to the
104 * AVR USI controller.
105 */
106
107static inline void
108setsck(struct spi_device *spi, int is_on)
109{
110 struct butterfly *pp = spidev_to_pp(spi);
111 u8 bit, byte = pp->lastbyte;
112
113 if (is_usidev(spi))
114 bit = usi_sck_bit;
115 else
116 bit = spi_sck_bit;
117
118 if (is_on)
119 byte |= bit;
120 else
121 byte &= ~bit;
122 parport_write_data(pp->port, byte);
123 pp->lastbyte = byte;
124}
125
126static inline void
127setmosi(struct spi_device *spi, int is_on)
128{
129 struct butterfly *pp = spidev_to_pp(spi);
130 u8 bit, byte = pp->lastbyte;
131
132 if (is_usidev(spi))
133 bit = usi_mosi_bit;
134 else
135 bit = spi_mosi_bit;
136
137 if (is_on)
138 byte |= bit;
139 else
140 byte &= ~bit;
141 parport_write_data(pp->port, byte);
142 pp->lastbyte = byte;
143}
144
145static inline int getmiso(struct spi_device *spi)
146{
147 struct butterfly *pp = spidev_to_pp(spi);
148 int value;
149 u8 bit;
150
151 if (is_usidev(spi))
152 bit = usi_miso_bit;
153 else
154 bit = spi_miso_bit;
155
156 /* only STATUS_BUSY is NOT negated */
157 value = !(parport_read_status(pp->port) & bit);
158 return (bit == PARPORT_STATUS_BUSY) ? value : !value;
159}
160
161static void butterfly_chipselect(struct spi_device *spi, int value)
162{
163 struct butterfly *pp = spidev_to_pp(spi);
164
165 /* set default clock polarity */
166 if (value)
167 setsck(spi, spi->mode & SPI_CPOL);
168
169 /* no chipselect on this USI link config */
170 if (is_usidev(spi))
171 return;
172
173 /* here, value == "activate or not" */
174
175 /* most PARPORT_CONTROL_* bits are negated */
176 if (spi_cs_bit == PARPORT_CONTROL_INIT)
177 value = !value;
178
179 /* here, value == "bit value to write in control register" */
180
181 parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0);
182}
183
184
185/* we only needed to implement one mode here, and choose SPI_MODE_0 */
186
187#define spidelay(X) do{}while(0)
188//#define spidelay ndelay
189
190#define EXPAND_BITBANG_TXRX
191#include <linux/spi/spi_bitbang.h>
192
193static u32
194butterfly_txrx_word_mode0(struct spi_device *spi,
195 unsigned nsecs,
196 u32 word, u8 bits)
197{
198 return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
199}
200
201/*----------------------------------------------------------------------*/
202
203/* override default partitioning with cmdlinepart */
204static struct mtd_partition partitions[] = { {
205 /* JFFS2 wants partitions of 4*N blocks for this device ... */
206
207 /* sector 0 = 8 pages * 264 bytes/page (1 block)
208 * sector 1 = 248 pages * 264 bytes/page
209 */
210 .name = "bookkeeping", // 66 KB
211 .offset = 0,
212 .size = (8 + 248) * 264,
213// .mask_flags = MTD_WRITEABLE,
214}, {
215 /* sector 2 = 256 pages * 264 bytes/page
216 * sectors 3-5 = 512 pages * 264 bytes/page
217 */
218 .name = "filesystem", // 462 KB
219 .offset = MTDPART_OFS_APPEND,
220 .size = MTDPART_SIZ_FULL,
221} };
222
223static struct flash_platform_data flash = {
224 .name = "butterflash",
225 .parts = partitions,
226 .nr_parts = ARRAY_SIZE(partitions),
227};
228
229
230/* REVISIT remove this ugly global and its "only one" limitation */
231static struct butterfly *butterfly;
232
233static void butterfly_attach(struct parport *p)
234{
235 struct pardevice *pd;
236 int status;
237 struct butterfly *pp;
238 struct spi_master *master;
239 struct platform_device *pdev;
240
241 if (butterfly)
242 return;
243
244 /* REVISIT: this just _assumes_ a butterfly is there ... no probe,
245 * and no way to be selective about what it binds to.
246 */
247
248 /* FIXME where should master->cdev.dev come from?
249 * e.g. /sys/bus/pnp0/00:0b, some PCI thing, etc
250 * setting up a platform device like this is an ugly kluge...
251 */
252 pdev = platform_device_register_simple("butterfly", -1, NULL, 0);
253
254 master = spi_alloc_master(&pdev->dev, sizeof *pp);
255 if (!master) {
256 status = -ENOMEM;
257 goto done;
258 }
259 pp = spi_master_get_devdata(master);
260
261 /*
262 * SPI and bitbang hookup
263 *
264 * use default setup(), cleanup(), and transfer() methods; and
265 * only bother implementing mode 0. Start it later.
266 */
267 master->bus_num = 42;
268 master->num_chipselect = 2;
269
270 pp->bitbang.master = spi_master_get(master);
271 pp->bitbang.chipselect = butterfly_chipselect;
272 pp->bitbang.txrx_word[SPI_MODE_0] = butterfly_txrx_word_mode0;
273
274 /*
275 * parport hookup
276 */
277 pp->port = p;
278 pd = parport_register_device(p, "spi_butterfly",
279 NULL, NULL, NULL,
280 0 /* FLAGS */, pp);
281 if (!pd) {
282 status = -ENOMEM;
283 goto clean0;
284 }
285 pp->pd = pd;
286
287 status = parport_claim(pd);
288 if (status < 0)
289 goto clean1;
290
291 /*
292 * Butterfly reset, powerup, run firmware
293 */
294 pr_debug("%s: powerup/reset Butterfly\n", p->name);
295
296 /* nCS for dataflash (this bit is inverted on output) */
297 parport_frob_control(pp->port, spi_cs_bit, 0);
298
299 /* stabilize power with chip in reset (nRESET), and
300 * both spi_sck_bit and usi_sck_bit clear (CPOL=0)
301 */
302 pp->lastbyte |= vcc_bits;
303 parport_write_data(pp->port, pp->lastbyte);
304 msleep(5);
305
306 /* take it out of reset; assume long reset delay */
307 pp->lastbyte |= butterfly_nreset;
308 parport_write_data(pp->port, pp->lastbyte);
309 msleep(100);
310
311
312 /*
313 * Start SPI ... for now, hide that we're two physical busses.
314 */
315 status = spi_bitbang_start(&pp->bitbang);
316 if (status < 0)
317 goto clean2;
318
319 /* Bus 1 lets us talk to at45db041b (firmware disables AVR)
320 * or AVR (firmware resets at45, acts as spi slave)
321 */
322 pp->info[0].max_speed_hz = 15 * 1000 * 1000;
323 strcpy(pp->info[0].modalias, "mtd_dataflash");
324 pp->info[0].platform_data = &flash;
325 pp->info[0].chip_select = 1;
326 pp->info[0].controller_data = pp;
327 pp->dataflash = spi_new_device(pp->bitbang.master, &pp->info[0]);
328 if (pp->dataflash)
329 pr_debug("%s: dataflash at %s\n", p->name,
330 pp->dataflash->dev.bus_id);
331
332#ifdef HAVE_USI
333 /* even more custom AVR firmware */
334 pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000;
335 strcpy(pp->info[1].modalias, "butterfly");
336 // pp->info[1].platform_data = ... TBD ... ;
337 pp->info[1].chip_select = 2,
338 pp->info[1].controller_data = pp;
339 pp->butterfly = spi_new_device(pp->bitbang.master, &pp->info[1]);
340 if (pp->butterfly)
341 pr_debug("%s: butterfly at %s\n", p->name,
342 pp->butterfly->dev.bus_id);
343
344 /* FIXME setup ACK for the IRQ line ... */
345#endif
346
347 // dev_info(_what?_, ...)
348 pr_info("%s: AVR Butterfly\n", p->name);
349 butterfly = pp;
350 return;
351
352clean2:
353 /* turn off VCC */
354 parport_write_data(pp->port, 0);
355
356 parport_release(pp->pd);
357clean1:
358 parport_unregister_device(pd);
359clean0:
360 (void) spi_master_put(pp->bitbang.master);
361done:
362 platform_device_unregister(pdev);
363 pr_debug("%s: butterfly probe, fail %d\n", p->name, status);
364}
365
366static void butterfly_detach(struct parport *p)
367{
368 struct butterfly *pp;
369 struct platform_device *pdev;
370 int status;
371
372 /* FIXME this global is ugly ... but, how to quickly get from
373 * the parport to the "struct butterfly" associated with it?
374 * "old school" driver-internal device lists?
375 */
376 if (!butterfly || butterfly->port != p)
377 return;
378 pp = butterfly;
379 butterfly = NULL;
380
381#ifdef HAVE_USI
382 spi_unregister_device(pp->butterfly);
383 pp->butterfly = NULL;
384#endif
385 spi_unregister_device(pp->dataflash);
386 pp->dataflash = NULL;
387
388 status = spi_bitbang_stop(&pp->bitbang);
389
390 /* turn off VCC */
391 parport_write_data(pp->port, 0);
392 msleep(10);
393
394 parport_release(pp->pd);
395 parport_unregister_device(pp->pd);
396
397 pdev = to_platform_device(pp->bitbang.master->cdev.dev);
398
399 (void) spi_master_put(pp->bitbang.master);
400
401 platform_device_unregister(pdev);
402}
403
404static struct parport_driver butterfly_driver = {
405 .name = "spi_butterfly",
406 .attach = butterfly_attach,
407 .detach = butterfly_detach,
408};
409
410
411static int __init butterfly_init(void)
412{
413 return parport_register_driver(&butterfly_driver);
414}
415device_initcall(butterfly_init);
416
417static void __exit butterfly_exit(void)
418{
419 parport_unregister_driver(&butterfly_driver);
420}
421module_exit(butterfly_exit);
422
423MODULE_LICENSE("GPL");
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 8f402f85e1ca..afc84cfb61f9 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -2534,9 +2534,6 @@ static struct usb_gadget_driver eth_driver = {
2534 .driver = { 2534 .driver = {
2535 .name = (char *) shortname, 2535 .name = (char *) shortname,
2536 .owner = THIS_MODULE, 2536 .owner = THIS_MODULE,
2537 // .shutdown = ...
2538 // .suspend = ...
2539 // .resume = ...
2540 }, 2537 },
2541}; 2538};
2542 2539
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index c6c279de832e..9a4edc5657aa 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -1738,9 +1738,6 @@ static struct usb_gadget_driver gadgetfs_driver = {
1738 1738
1739 .driver = { 1739 .driver = {
1740 .name = (char *) shortname, 1740 .name = (char *) shortname,
1741 // .shutdown = ...
1742 // .suspend = ...
1743 // .resume = ...
1744 }, 1741 },
1745}; 1742};
1746 1743
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 2e6926b33455..ba9acd531024 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -374,9 +374,6 @@ static struct usb_gadget_driver gs_gadget_driver = {
374 .disconnect = gs_disconnect, 374 .disconnect = gs_disconnect,
375 .driver = { 375 .driver = {
376 .name = GS_SHORT_NAME, 376 .name = GS_SHORT_NAME,
377 /* .shutdown = ... */
378 /* .suspend = ... */
379 /* .resume = ... */
380 }, 377 },
381}; 378};
382 379
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 6c58636e914b..2fc110d3ad5a 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -1303,9 +1303,6 @@ static struct usb_gadget_driver zero_driver = {
1303 .driver = { 1303 .driver = {
1304 .name = (char *) shortname, 1304 .name = (char *) shortname,
1305 .owner = THIS_MODULE, 1305 .owner = THIS_MODULE,
1306 // .shutdown = ...
1307 // .suspend = ...
1308 // .resume = ...
1309 }, 1306 },
1310}; 1307};
1311 1308
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index 509dd0a04c54..5246b35301de 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -37,6 +37,16 @@ config USB_HIDINPUT
37 37
38 If unsure, say Y. 38 If unsure, say Y.
39 39
40config USB_HIDINPUT_POWERBOOK
41 bool "Enable support for iBook/PowerBook special keys"
42 default n
43 depends on USB_HIDINPUT
44 help
45 Say Y here if you want support for the special keys (Fn, Numlock) on
46 Apple iBooks and PowerBooks.
47
48 If unsure, say N.
49
40config HID_FF 50config HID_FF
41 bool "Force feedback support (EXPERIMENTAL)" 51 bool "Force feedback support (EXPERIMENTAL)"
42 depends on USB_HIDINPUT && EXPERIMENTAL 52 depends on USB_HIDINPUT && EXPERIMENTAL
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 5f52979af1c7..a91e72c41415 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1450,6 +1450,9 @@ void hid_init_reports(struct hid_device *hid)
1450#define USB_VENDOR_ID_APPLE 0x05ac 1450#define USB_VENDOR_ID_APPLE 0x05ac
1451#define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 1451#define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304
1452 1452
1453#define USB_VENDOR_ID_CHERRY 0x046a
1454#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
1455
1453/* 1456/*
1454 * Alphabetically sorted blacklist by quirk type. 1457 * Alphabetically sorted blacklist by quirk type.
1455 */ 1458 */
@@ -1580,6 +1583,16 @@ static const struct hid_blacklist {
1580 { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, 1583 { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
1581 { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, 1584 { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
1582 1585
1586 { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION },
1587
1588 { USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN },
1589 { USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN },
1590 { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN },
1591 { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN },
1592 { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN },
1593 { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN },
1594 { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN },
1595
1583 { 0, 0 } 1596 { 0, 0 }
1584}; 1597};
1585 1598
@@ -1626,6 +1639,20 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
1626 usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma); 1639 usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma);
1627} 1640}
1628 1641
1642/*
1643 * Cherry Cymotion keyboard have an invalid HID report descriptor,
1644 * that needs fixing before we can parse it.
1645 */
1646
1647static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize)
1648{
1649 if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
1650 info("Fixing up Cherry Cymotion report descriptor");
1651 rdesc[11] = rdesc[16] = 0xff;
1652 rdesc[12] = rdesc[17] = 0x03;
1653 }
1654}
1655
1629static struct hid_device *usb_hid_configure(struct usb_interface *intf) 1656static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1630{ 1657{
1631 struct usb_host_interface *interface = intf->cur_altsetting; 1658 struct usb_host_interface *interface = intf->cur_altsetting;
@@ -1673,6 +1700,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1673 return NULL; 1700 return NULL;
1674 } 1701 }
1675 1702
1703 if ((quirks & HID_QUIRK_CYMOTION))
1704 hid_fixup_cymotion_descriptor(rdesc, rsize);
1705
1676#ifdef DEBUG_DATA 1706#ifdef DEBUG_DATA
1677 printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); 1707 printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
1678 for (n = 0; n < rsize; n++) 1708 for (n = 0; n < rsize; n++)
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 192a03b28971..cb0d80f49252 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -73,6 +73,160 @@ static const struct {
73#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) 73#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0)
74#define map_ff_effect(c) do { set_bit(c, input->ffbit); } while (0) 74#define map_ff_effect(c) do { set_bit(c, input->ffbit); } while (0)
75 75
76#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
77
78struct hidinput_key_translation {
79 u16 from;
80 u16 to;
81 u8 flags;
82};
83
84#define POWERBOOK_FLAG_FKEY 0x01
85
86static struct hidinput_key_translation powerbook_fn_keys[] = {
87 { KEY_BACKSPACE, KEY_DELETE },
88 { KEY_F1, KEY_BRIGHTNESSDOWN, POWERBOOK_FLAG_FKEY },
89 { KEY_F2, KEY_BRIGHTNESSUP, POWERBOOK_FLAG_FKEY },
90 { KEY_F3, KEY_MUTE, POWERBOOK_FLAG_FKEY },
91 { KEY_F4, KEY_VOLUMEDOWN, POWERBOOK_FLAG_FKEY },
92 { KEY_F5, KEY_VOLUMEUP, POWERBOOK_FLAG_FKEY },
93 { KEY_F6, KEY_NUMLOCK, POWERBOOK_FLAG_FKEY },
94 { KEY_F7, KEY_SWITCHVIDEOMODE, POWERBOOK_FLAG_FKEY },
95 { KEY_F8, KEY_KBDILLUMTOGGLE, POWERBOOK_FLAG_FKEY },
96 { KEY_F9, KEY_KBDILLUMDOWN, POWERBOOK_FLAG_FKEY },
97 { KEY_F10, KEY_KBDILLUMUP, POWERBOOK_FLAG_FKEY },
98 { KEY_UP, KEY_PAGEUP },
99 { KEY_DOWN, KEY_PAGEDOWN },
100 { KEY_LEFT, KEY_HOME },
101 { KEY_RIGHT, KEY_END },
102 { }
103};
104
105static struct hidinput_key_translation powerbook_numlock_keys[] = {
106 { KEY_J, KEY_KP1 },
107 { KEY_K, KEY_KP2 },
108 { KEY_L, KEY_KP3 },
109 { KEY_U, KEY_KP4 },
110 { KEY_I, KEY_KP5 },
111 { KEY_O, KEY_KP6 },
112 { KEY_7, KEY_KP7 },
113 { KEY_8, KEY_KP8 },
114 { KEY_9, KEY_KP9 },
115 { KEY_M, KEY_KP0 },
116 { KEY_DOT, KEY_KPDOT },
117 { KEY_SLASH, KEY_KPPLUS },
118 { KEY_SEMICOLON, KEY_KPMINUS },
119 { KEY_P, KEY_KPASTERISK },
120 { KEY_MINUS, KEY_KPEQUAL },
121 { KEY_0, KEY_KPSLASH },
122 { KEY_F6, KEY_NUMLOCK },
123 { KEY_KPENTER, KEY_KPENTER },
124 { KEY_BACKSPACE, KEY_BACKSPACE },
125 { }
126};
127
128static int usbhid_pb_fnmode = 1;
129module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644);
130MODULE_PARM_DESC(pb_fnmode,
131 "Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)");
132
133static struct hidinput_key_translation *find_translation(struct hidinput_key_translation *table, u16 from)
134{
135 struct hidinput_key_translation *trans;
136
137 /* Look for the translation */
138 for (trans = table; trans->from; trans++)
139 if (trans->from == from)
140 return trans;
141
142 return NULL;
143}
144
145static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
146 struct hid_usage *usage, __s32 value)
147{
148 struct hidinput_key_translation *trans;
149
150 if (usage->code == KEY_FN) {
151 if (value) hid->quirks |= HID_QUIRK_POWERBOOK_FN_ON;
152 else hid->quirks &= ~HID_QUIRK_POWERBOOK_FN_ON;
153
154 input_event(input, usage->type, usage->code, value);
155
156 return 1;
157 }
158
159 if (usbhid_pb_fnmode) {
160 int do_translate;
161
162 trans = find_translation(powerbook_fn_keys, usage->code);
163 if (trans) {
164 if (test_bit(usage->code, hid->pb_pressed_fn))
165 do_translate = 1;
166 else if (trans->flags & POWERBOOK_FLAG_FKEY)
167 do_translate =
168 (usbhid_pb_fnmode == 2 && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) ||
169 (usbhid_pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON));
170 else
171 do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON);
172
173 if (do_translate) {
174 if (value)
175 set_bit(usage->code, hid->pb_pressed_fn);
176 else
177 clear_bit(usage->code, hid->pb_pressed_fn);
178
179 input_event(input, usage->type, trans->to, value);
180
181 return 1;
182 }
183 }
184
185 if (test_bit(usage->code, hid->pb_pressed_numlock) ||
186 test_bit(LED_NUML, input->led)) {
187 trans = find_translation(powerbook_numlock_keys, usage->code);
188
189 if (trans) {
190 if (value)
191 set_bit(usage->code, hid->pb_pressed_numlock);
192 else
193 clear_bit(usage->code, hid->pb_pressed_numlock);
194
195 input_event(input, usage->type, trans->to, value);
196 }
197
198 return 1;
199 }
200 }
201
202 return 0;
203}
204
205static void hidinput_pb_setup(struct input_dev *input)
206{
207 struct hidinput_key_translation *trans;
208
209 set_bit(KEY_NUMLOCK, input->keybit);
210
211 /* Enable all needed keys */
212 for (trans = powerbook_fn_keys; trans->from; trans++)
213 set_bit(trans->to, input->keybit);
214
215 for (trans = powerbook_numlock_keys; trans->from; trans++)
216 set_bit(trans->to, input->keybit);
217}
218#else
219static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
220 struct hid_usage *usage, __s32 value)
221{
222 return 0;
223}
224
225static inline void hidinput_pb_setup(struct input_dev *input)
226{
227}
228#endif
229
76static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, 230static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
77 struct hid_usage *usage) 231 struct hid_usage *usage)
78{ 232{
@@ -135,8 +289,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
135 case HID_UP_SIMULATION: 289 case HID_UP_SIMULATION:
136 290
137 switch (usage->hid & 0xffff) { 291 switch (usage->hid & 0xffff) {
138 case 0xba: map_abs(ABS_RUDDER); break; 292 case 0xba: map_abs(ABS_RUDDER); break;
139 case 0xbb: map_abs(ABS_THROTTLE); break; 293 case 0xbb: map_abs(ABS_THROTTLE); break;
294 case 0xc4: map_abs(ABS_GAS); break;
295 case 0xc5: map_abs(ABS_BRAKE); break;
296 case 0xc8: map_abs(ABS_WHEEL); break;
140 default: goto ignore; 297 default: goto ignore;
141 } 298 }
142 break; 299 break;
@@ -289,11 +446,19 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
289 case 0x226: map_key_clear(KEY_STOP); break; 446 case 0x226: map_key_clear(KEY_STOP); break;
290 case 0x227: map_key_clear(KEY_REFRESH); break; 447 case 0x227: map_key_clear(KEY_REFRESH); break;
291 case 0x22a: map_key_clear(KEY_BOOKMARKS); break; 448 case 0x22a: map_key_clear(KEY_BOOKMARKS); break;
449 case 0x233: map_key_clear(KEY_SCROLLUP); break;
450 case 0x234: map_key_clear(KEY_SCROLLDOWN); break;
292 case 0x238: map_rel(REL_HWHEEL); break; 451 case 0x238: map_rel(REL_HWHEEL); break;
293 case 0x279: map_key_clear(KEY_REDO); break; 452 case 0x279: map_key_clear(KEY_REDO); break;
294 case 0x289: map_key_clear(KEY_REPLY); break; 453 case 0x289: map_key_clear(KEY_REPLY); break;
295 case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; 454 case 0x28b: map_key_clear(KEY_FORWARDMAIL); break;
296 case 0x28c: map_key_clear(KEY_SEND); break; 455 case 0x28c: map_key_clear(KEY_SEND); break;
456
457 /* Reported on a Cherry Cymotion keyboard */
458 case 0x301: map_key_clear(KEY_PROG1); break;
459 case 0x302: map_key_clear(KEY_PROG2); break;
460 case 0x303: map_key_clear(KEY_PROG3); break;
461
297 default: goto ignore; 462 default: goto ignore;
298 } 463 }
299 break; 464 break;
@@ -325,7 +490,12 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
325 490
326 set_bit(EV_REP, input->evbit); 491 set_bit(EV_REP, input->evbit);
327 switch(usage->hid & HID_USAGE) { 492 switch(usage->hid & HID_USAGE) {
328 case 0x003: map_key_clear(KEY_FN); break; 493 case 0x003:
494 /* The fn key on Apple PowerBooks */
495 map_key_clear(KEY_FN);
496 hidinput_pb_setup(input);
497 break;
498
329 default: goto ignore; 499 default: goto ignore;
330 } 500 }
331 break; 501 break;
@@ -482,6 +652,9 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
482 return; 652 return;
483 } 653 }
484 654
655 if ((hid->quirks & HID_QUIRK_POWERBOOK_HAS_FN) && hidinput_pb_event(hid, input, usage, value))
656 return;
657
485 if (usage->hat_min < usage->hat_max || usage->hat_dir) { 658 if (usage->hat_min < usage->hat_max || usage->hat_dir) {
486 int hat_dir = usage->hat_dir; 659 int hat_dir = usage->hat_dir;
487 if (!hat_dir) 660 if (!hat_dir)
@@ -524,7 +697,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
524 return; 697 return;
525 } 698 }
526 699
527 if((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */ 700 if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */
528 return; 701 return;
529 702
530 input_event(input, usage->type, usage->code, value); 703 input_event(input, usage->type, usage->code, value);
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
index ee48a2276104..8b0d4346ce9c 100644
--- a/drivers/usb/input/hid.h
+++ b/drivers/usb/input/hid.h
@@ -235,17 +235,20 @@ struct hid_item {
235 * HID device quirks. 235 * HID device quirks.
236 */ 236 */
237 237
238#define HID_QUIRK_INVERT 0x001 238#define HID_QUIRK_INVERT 0x00000001
239#define HID_QUIRK_NOTOUCH 0x002 239#define HID_QUIRK_NOTOUCH 0x00000002
240#define HID_QUIRK_IGNORE 0x004 240#define HID_QUIRK_IGNORE 0x00000004
241#define HID_QUIRK_NOGET 0x008 241#define HID_QUIRK_NOGET 0x00000008
242#define HID_QUIRK_HIDDEV 0x010 242#define HID_QUIRK_HIDDEV 0x00000010
243#define HID_QUIRK_BADPAD 0x020 243#define HID_QUIRK_BADPAD 0x00000020
244#define HID_QUIRK_MULTI_INPUT 0x040 244#define HID_QUIRK_MULTI_INPUT 0x00000040
245#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x080 245#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080
246#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100 246#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100
247#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200 247#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200
248#define HID_QUIRK_2WHEEL_POWERMOUSE 0x400 248#define HID_QUIRK_2WHEEL_POWERMOUSE 0x00000400
249#define HID_QUIRK_CYMOTION 0x00000800
250#define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000
251#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000
249 252
250/* 253/*
251 * This is the global environment of the parser. This information is 254 * This is the global environment of the parser. This information is
@@ -431,6 +434,11 @@ struct hid_device { /* device report descriptor */
431 void (*ff_exit)(struct hid_device*); /* Called by hid_exit_ff(hid) */ 434 void (*ff_exit)(struct hid_device*); /* Called by hid_exit_ff(hid) */
432 int (*ff_event)(struct hid_device *hid, struct input_dev *input, 435 int (*ff_event)(struct hid_device *hid, struct input_dev *input,
433 unsigned int type, unsigned int code, int value); 436 unsigned int type, unsigned int code, int value);
437
438#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
439 unsigned long pb_pressed_fn[NBITS(KEY_MAX)];
440 unsigned long pb_pressed_numlock[NBITS(KEY_MAX)];
441#endif
434}; 442};
435 443
436#define HID_GLOBAL_STACK_SIZE 4 444#define HID_GLOBAL_STACK_SIZE 4
diff --git a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c
index 19e015d171aa..d9d9f656b8c9 100644
--- a/drivers/usb/input/pid.c
+++ b/drivers/usb/input/pid.c
@@ -259,7 +259,7 @@ static int hid_pid_upload_effect(struct input_dev *dev,
259int hid_pid_init(struct hid_device *hid) 259int hid_pid_init(struct hid_device *hid)
260{ 260{
261 struct hid_ff_pid *private; 261 struct hid_ff_pid *private;
262 struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list); 262 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
263 struct input_dev *input_dev = hidinput->input; 263 struct input_dev *input_dev = hidinput->input;
264 264
265 private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL); 265 private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL);
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
index 48df4cfd5a42..d3e15df9e815 100644
--- a/drivers/usb/input/wacom.c
+++ b/drivers/usb/input/wacom.c
@@ -95,7 +95,7 @@ MODULE_LICENSE(DRIVER_LICENSE);
95enum { 95enum {
96 PENPARTNER = 0, 96 PENPARTNER = 0,
97 GRAPHIRE, 97 GRAPHIRE,
98 G4, 98 WACOM_G4,
99 PL, 99 PL,
100 INTUOS, 100 INTUOS,
101 INTUOS3, 101 INTUOS3,
@@ -373,7 +373,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
373 373
374 case 2: /* Mouse with wheel */ 374 case 2: /* Mouse with wheel */
375 input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); 375 input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
376 if (wacom->features->type == G4) { 376 if (wacom->features->type == WACOM_G4) {
377 rw = data[7] & 0x04 ? -(data[7] & 0x03) : (data[7] & 0x03); 377 rw = data[7] & 0x04 ? -(data[7] & 0x03) : (data[7] & 0x03);
378 input_report_rel(dev, REL_WHEEL, rw); 378 input_report_rel(dev, REL_WHEEL, rw);
379 } else 379 } else
@@ -385,7 +385,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
385 id = CURSOR_DEVICE_ID; 385 id = CURSOR_DEVICE_ID;
386 input_report_key(dev, BTN_LEFT, data[1] & 0x01); 386 input_report_key(dev, BTN_LEFT, data[1] & 0x01);
387 input_report_key(dev, BTN_RIGHT, data[1] & 0x02); 387 input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
388 if (wacom->features->type == G4) 388 if (wacom->features->type == WACOM_G4)
389 input_report_abs(dev, ABS_DISTANCE, data[6]); 389 input_report_abs(dev, ABS_DISTANCE, data[6]);
390 else 390 else
391 input_report_abs(dev, ABS_DISTANCE, data[7]); 391 input_report_abs(dev, ABS_DISTANCE, data[7]);
@@ -410,7 +410,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
410 input_sync(dev); 410 input_sync(dev);
411 411
412 /* send pad data */ 412 /* send pad data */
413 if (wacom->features->type == G4) { 413 if (wacom->features->type == WACOM_G4) {
414 /* fist time sending pad data */ 414 /* fist time sending pad data */
415 if (wacom->tool[1] != BTN_TOOL_FINGER) { 415 if (wacom->tool[1] != BTN_TOOL_FINGER) {
416 wacom->id[1] = 0; 416 wacom->id[1] = 0;
@@ -713,8 +713,8 @@ static struct wacom_features wacom_features[] = {
713 { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_graphire_irq }, 713 { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_graphire_irq },
714 { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_graphire_irq }, 714 { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_graphire_irq },
715 { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_graphire_irq }, 715 { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_graphire_irq },
716 { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 32, G4, wacom_graphire_irq }, 716 { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 32, WACOM_G4, wacom_graphire_irq },
717 { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 32, G4, wacom_graphire_irq }, 717 { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 32, WACOM_G4, wacom_graphire_irq },
718 { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq }, 718 { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq },
719 { "Wacom PenStation2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_graphire_irq }, 719 { "Wacom PenStation2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_graphire_irq },
720 { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq }, 720 { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq },
@@ -859,7 +859,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
859 input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0); 859 input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0);
860 860
861 switch (wacom->features->type) { 861 switch (wacom->features->type) {
862 case G4: 862 case WACOM_G4:
863 input_dev->evbit[0] |= BIT(EV_MSC); 863 input_dev->evbit[0] |= BIT(EV_MSC);
864 input_dev->mscbit[0] |= BIT(MSC_SERIAL); 864 input_dev->mscbit[0] |= BIT(MSC_SERIAL);
865 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); 865 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index 664139afcfa9..e9f9f4bafa17 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -37,11 +37,6 @@ static int usb_serial_device_match (struct device *dev, struct device_driver *dr
37 return 0; 37 return 0;
38} 38}
39 39
40struct bus_type usb_serial_bus_type = {
41 .name = "usb-serial",
42 .match = usb_serial_device_match,
43};
44
45static int usb_serial_device_probe (struct device *dev) 40static int usb_serial_device_probe (struct device *dev)
46{ 41{
47 struct usb_serial_driver *driver; 42 struct usb_serial_driver *driver;
@@ -109,14 +104,18 @@ exit:
109 return retval; 104 return retval;
110} 105}
111 106
107struct bus_type usb_serial_bus_type = {
108 .name = "usb-serial",
109 .match = usb_serial_device_match,
110 .probe = usb_serial_device_probe,
111 .remove = usb_serial_device_remove,
112};
113
112int usb_serial_bus_register(struct usb_serial_driver *driver) 114int usb_serial_bus_register(struct usb_serial_driver *driver)
113{ 115{
114 int retval; 116 int retval;
115 117
116 driver->driver.bus = &usb_serial_bus_type; 118 driver->driver.bus = &usb_serial_bus_type;
117 driver->driver.probe = usb_serial_device_probe;
118 driver->driver.remove = usb_serial_device_remove;
119
120 retval = driver_register(&driver->driver); 119 retval = driver_register(&driver->driver);
121 120
122 return retval; 121 return retval;
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 9ffff1938239..0eb883f44ada 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -43,8 +43,6 @@ static int debug;
43#define PL2303_BUF_SIZE 1024 43#define PL2303_BUF_SIZE 1024
44#define PL2303_TMP_BUF_SIZE 1024 44#define PL2303_TMP_BUF_SIZE 1024
45 45
46static DECLARE_MUTEX(pl2303_tmp_buf_sem);
47
48struct pl2303_buf { 46struct pl2303_buf {
49 unsigned int buf_size; 47 unsigned int buf_size;
50 char *buf_buf; 48 char *buf_buf;
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index d549e215f3c5..2c42a812655a 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -590,6 +590,8 @@ static u_short maxfmode, chipset;
590#define highw(x) ((u_long)(x)>>16 & 0xffff) 590#define highw(x) ((u_long)(x)>>16 & 0xffff)
591#define loww(x) ((u_long)(x) & 0xffff) 591#define loww(x) ((u_long)(x) & 0xffff)
592 592
593#define custom amiga_custom
594
593#define VBlankOn() custom.intena = IF_SETCLR|IF_COPER 595#define VBlankOn() custom.intena = IF_SETCLR|IF_COPER
594#define VBlankOff() custom.intena = IF_COPER 596#define VBlankOff() custom.intena = IF_COPER
595 597
@@ -1164,8 +1166,8 @@ static void ami_update_display(void);
1164static void ami_init_display(void); 1166static void ami_init_display(void);
1165static void ami_do_blank(void); 1167static void ami_do_blank(void);
1166static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix); 1168static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix);
1167static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data); 1169static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data);
1168static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data); 1170static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data);
1169static int ami_get_cursorstate(struct fb_cursorstate *state); 1171static int ami_get_cursorstate(struct fb_cursorstate *state);
1170static int ami_set_cursorstate(struct fb_cursorstate *state); 1172static int ami_set_cursorstate(struct fb_cursorstate *state);
1171static void ami_set_sprite(void); 1173static void ami_set_sprite(void);
@@ -2179,6 +2181,7 @@ static int amifb_ioctl(struct inode *inode, struct file *file,
2179 struct fb_var_cursorinfo var; 2181 struct fb_var_cursorinfo var;
2180 struct fb_cursorstate state; 2182 struct fb_cursorstate state;
2181 } crsr; 2183 } crsr;
2184 void __user *argp = (void __user *)arg;
2182 int i; 2185 int i;
2183 2186
2184 switch (cmd) { 2187 switch (cmd) {
@@ -2186,33 +2189,32 @@ static int amifb_ioctl(struct inode *inode, struct file *file,
2186 i = ami_get_fix_cursorinfo(&crsr.fix); 2189 i = ami_get_fix_cursorinfo(&crsr.fix);
2187 if (i) 2190 if (i)
2188 return i; 2191 return i;
2189 return copy_to_user((void *)arg, &crsr.fix, 2192 return copy_to_user(argp, &crsr.fix,
2190 sizeof(crsr.fix)) ? -EFAULT : 0; 2193 sizeof(crsr.fix)) ? -EFAULT : 0;
2191 2194
2192 case FBIOGET_VCURSORINFO: 2195 case FBIOGET_VCURSORINFO:
2193 i = ami_get_var_cursorinfo(&crsr.var, 2196 i = ami_get_var_cursorinfo(&crsr.var,
2194 ((struct fb_var_cursorinfo *)arg)->data); 2197 ((struct fb_var_cursorinfo __user *)arg)->data);
2195 if (i) 2198 if (i)
2196 return i; 2199 return i;
2197 return copy_to_user((void *)arg, &crsr.var, 2200 return copy_to_user(argp, &crsr.var,
2198 sizeof(crsr.var)) ? -EFAULT : 0; 2201 sizeof(crsr.var)) ? -EFAULT : 0;
2199 2202
2200 case FBIOPUT_VCURSORINFO: 2203 case FBIOPUT_VCURSORINFO:
2201 if (copy_from_user(&crsr.var, (void *)arg, 2204 if (copy_from_user(&crsr.var, argp, sizeof(crsr.var)))
2202 sizeof(crsr.var)))
2203 return -EFAULT; 2205 return -EFAULT;
2204 return ami_set_var_cursorinfo(&crsr.var, 2206 return ami_set_var_cursorinfo(&crsr.var,
2205 ((struct fb_var_cursorinfo *)arg)->data); 2207 ((struct fb_var_cursorinfo __user *)arg)->data);
2206 2208
2207 case FBIOGET_CURSORSTATE: 2209 case FBIOGET_CURSORSTATE:
2208 i = ami_get_cursorstate(&crsr.state); 2210 i = ami_get_cursorstate(&crsr.state);
2209 if (i) 2211 if (i)
2210 return i; 2212 return i;
2211 return copy_to_user((void *)arg, &crsr.state, 2213 return copy_to_user(argp, &crsr.state,
2212 sizeof(crsr.state)) ? -EFAULT : 0; 2214 sizeof(crsr.state)) ? -EFAULT : 0;
2213 2215
2214 case FBIOPUT_CURSORSTATE: 2216 case FBIOPUT_CURSORSTATE:
2215 if (copy_from_user(&crsr.state, (void *)arg, 2217 if (copy_from_user(&crsr.state, argp,
2216 sizeof(crsr.state))) 2218 sizeof(crsr.state)))
2217 return -EFAULT; 2219 return -EFAULT;
2218 return ami_set_cursorstate(&crsr.state); 2220 return ami_set_cursorstate(&crsr.state);
@@ -3325,7 +3327,7 @@ static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix)
3325 return 0; 3327 return 0;
3326} 3328}
3327 3329
3328static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data) 3330static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data)
3329{ 3331{
3330 struct amifb_par *par = &currentpar; 3332 struct amifb_par *par = &currentpar;
3331 register u_short *lspr, *sspr; 3333 register u_short *lspr, *sspr;
@@ -3347,14 +3349,14 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
3347 var->yspot = par->crsr.spot_y; 3349 var->yspot = par->crsr.spot_y;
3348 if (size > var->height*var->width) 3350 if (size > var->height*var->width)
3349 return -ENAMETOOLONG; 3351 return -ENAMETOOLONG;
3350 if (!access_ok(VERIFY_WRITE, (void *)data, size)) 3352 if (!access_ok(VERIFY_WRITE, data, size))
3351 return -EFAULT; 3353 return -EFAULT;
3352 delta = 1<<par->crsr.fmode; 3354 delta = 1<<par->crsr.fmode;
3353 lspr = lofsprite + (delta<<1); 3355 lspr = lofsprite + (delta<<1);
3354 if (par->bplcon0 & BPC0_LACE) 3356 if (par->bplcon0 & BPC0_LACE)
3355 sspr = shfsprite + (delta<<1); 3357 sspr = shfsprite + (delta<<1);
3356 else 3358 else
3357 sspr = 0; 3359 sspr = NULL;
3358 for (height = (short)var->height-1; height >= 0; height--) { 3360 for (height = (short)var->height-1; height >= 0; height--) {
3359 bits = 0; words = delta; datawords = 0; 3361 bits = 0; words = delta; datawords = 0;
3360 for (width = (short)var->width-1; width >= 0; width--) { 3362 for (width = (short)var->width-1; width >= 0; width--) {
@@ -3400,7 +3402,7 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
3400 return 0; 3402 return 0;
3401} 3403}
3402 3404
3403static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data) 3405static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data)
3404{ 3406{
3405 struct amifb_par *par = &currentpar; 3407 struct amifb_par *par = &currentpar;
3406 register u_short *lspr, *sspr; 3408 register u_short *lspr, *sspr;
@@ -3427,7 +3429,7 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
3427 return -EINVAL; 3429 return -EINVAL;
3428 if (!var->height) 3430 if (!var->height)
3429 return -EINVAL; 3431 return -EINVAL;
3430 if (!access_ok(VERIFY_READ, (void *)data, var->width*var->height)) 3432 if (!access_ok(VERIFY_READ, data, var->width*var->height))
3431 return -EFAULT; 3433 return -EFAULT;
3432 delta = 1<<fmode; 3434 delta = 1<<fmode;
3433 lofsprite = shfsprite = (u_short *)spritememory; 3435 lofsprite = shfsprite = (u_short *)spritememory;
@@ -3442,13 +3444,13 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
3442 if (((var->height+2)<<fmode<<2) > SPRITEMEMSIZE) 3444 if (((var->height+2)<<fmode<<2) > SPRITEMEMSIZE)
3443 return -EINVAL; 3445 return -EINVAL;
3444 memset(lspr, 0, (var->height+2)<<fmode<<2); 3446 memset(lspr, 0, (var->height+2)<<fmode<<2);
3445 sspr = 0; 3447 sspr = NULL;
3446 } 3448 }
3447 for (height = (short)var->height-1; height >= 0; height--) { 3449 for (height = (short)var->height-1; height >= 0; height--) {
3448 bits = 16; words = delta; datawords = 0; 3450 bits = 16; words = delta; datawords = 0;
3449 for (width = (short)var->width-1; width >= 0; width--) { 3451 for (width = (short)var->width-1; width >= 0; width--) {
3450 unsigned long tdata = 0; 3452 unsigned long tdata = 0;
3451 get_user(tdata, (char *)data); 3453 get_user(tdata, data);
3452 data++; 3454 data++;
3453#ifdef __mc68000__ 3455#ifdef __mc68000__
3454 asm volatile ( 3456 asm volatile (
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index e370125e4fbc..ed81005cbdba 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -3501,7 +3501,7 @@ err_release_mem:
3501 3501
3502static int __devinit atyfb_atari_probe(void) 3502static int __devinit atyfb_atari_probe(void)
3503{ 3503{
3504 struct aty_par *par; 3504 struct atyfb_par *par;
3505 struct fb_info *info; 3505 struct fb_info *info;
3506 int m64_num; 3506 int m64_num;
3507 u32 clock_r; 3507 u32 clock_r;
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index cfc748e94272..e6cbd9de944a 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -609,18 +609,19 @@ void __init macfb_setup(char *options)
609 } 609 }
610} 610}
611 611
612void __init macfb_init(void) 612static int __init macfb_init(void)
613{ 613{
614 int video_cmap_len, video_is_nubus = 0; 614 int video_cmap_len, video_is_nubus = 0;
615 struct nubus_dev* ndev = NULL; 615 struct nubus_dev* ndev = NULL;
616 char *option = NULL; 616 char *option = NULL;
617 int err;
617 618
618 if (fb_get_options("macfb", &option)) 619 if (fb_get_options("macfb", &option))
619 return -ENODEV; 620 return -ENODEV;
620 macfb_setup(option); 621 macfb_setup(option);
621 622
622 if (!MACH_IS_MAC) 623 if (!MACH_IS_MAC)
623 return; 624 return -ENODEV;
624 625
625 /* There can only be one internal video controller anyway so 626 /* There can only be one internal video controller anyway so
626 we're not too worried about this */ 627 we're not too worried about this */
@@ -958,11 +959,11 @@ void __init macfb_init(void)
958 959
959 fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0); 960 fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
960 961
961 if (register_framebuffer(&fb_info) < 0) 962 err = register_framebuffer(&fb_info);
962 return; 963 if (!err)
963 964 printk("fb%d: %s frame buffer device\n",
964 printk("fb%d: %s frame buffer device\n", 965 fb_info.node, fb_info.fix.id);
965 fb_info.node, fb_info.fix.id); 966 return err;
966} 967}
967 968
968module_init(macfb_init); 969module_init(macfb_init);
diff --git a/drivers/zorro/proc.c b/drivers/zorro/proc.c
index 1a409c2c320c..7aa2d3de6d37 100644
--- a/drivers/zorro/proc.c
+++ b/drivers/zorro/proc.c
@@ -45,7 +45,7 @@ proc_bus_zorro_lseek(struct file *file, loff_t off, int whence)
45} 45}
46 46
47static ssize_t 47static ssize_t
48proc_bus_zorro_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) 48proc_bus_zorro_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
49{ 49{
50 struct inode *ino = file->f_dentry->d_inode; 50 struct inode *ino = file->f_dentry->d_inode;
51 struct proc_dir_entry *dp = PDE(ino); 51 struct proc_dir_entry *dp = PDE(ino);
diff --git a/drivers/zorro/zorro-driver.c b/drivers/zorro/zorro-driver.c
index ccba227676f2..fcbee748c592 100644
--- a/drivers/zorro/zorro-driver.c
+++ b/drivers/zorro/zorro-driver.c
@@ -77,7 +77,6 @@ int zorro_register_driver(struct zorro_driver *drv)
77 /* initialize common driver fields */ 77 /* initialize common driver fields */
78 drv->driver.name = drv->name; 78 drv->driver.name = drv->name;
79 drv->driver.bus = &zorro_bus_type; 79 drv->driver.bus = &zorro_bus_type;
80 drv->driver.probe = zorro_device_probe;
81 80
82 /* register with core */ 81 /* register with core */
83 count = driver_register(&drv->driver); 82 count = driver_register(&drv->driver);
@@ -132,7 +131,8 @@ static int zorro_bus_match(struct device *dev, struct device_driver *drv)
132 131
133struct bus_type zorro_bus_type = { 132struct bus_type zorro_bus_type = {
134 .name = "zorro", 133 .name = "zorro",
135 .match = zorro_bus_match 134 .match = zorro_bus_match,
135 .probe = zorro_device_probe,
136}; 136};
137 137
138 138