aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/processor_idle.c2
-rw-r--r--drivers/acpi/scan.c4
-rw-r--r--drivers/atm/eni.c27
-rw-r--r--drivers/atm/fore200e.c4
-rw-r--r--drivers/atm/he.c3
-rw-r--r--drivers/atm/he.h2
-rw-r--r--drivers/base/bus.c5
-rw-r--r--drivers/base/core.c2
-rw-r--r--drivers/base/platform.c4
-rw-r--r--drivers/block/DAC960.c132
-rw-r--r--drivers/block/DAC960.h317
-rw-r--r--drivers/block/Kconfig4
-rw-r--r--drivers/block/aoe/aoe.h2
-rw-r--r--drivers/block/aoe/aoeblk.c13
-rw-r--r--drivers/block/aoe/aoedev.c11
-rw-r--r--drivers/block/aoe/aoenet.c17
-rw-r--r--drivers/block/floppy.c2
-rw-r--r--drivers/block/genhd.c4
-rw-r--r--drivers/block/nbd.c16
-rw-r--r--drivers/block/noop-iosched.c27
-rw-r--r--drivers/cdrom/cdrom.c2
-rw-r--r--drivers/cdrom/cdu31a.c6
-rw-r--r--drivers/cdrom/mcdx.c28
-rw-r--r--drivers/cdrom/sbpcd.c2
-rw-r--r--drivers/char/Kconfig20
-rw-r--r--drivers/char/Makefile3
-rw-r--r--drivers/char/agp/ali-agp.c4
-rw-r--r--drivers/char/agp/amd-k7-agp.c2
-rw-r--r--drivers/char/agp/amd64-agp.c2
-rw-r--r--drivers/char/agp/ati-agp.c2
-rw-r--r--drivers/char/agp/backend.c4
-rw-r--r--drivers/char/agp/efficeon-agp.c2
-rw-r--r--drivers/char/agp/frontend.c6
-rw-r--r--drivers/char/agp/nvidia-agp.c2
-rw-r--r--drivers/char/agp/sis-agp.c2
-rw-r--r--drivers/char/agp/sworks-agp.c2
-rw-r--r--drivers/char/agp/via-agp.c4
-rw-r--r--drivers/char/dtlk.c2
-rw-r--r--drivers/char/hangcheck-timer.c104
-rw-r--r--drivers/char/ipmi/ipmi_bt_sm.c1
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c36
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c97
-rw-r--r--drivers/char/ipmi/ipmi_si_sm.h2
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c2
-rw-r--r--drivers/char/keyboard.c3
-rw-r--r--drivers/char/mbcs.c849
-rw-r--r--drivers/char/mbcs.h553
-rw-r--r--drivers/char/rio/rio_linux.c2
-rw-r--r--drivers/char/s3c2410-rtc.c8
-rw-r--r--drivers/char/snsc.c8
-rw-r--r--drivers/char/snsc.h40
-rw-r--r--drivers/char/snsc_event.c304
-rw-r--r--drivers/char/sonypi.c6
-rw-r--r--drivers/char/specialix.c11
-rw-r--r--drivers/char/stallion.c4
-rw-r--r--drivers/char/tpm/tpm.c6
-rw-r--r--drivers/char/tty_io.c2
-rw-r--r--drivers/char/vt_ioctl.c3
-rw-r--r--drivers/cpufreq/cpufreq.c97
-rw-r--r--drivers/i2c/busses/Kconfig2
-rw-r--r--drivers/i2c/busses/i2c-mpc.c4
-rw-r--r--drivers/ide/pci/sis5513.c6
-rw-r--r--drivers/ide/ppc/pmac.c7
-rw-r--r--drivers/ieee1394/ohci1394.c69
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.c2
-rw-r--r--drivers/input/joystick/spaceorb.c2
-rw-r--r--drivers/input/keyboard/atkbd.c2
-rw-r--r--drivers/isdn/capi/capi.c10
-rw-r--r--drivers/isdn/capi/kcapi_proc.c10
-rw-r--r--drivers/isdn/divert/isdn_divert.c10
-rw-r--r--drivers/isdn/hisax/hfc4s8s_l1.c1
-rw-r--r--drivers/macintosh/adbhid.c40
-rw-r--r--drivers/macintosh/via-pmu.c9
-rw-r--r--drivers/md/dm-crypt.c19
-rw-r--r--drivers/md/dm-emc.c6
-rw-r--r--drivers/md/dm-hw-handler.c2
-rw-r--r--drivers/md/dm-mpath.c32
-rw-r--r--drivers/md/dm-path-selector.c2
-rw-r--r--drivers/md/dm-table.c2
-rw-r--r--drivers/md/dm-zero.c4
-rw-r--r--drivers/md/dm.c96
-rw-r--r--drivers/md/md.c14
-rw-r--r--drivers/md/multipath.c5
-rw-r--r--drivers/md/raid1.c2
-rw-r--r--drivers/md/raid10.c2
-rw-r--r--drivers/md/raid5.c2
-rw-r--r--drivers/md/raid6main.c2
-rw-r--r--drivers/media/common/ir-common.c18
-rw-r--r--drivers/media/dvb/frontends/cx22702.c15
-rw-r--r--drivers/media/dvb/frontends/cx22702.h3
-rw-r--r--drivers/media/video/Kconfig1
-rw-r--r--drivers/media/video/bttv-driver.c6
-rw-r--r--drivers/media/video/bttv-i2c.c14
-rw-r--r--drivers/media/video/cx88/cx88-core.c5
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c16
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c4
-rw-r--r--drivers/media/video/cx88/cx88-vbi.c6
-rw-r--r--drivers/media/video/cx88/cx88-video.c12
-rw-r--r--drivers/media/video/cx88/cx88.h4
-rw-r--r--drivers/media/video/msp3400.c28
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c89
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c21
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c20
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c1
-rw-r--r--drivers/media/video/tuner-core.c14
-rw-r--r--drivers/media/video/tvaudio.c2
-rw-r--r--drivers/mmc/Kconfig2
-rw-r--r--drivers/net/3c59x.c9
-rw-r--r--drivers/net/Kconfig10
-rw-r--r--drivers/net/Space.c2
-rw-r--r--drivers/net/appletalk/Kconfig2
-rw-r--r--drivers/net/appletalk/cops.c4
-rw-r--r--drivers/net/appletalk/cops_ffdrv.h2
-rw-r--r--drivers/net/appletalk/cops_ltdrv.h2
-rw-r--r--drivers/net/appletalk/ltpc.c2
-rw-r--r--drivers/net/arcnet/capmode.c2
-rw-r--r--drivers/net/gt96100eth.h4
-rw-r--r--drivers/net/hamradio/6pack.c4
-rw-r--r--drivers/net/hamradio/Kconfig4
-rw-r--r--drivers/net/hamradio/baycom_epp.c4
-rw-r--r--drivers/net/hamradio/bpqether.c10
-rw-r--r--drivers/net/hamradio/dmascc.c4
-rw-r--r--drivers/net/hamradio/hdlcdrv.c4
-rw-r--r--drivers/net/hamradio/mkiss.c4
-rw-r--r--drivers/net/hamradio/scc.c5
-rw-r--r--drivers/net/hamradio/yam.c4
-rw-r--r--drivers/net/hp100.c4
-rw-r--r--drivers/net/irda/Kconfig10
-rw-r--r--drivers/net/loopback.c2
-rw-r--r--drivers/net/mv643xx_eth.c4
-rw-r--r--drivers/net/ppp_deflate.c6
-rw-r--r--drivers/net/ppp_generic.c12
-rw-r--r--drivers/net/r8169.c2
-rw-r--r--drivers/net/slip.c30
-rw-r--r--drivers/net/sunbmac.c13
-rw-r--r--drivers/net/sunhme.c16
-rw-r--r--drivers/net/sunlance.c17
-rw-r--r--drivers/net/sunqe.c17
-rw-r--r--drivers/net/tg3.c662
-rw-r--r--drivers/net/tg3.h25
-rw-r--r--drivers/net/wan/Kconfig6
-rw-r--r--drivers/net/wan/cycx_x25.c8
-rw-r--r--drivers/net/wan/pc300_drv.c22
-rw-r--r--drivers/net/wan/pc300_tty.c27
-rw-r--r--drivers/net/wan/sdla_chdlc.c13
-rw-r--r--drivers/net/wan/x25_asy.c20
-rw-r--r--drivers/oprofile/oprofile_files.c4
-rw-r--r--drivers/parport/Kconfig2
-rw-r--r--drivers/parport/parport_pc.c34
-rw-r--r--drivers/pci/hotplug.c4
-rw-r--r--drivers/pci/hotplug/ibmphp.h2
-rw-r--r--drivers/pci/hotplug/ibmphp_hpc.c6
-rw-r--r--drivers/pci/hotplug/ibmphp_pci.c7
-rw-r--r--drivers/pci/hotplug/pci_hotplug.h2
-rw-r--r--drivers/pci/hotplug/pciehp_core.c23
-rw-r--r--drivers/pci/hotplug/pcihp_skeleton.c2
-rw-r--r--drivers/pci/msi.c6
-rw-r--r--drivers/pci/pci-acpi.c2
-rw-r--r--drivers/pci/pci-driver.c11
-rw-r--r--drivers/pci/pci-sysfs.c82
-rw-r--r--drivers/pci/pci.c20
-rw-r--r--drivers/pci/probe.c1
-rw-r--r--drivers/pci/proc.c1
-rw-r--r--drivers/pci/quirks.c2
-rw-r--r--drivers/pci/rom.c14
-rw-r--r--drivers/pcmcia/pd6729.c2
-rw-r--r--drivers/pcmcia/ti113x.h40
-rw-r--r--drivers/pnp/manager.c2
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c4
-rw-r--r--drivers/pnp/pnpbios/rsparser.c4
-rw-r--r--drivers/s390/block/dasd.c21
-rw-r--r--drivers/s390/block/dasd_cmb.c19
-rw-r--r--drivers/s390/block/dasd_devmap.c59
-rw-r--r--drivers/s390/block/dasd_eckd.c5
-rw-r--r--drivers/s390/block/dasd_genhd.c10
-rw-r--r--drivers/s390/block/dasd_int.h7
-rw-r--r--drivers/s390/block/dasd_ioctl.c31
-rw-r--r--drivers/s390/block/dasd_proc.c8
-rw-r--r--drivers/s390/cio/airq.c4
-rw-r--r--drivers/s390/cio/cio.c4
-rw-r--r--drivers/s390/cio/device_ops.c6
-rw-r--r--drivers/s390/cio/qdio.h6
-rw-r--r--drivers/s390/crypto/z90main.c140
-rw-r--r--drivers/s390/net/smsgiucv.c19
-rw-r--r--drivers/s390/net/smsgiucv.h4
-rw-r--r--drivers/sbus/char/rtc.c109
-rw-r--r--drivers/scsi/Kconfig12
-rw-r--r--drivers/scsi/NCR53C9x.c5
-rw-r--r--drivers/scsi/aacraid/linit.c2
-rw-r--r--drivers/scsi/esp.c11
-rw-r--r--drivers/scsi/pas16.c6
-rw-r--r--drivers/scsi/pluto.c2
-rw-r--r--drivers/scsi/scsi.c2
-rw-r--r--drivers/scsi/scsi_error.c2
-rw-r--r--drivers/scsi/scsi_scan.c2
-rw-r--r--drivers/scsi/scsi_transport_spi.c49
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c5
-rw-r--r--drivers/serial/21285.c2
-rw-r--r--drivers/serial/8250.c2
-rw-r--r--drivers/serial/8250_hp300.c53
-rw-r--r--drivers/serial/8250_pci.c2
-rw-r--r--drivers/serial/amba-pl010.c2
-rw-r--r--drivers/serial/amba-pl011.c2
-rw-r--r--drivers/serial/clps711x.c65
-rw-r--r--drivers/serial/imx.c68
-rw-r--r--drivers/serial/ioc4_serial.c50
-rw-r--r--drivers/serial/jsm/jsm.h1
-rw-r--r--drivers/serial/jsm/jsm_neo.c2
-rw-r--r--drivers/serial/jsm/jsm_tty.c4
-rw-r--r--drivers/serial/mpsc.c14
-rw-r--r--drivers/serial/mpsc.h10
-rw-r--r--drivers/serial/s3c2410.c2
-rw-r--r--drivers/serial/sa1100.c65
-rw-r--r--drivers/serial/serial_cs.c173
-rw-r--r--drivers/serial/serial_lh7a40x.c2
-rw-r--r--drivers/serial/sn_console.c4
-rw-r--r--drivers/serial/sunsab.c16
-rw-r--r--drivers/serial/sunsu.c11
-rw-r--r--drivers/telephony/ixj.c18
-rw-r--r--drivers/telephony/ixj.h2
-rw-r--r--drivers/usb/core/message.c4
-rw-r--r--drivers/usb/core/urb.c6
-rw-r--r--drivers/usb/core/usb.c6
-rw-r--r--drivers/usb/gadget/ether.c2
-rw-r--r--drivers/usb/gadget/inode.c2
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c2
-rw-r--r--drivers/usb/gadget/serial.c2
-rw-r--r--drivers/usb/host/ehci-hcd.c65
-rw-r--r--drivers/usb/host/ehci-hub.c2
-rw-r--r--drivers/usb/host/ehci.h19
-rw-r--r--drivers/usb/host/hc_crisv10.c2
-rw-r--r--drivers/usb/host/sl811-hcd.c4
-rw-r--r--drivers/usb/image/mdc800.c2
-rw-r--r--drivers/usb/image/microtek.c2
-rw-r--r--drivers/usb/input/aiptek.c2
-rw-r--r--drivers/usb/input/ati_remote.c2
-rw-r--r--drivers/usb/input/mtouchusb.c2
-rw-r--r--drivers/usb/input/usbkbd.c3
-rw-r--r--drivers/usb/media/ov511.c2
-rw-r--r--drivers/usb/media/pwc/pwc-ctrl.c80
-rw-r--r--drivers/usb/media/pwc/pwc-if.c12
-rw-r--r--drivers/usb/media/pwc/pwc-ioctl.h2
-rw-r--r--drivers/usb/media/pwc/pwc.h6
-rw-r--r--drivers/usb/media/sn9c102_core.c4
-rw-r--r--drivers/usb/media/sn9c102_sensor.h2
-rw-r--r--drivers/usb/misc/legousbtower.c2
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c3
-rw-r--r--drivers/usb/net/pegasus.c4
-rw-r--r--drivers/usb/net/usbnet.c432
-rw-r--r--drivers/usb/net/zd1201.c28
-rw-r--r--drivers/usb/serial/Kconfig18
-rw-r--r--drivers/usb/serial/Makefile2
-rw-r--r--drivers/usb/serial/airprime.c63
-rw-r--r--drivers/usb/serial/cypress_m8.c187
-rw-r--r--drivers/usb/serial/ftdi_sio.c46
-rw-r--r--drivers/usb/serial/ftdi_sio.h36
-rw-r--r--drivers/usb/serial/hp4x.c85
-rw-r--r--drivers/usb/serial/io_usbvend.h2
-rw-r--r--drivers/usb/serial/keyspan_usa90msg.h2
-rw-r--r--drivers/usb/storage/debug.c1
-rw-r--r--drivers/usb/storage/shuttle_usbat.c2
-rw-r--r--drivers/usb/storage/unusual_devs.h39
-rw-r--r--drivers/video/Kconfig8
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/amba-clcd.c22
-rw-r--r--drivers/video/aty/radeon_base.c118
-rw-r--r--drivers/video/console/fbcon.c5
-rw-r--r--drivers/video/console/vgacon.c2
-rw-r--r--drivers/video/cyber2000fb.c8
-rw-r--r--drivers/video/fbcmap.c32
-rw-r--r--drivers/video/fbmem.c7
-rw-r--r--drivers/video/fbmon.c1
-rw-r--r--drivers/video/fbsysfs.c2
-rw-r--r--drivers/video/i810/i810_main.c14
-rw-r--r--drivers/video/imsttfb.c4
-rw-r--r--drivers/video/imxfb.c695
-rw-r--r--drivers/video/imxfb.h72
-rw-r--r--drivers/video/intelfb/intelfbdrv.c38
-rw-r--r--drivers/video/intelfb/intelfbdrv.h68
-rw-r--r--drivers/video/logo/Kconfig2
-rw-r--r--drivers/video/nvidia/nvidia.c26
-rw-r--r--drivers/video/radeonfb.c2
-rw-r--r--drivers/video/savage/savagefb_driver.c6
-rw-r--r--drivers/video/sis/init.c4
-rw-r--r--drivers/video/sis/init.h3
-rw-r--r--drivers/video/sis/init301.c9
-rw-r--r--drivers/video/sis/init301.h4
-rw-r--r--drivers/video/sis/sis_main.c5
-rw-r--r--drivers/video/tcx.c14
-rw-r--r--drivers/video/tdfxfb.c88
-rw-r--r--drivers/video/tgafb.c4
-rw-r--r--drivers/video/vesafb.c3
293 files changed, 6461 insertions, 1868 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 05a17812d52..ff64d333e95 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -838,7 +838,7 @@ int acpi_processor_cst_has_changed (struct acpi_processor *pr)
/* Fall back to the default idle loop */
pm_idle = pm_idle_save;
- synchronize_kernel();
+ synchronize_sched(); /* Relies on interrupts forcing exit from idle. */
pr->flags.power = 0;
result = acpi_processor_get_power_info(pr);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e7ca0662656..119c94093a1 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -379,8 +379,8 @@ ACPI_DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
/**
* setup_sys_fs_device_files - sets up the device files under device namespace
- * @@dev: acpi_device object
- * @@func: function pointer to create or destroy the device file
+ * @dev: acpi_device object
+ * @func: function pointer to create or destroy the device file
*/
static void
setup_sys_fs_device_files (
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 78e34ee79df..10da3693476 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -59,7 +59,6 @@
* - doesn't support OAM cells
* - eni_put_free may hang if not putting memory fragments that _complete_
* 2^n block (never happens in real life, though)
- * - keeps IRQ even if initialization fails
*/
@@ -1802,22 +1801,22 @@ static int __devinit eni_start(struct atm_dev *dev)
if (request_irq(eni_dev->irq,&eni_int,SA_SHIRQ,DEV_LABEL,dev)) {
printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",
dev->number,eni_dev->irq);
- return -EAGAIN;
+ error = -EAGAIN;
+ goto out;
}
- /* @@@ should release IRQ on error */
pci_set_master(eni_dev->pci_dev);
if ((error = pci_write_config_word(eni_dev->pci_dev,PCI_COMMAND,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
(eni_dev->asic ? PCI_COMMAND_PARITY | PCI_COMMAND_SERR : 0)))) {
printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory+"
"master (0x%02x)\n",dev->number,error);
- return error;
+ goto free_irq;
}
if ((error = pci_write_config_byte(eni_dev->pci_dev,PCI_TONGA_CTRL,
END_SWAP_DMA))) {
printk(KERN_ERR DEV_LABEL "(itf %d): can't set endian swap "
"(0x%02x)\n",dev->number,error);
- return error;
+ goto free_irq;
}
/* determine addresses of internal tables */
eni_dev->vci = eni_dev->ram;
@@ -1839,7 +1838,8 @@ static int __devinit eni_start(struct atm_dev *dev)
if (!eni_dev->free_list) {
printk(KERN_ERR DEV_LABEL "(itf %d): couldn't get free page\n",
dev->number);
- return -ENOMEM;
+ error = -ENOMEM;
+ goto free_irq;
}
eni_dev->free_len = 0;
eni_put_free(eni_dev,buf,buffer_mem);
@@ -1855,17 +1855,26 @@ static int __devinit eni_start(struct atm_dev *dev)
*/
eni_out(0xffffffff,MID_IE);
error = start_tx(dev);
- if (error) return error;
+ if (error) goto free_list;
error = start_rx(dev);
- if (error) return error;
+ if (error) goto free_list;
error = dev->phy->start(dev);
- if (error) return error;
+ if (error) goto free_list;
eni_out(eni_in(MID_MC_S) | (1 << MID_INT_SEL_SHIFT) |
MID_TX_LOCK_MODE | MID_DMA_ENABLE | MID_TX_ENABLE | MID_RX_ENABLE,
MID_MC_S);
/* Tonga uses SBus INTReq1 */
(void) eni_in(MID_ISA); /* clear Midway interrupts */
return 0;
+
+free_list:
+ kfree(eni_dev->free_list);
+
+free_irq:
+ free_irq(eni_dev->irq, eni_dev);
+
+out:
+ return error;
}
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 196b3364462..9e65bfb85ba 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -2792,8 +2792,6 @@ static void __devexit fore200e_pca_remove_one(struct pci_dev *pci_dev)
fore200e = pci_get_drvdata(pci_dev);
- list_del(&fore200e->entry);
-
fore200e_shutdown(fore200e);
kfree(fore200e);
pci_disable_device(pci_dev);
@@ -2850,7 +2848,7 @@ fore200e_module_init(void)
}
#ifdef CONFIG_ATM_FORE200E_PCA
- if (!pci_module_init(&fore200e_pca_driver))
+ if (!pci_register_driver(&fore200e_pca_driver))
return 0;
#endif
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index c2c31a5f451..3022c548a13 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -70,6 +70,7 @@
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
@@ -371,7 +372,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
if (pci_enable_device(pci_dev))
return -EIO;
- if (pci_set_dma_mask(pci_dev, HE_DMA_MASK) != 0) {
+ if (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK) != 0) {
printk(KERN_WARNING "he: no suitable dma available\n");
err = -EIO;
goto init_one_failure;
diff --git a/drivers/atm/he.h b/drivers/atm/he.h
index 1a903859343..1dc277547a7 100644
--- a/drivers/atm/he.h
+++ b/drivers/atm/he.h
@@ -380,8 +380,6 @@ struct he_vcc
#define PCI_VENDOR_ID_FORE 0x1127
#define PCI_DEVICE_ID_FORE_HE 0x400
-#define HE_DMA_MASK 0xffffffff
-
#define GEN_CNTL_0 0x40
#define INT_PROC_ENBL (1<<25)
#define SLAVE_ENDIAN_MODE (1<<16)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index f4fa27315fb..2b3902c867d 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -405,9 +405,8 @@ void device_release_driver(struct device * dev)
static void driver_detach(struct device_driver * drv)
{
- struct list_head * entry, * next;
- list_for_each_safe(entry, next, &drv->devices) {
- struct device * dev = container_of(entry, struct device, driver_list);
+ while (!list_empty(&drv->devices)) {
+ struct device * dev = container_of(drv->devices.next, struct device, driver_list);
device_release_driver(dev);
}
}
diff --git a/drivers/base/core.c b/drivers/base/core.c
index a7cedd8cefe..268a9c8d168 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -139,7 +139,7 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
buffer = &buffer[length];
buffer_size -= length;
- if (dev->bus->hotplug) {
+ if (dev->bus && dev->bus->hotplug) {
/* have the bus specific function add its stuff */
retval = dev->bus->hotplug (dev, envp, num_envp, buffer, buffer_size);
if (retval) {
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index cd6453905a9..3a5f4c99179 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -115,7 +115,7 @@ int platform_add_devices(struct platform_device **devs, int num)
/**
* platform_device_register - add a platform-level device
- * @dev: platform device we're adding
+ * @pdev: platform device we're adding
*
*/
int platform_device_register(struct platform_device * pdev)
@@ -174,7 +174,7 @@ int platform_device_register(struct platform_device * pdev)
/**
* platform_device_unregister - remove a platform-level device
- * @dev: platform device we're removing
+ * @pdev: platform device we're removing
*
* Note that this function will also release all memory- and port-based
* resources owned by the device (@dev->resource).
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 423bbf2000d..3760edfdc65 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -3,6 +3,7 @@
Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
Copyright 1998-2001 by Leonard N. Zubkoff <lnz@dandelion.com>
+ Portions Copyright 2002 by Mylex (An IBM Business Unit)
This program is free software; you may redistribute and/or modify it under
the terms of the GNU General Public License Version 2 as published by the
@@ -532,6 +533,34 @@ static void DAC960_WaitForCommand(DAC960_Controller_T *Controller)
spin_lock_irq(&Controller->queue_lock);
}
+/*
+ DAC960_GEM_QueueCommand queues Command for DAC960 GEM Series Controllers.
+*/
+
+static void DAC960_GEM_QueueCommand(DAC960_Command_T *Command)
+{
+ DAC960_Controller_T *Controller = Command->Controller;
+ void __iomem *ControllerBaseAddress = Controller->BaseAddress;
+ DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+ DAC960_V2_CommandMailbox_T *NextCommandMailbox =
+ Controller->V2.NextCommandMailbox;
+
+ CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+ DAC960_GEM_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+
+ if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
+ Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
+ DAC960_GEM_MemoryMailboxNewCommand(ControllerBaseAddress);
+
+ Controller->V2.PreviousCommandMailbox2 =
+ Controller->V2.PreviousCommandMailbox1;
+ Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;
+
+ if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)
+ NextCommandMailbox = Controller->V2.FirstCommandMailbox;
+
+ Controller->V2.NextCommandMailbox = NextCommandMailbox;
+}
/*
DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers.
@@ -1464,6 +1493,17 @@ static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
Controller->V2.FirstStatusMailboxDMA;
switch (Controller->HardwareType)
{
+ case DAC960_GEM_Controller:
+ while (DAC960_GEM_HardwareMailboxFullP(ControllerBaseAddress))
+ udelay(1);
+ DAC960_GEM_WriteHardwareMailbox(ControllerBaseAddress, CommandMailboxDMA);
+ DAC960_GEM_HardwareMailboxNewCommand(ControllerBaseAddress);
+ while (!DAC960_GEM_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
+ udelay(1);
+ CommandStatus = DAC960_GEM_ReadCommandStatus(ControllerBaseAddress);
+ DAC960_GEM_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+ DAC960_GEM_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
+ break;
case DAC960_BA_Controller:
while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress))
udelay(1);
@@ -2627,6 +2667,9 @@ static void DAC960_DetectCleanup(DAC960_Controller_T *Controller)
if (Controller->MemoryMappedAddress) {
switch(Controller->HardwareType)
{
+ case DAC960_GEM_Controller:
+ DAC960_GEM_DisableInterrupts(Controller->BaseAddress);
+ break;
case DAC960_BA_Controller:
DAC960_BA_DisableInterrupts(Controller->BaseAddress);
break;
@@ -2705,6 +2748,9 @@ DAC960_DetectController(struct pci_dev *PCI_Device,
switch (Controller->HardwareType)
{
+ case DAC960_GEM_Controller:
+ Controller->PCI_Address = pci_resource_start(PCI_Device, 0);
+ break;
case DAC960_BA_Controller:
Controller->PCI_Address = pci_resource_start(PCI_Device, 0);
break;
@@ -2756,6 +2802,36 @@ DAC960_DetectController(struct pci_dev *PCI_Device,
BaseAddress = Controller->BaseAddress;
switch (Controller->HardwareType)
{
+ case DAC960_GEM_Controller:
+ DAC960_GEM_DisableInterrupts(BaseAddress);
+ DAC960_GEM_AcknowledgeHardwareMailboxStatus(BaseAddress);
+ udelay(1000);
+ while (DAC960_GEM_InitializationInProgressP(BaseAddress))
+ {
+ if (DAC960_GEM_ReadErrorStatus(BaseAddress, &ErrorStatus,
+ &Parameter0, &Parameter1) &&
+ DAC960_ReportErrorStatus(Controller, ErrorStatus,
+ Parameter0, Parameter1))
+ goto Failure;
+ udelay(10);
+ }
+ if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
+ {
+ DAC960_Error("Unable to Enable Memory Mailbox Interface "
+ "for Controller at\n", Controller);
+ goto Failure;
+ }
+ DAC960_GEM_EnableInterrupts(BaseAddress);
+ Controller->QueueCommand = DAC960_GEM_QueueCommand;
+ Controller->ReadControllerConfiguration =
+ DAC960_V2_ReadControllerConfiguration;
+ Controller->ReadDeviceConfiguration =
+ DAC960_V2_ReadDeviceConfiguration;
+ Controller->ReportDeviceConfiguration =
+ DAC960_V2_ReportDeviceConfiguration;
+ Controller->QueueReadWriteCommand =
+ DAC960_V2_QueueReadWriteCommand;
+ break;
case DAC960_BA_Controller:
DAC960_BA_DisableInterrupts(BaseAddress);
DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress);
@@ -5189,6 +5265,47 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
wake_up(&Controller->CommandWaitQueue);
}
+/*
+ DAC960_GEM_InterruptHandler handles hardware interrupts from DAC960 GEM Series
+ Controllers.
+*/
+
+static irqreturn_t DAC960_GEM_InterruptHandler(int IRQ_Channel,
+ void *DeviceIdentifier,
+ struct pt_regs *InterruptRegisters)
+{
+ DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+ void __iomem *ControllerBaseAddress = Controller->BaseAddress;
+ DAC960_V2_StatusMailbox_T *NextStatusMailbox;
+ unsigned long flags;
+
+ spin_lock_irqsave(&Controller->queue_lock, flags);
+ DAC960_GEM_AcknowledgeInterrupt(ControllerBaseAddress);
+ NextStatusMailbox = Controller->V2.NextStatusMailbox;
+ while (NextStatusMailbox->Fields.CommandIdentifier > 0)
+ {
+ DAC960_V2_CommandIdentifier_T CommandIdentifier =
+ NextStatusMailbox->Fields.CommandIdentifier;
+ DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+ Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
+ Command->V2.RequestSenseLength =
+ NextStatusMailbox->Fields.RequestSenseLength;
+ Command->V2.DataTransferResidue =
+ NextStatusMailbox->Fields.DataTransferResidue;
+ NextStatusMailbox->Words[0] = 0;
+ if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
+ NextStatusMailbox = Controller->V2.FirstStatusMailbox;
+ DAC960_V2_ProcessCompletedCommand(Command);
+ }
+ Controller->V2.NextStatusMailbox = NextStatusMailbox;
+ /*
+ Attempt to remove additional I/O Requests from the Controller's
+ I/O Request Queue and queue them to the Controller.
+ */
+ DAC960_ProcessRequest(Controller);
+ spin_unlock_irqrestore(&Controller->queue_lock, flags);
+ return IRQ_HANDLED;
+}
/*
DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series
@@ -6962,6 +7079,14 @@ static void DAC960_gam_cleanup(void)
#endif /* DAC960_GAM_MINOR */
+static struct DAC960_privdata DAC960_GEM_privdata = {
+ .HardwareType = DAC960_GEM_Controller,
+ .FirmwareType = DAC960_V2_Controller,
+ .InterruptHandler = DAC960_GEM_InterruptHandler,
+ .MemoryWindowSize = DAC960_GEM_RegisterWindowSize,
+};
+
+
static struct DAC960_privdata DAC960_BA_privdata = {
.HardwareType = DAC960_BA_Controller,
.FirmwareType = DAC960_V2_Controller,
@@ -7007,6 +7132,13 @@ static struct DAC960_privdata DAC960_P_privdata = {
static struct pci_device_id DAC960_id_table[] = {
{
.vendor = PCI_VENDOR_ID_MYLEX,
+ .device = PCI_DEVICE_ID_MYLEX_DAC960_GEM,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (unsigned long) &DAC960_GEM_privdata,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_MYLEX,
.device = PCI_DEVICE_ID_MYLEX_DAC960_BA,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h
index d5e8e7190c9..a82f37f749a 100644
--- a/drivers/block/DAC960.h
+++ b/drivers/block/DAC960.h
@@ -2114,7 +2114,8 @@ typedef enum
DAC960_LA_Controller = 3, /* DAC1164P */
DAC960_PG_Controller = 4, /* DAC960PTL/PJ/PG */
DAC960_PD_Controller = 5, /* DAC960PU/PD/PL/P */
- DAC960_P_Controller = 6 /* DAC960PU/PD/PL/P */
+ DAC960_P_Controller = 6, /* DAC960PU/PD/PL/P */
+ DAC960_GEM_Controller = 7, /* AcceleRAID 4/5/600 */
}
DAC960_HardwareType_T;
@@ -2541,6 +2542,320 @@ void dma_addr_writeql(dma_addr_t addr, void __iomem *write_address)
}
/*
+ Define the DAC960 GEM Series Controller Interface Register Offsets.
+ */
+
+#define DAC960_GEM_RegisterWindowSize 0x600
+
+typedef enum
+{
+ DAC960_GEM_InboundDoorBellRegisterReadSetOffset = 0x214,
+ DAC960_GEM_InboundDoorBellRegisterClearOffset = 0x218,
+ DAC960_GEM_OutboundDoorBellRegisterReadSetOffset = 0x224,
+ DAC960_GEM_OutboundDoorBellRegisterClearOffset = 0x228,
+ DAC960_GEM_InterruptStatusRegisterOffset = 0x208,
+ DAC960_GEM_InterruptMaskRegisterReadSetOffset = 0x22C,
+ DAC960_GEM_InterruptMaskRegisterClearOffset = 0x230,
+ DAC960_GEM_CommandMailboxBusAddressOffset = 0x510,
+ DAC960_GEM_CommandStatusOffset = 0x518,
+ DAC960_GEM_ErrorStatusRegisterReadSetOffset = 0x224,
+ DAC960_GEM_ErrorStatusRegisterClearOffset = 0x228,
+}
+DAC960_GEM_RegisterOffsets_T;
+
+/*
+ Define the structure of the DAC960 GEM Series Inbound Door Bell
+ */
+
+typedef union DAC960_GEM_InboundDoorBellRegister
+{
+ unsigned int All;
+ struct {
+ unsigned int :24;
+ boolean HardwareMailboxNewCommand:1;
+ boolean AcknowledgeHardwareMailboxStatus:1;
+ boolean GenerateInterrupt:1;
+ boolean ControllerReset:1;
+ boolean MemoryMailboxNewCommand:1;
+ unsigned int :3;
+ } Write;
+ struct {
+ unsigned int :24;
+ boolean HardwareMailboxFull:1;
+ boolean InitializationInProgress:1;
+ unsigned int :6;
+ } Read;
+}
+DAC960_GEM_InboundDoorBellRegister_T;
+
+/*
+ Define the structure of the DAC960 GEM Series Outbound Door Bell Register.
+ */
+typedef union DAC960_GEM_OutboundDoorBellRegister
+{
+ unsigned int All;
+ struct {
+ unsigned int :24;
+ boolean AcknowledgeHardwareMailboxInterrupt:1;
+ boolean AcknowledgeMemoryMailboxInterrupt:1;
+ unsigned int :6;
+ } Write;
+ struct {
+ unsigned int :24;
+ boolean HardwareMailboxStatusAvailable:1;
+ boolean MemoryMailboxStatusAvailable:1;
+ unsigned int :6;
+ } Read;
+}
+DAC960_GEM_OutboundDoorBellRegister_T;
+
+/*
+ Define the structure of the DAC960 GEM Series Interrupt Mask Register.
+ */
+typedef union DAC960_GEM_InterruptMaskRegister
+{
+ unsigned int All;
+ struct {
+ unsigned int :16;
+ unsigned int :8;
+ unsigned int HardwareMailboxInterrupt:1;
+ unsigned int MemoryMailboxInterrupt:1;
+ unsigned int :6;
+ } Bits;
+}
+DAC960_GEM_InterruptMaskRegister_T;
+
+/*
+ Define the structure of the DAC960 GEM Series Error Status Register.
+ */
+
+typedef union DAC960_GEM_ErrorStatusRegister
+{
+ unsigned int All;
+ struct {
+ unsigned int :24;
+ unsigned int :5;
+ boolean ErrorStatusPending:1;
+ unsigned int :2;
+ } Bits;
+}
+DAC960_GEM_ErrorStatusRegister_T;
+
+/*
+ Define inline functions to provide an abstraction for reading and writing the
+ DAC960 GEM Series Controller Interface Registers.
+*/
+
+static inline
+void DAC960_GEM_HardwareMailboxNewCommand(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
+ InboundDoorBellRegister.All = 0;
+ InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
+ writel(InboundDoorBellRegister.All,
+ ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
+}
+
+static inline
+void DAC960_GEM_AcknowledgeHardwareMailboxStatus(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
+ InboundDoorBellRegister.All = 0;
+ InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
+ writel(InboundDoorBellRegister.All,
+ ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterClearOffset);
+}
+
+static inline
+void DAC960_GEM_GenerateInterrupt(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
+ InboundDoorBellRegister.All = 0;
+ InboundDoorBellRegister.Write.GenerateInterrupt = true;
+ writel(InboundDoorBellRegister.All,
+ ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
+}
+
+static inline
+void DAC960_GEM_ControllerReset(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
+ InboundDoorBellRegister.All = 0;
+ InboundDoorBellRegister.Write.ControllerReset = true;
+ writel(InboundDoorBellRegister.All,
+ ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
+}
+
+static inline
+void DAC960_GEM_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
+ InboundDoorBellRegister.All = 0;
+ InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
+ writel(InboundDoorBellRegister.All,
+ ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
+}
+
+static inline
+boolean DAC960_GEM_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
+ InboundDoorBellRegister.All =
+ readl(ControllerBaseAddress +
+ DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
+ return InboundDoorBellRegister.Read.HardwareMailboxFull;
+}
+
+static inline
+boolean DAC960_GEM_InitializationInProgressP(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
+ InboundDoorBellRegister.All =
+ readl(ControllerBaseAddress +
+ DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
+ return InboundDoorBellRegister.Read.InitializationInProgress;
+}
+
+static inline
+void DAC960_GEM_AcknowledgeHardwareMailboxInterrupt(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+ OutboundDoorBellRegister.All = 0;
+ OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
+ writel(OutboundDoorBellRegister.All,
+ ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset);
+}
+
+static inline
+void DAC960_GEM_AcknowledgeMemoryMailboxInterrupt(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+ OutboundDoorBellRegister.All = 0;
+ OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
+ writel(OutboundDoorBellRegister.All,
+ ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset);
+}
+
+static inline
+void DAC960_GEM_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+ OutboundDoorBellRegister.All = 0;
+ OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
+ OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
+ writel(OutboundDoorBellRegister.All,
+ ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset);
+}
+
+static inline
+boolean DAC960_GEM_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+ OutboundDoorBellRegister.All =
+ readl(ControllerBaseAddress +
+ DAC960_GEM_OutboundDoorBellRegisterReadSetOffset);
+ return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
+}
+
+static inline
+boolean DAC960_GEM_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+ OutboundDoorBellRegister.All =
+ readl(ControllerBaseAddress +
+ DAC960_GEM_OutboundDoorBellRegisterReadSetOffset);
+ return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
+}
+
+static inline
+void DAC960_GEM_EnableInterrupts(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister;
+ InterruptMaskRegister.All = 0;
+ InterruptMaskRegister.Bits.HardwareMailboxInterrupt = true;
+ InterruptMaskRegister.Bits.MemoryMailboxInterrupt = true;
+ writel(InterruptMaskRegister.All,
+ ControllerBaseAddress + DAC960_GEM_InterruptMaskRegisterClearOffset);
+}
+
+static inline
+void DAC960_GEM_DisableInterrupts(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister;
+ InterruptMaskRegister.All = 0;
+ InterruptMaskRegister.Bits.HardwareMailboxInterrupt = true;
+ InterruptMaskRegister.Bits.MemoryMailboxInterrupt = true;
+ writel(InterruptMaskRegister.All,
+ ControllerBaseAddress + DAC960_GEM_InterruptMaskRegisterReadSetOffset);
+}
+
+static inline
+boolean DAC960_GEM_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
+{
+ DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister;
+ InterruptMaskRegister.All =
+ readl(ControllerBaseAddress +
+ DAC960_GEM_InterruptMaskRegisterReadSetOffset);
+ return !(InterruptMaskRegister.Bits.HardwareMailboxInterrupt ||
+ InterruptMaskRegister.Bits.MemoryMailboxInterrupt);
+}
+
+static inline
+void DAC960_GEM_WriteCommandMailbox(DAC960_V2_CommandMailbox_T
+ *MemoryCommandMailbox,
+ DAC960_V2_CommandMailbox_T
+ *CommandMailbox)
+{
+ memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1],
+ sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int));
+ wmb();
+ MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
+ mb();
+}
+
+static inline
+void DAC960_GEM_WriteHardwareMailbox(void __iomem *ControllerBaseAddress,
+ dma_addr_t CommandMailboxDMA)
+{
+ dma_addr_writeql(CommandMailboxDMA,
+ ControllerBaseAddress +
+ DAC960_GEM_CommandMailboxBusAddressOffset);
+}
+
+static inline DAC960_V2_CommandIdentifier_T
+DAC960_GEM_ReadCommandIdentifier(void __iomem *ControllerBaseAddress)
+{
+ return readw(ControllerBaseAddress + DAC960_GEM_CommandStatusOffset);
+}
+
+static inline DAC960_V2_CommandStatus_T
+DAC960_GEM_ReadCommandStatus(void __iomem *ControllerBaseAddress)
+{
+ return readw(ControllerBaseAddress + DAC960_GEM_CommandStatusOffset + 2);
+}
+
+static inline boolean
+DAC960_GEM_ReadErrorStatus(void __iomem *ControllerBaseAddress,
+ unsigned char *ErrorStatus,
+ unsigned char *Parameter0,
+ unsigned char *Parameter1)
+{
+ DAC960_GEM_ErrorStatusRegister_T ErrorStatusRegister;
+ ErrorStatusRegister.All =
+ readl(ControllerBaseAddress + DAC960_GEM_ErrorStatusRegisterReadSetOffset);
+ if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
+ ErrorStatusRegister.Bits.ErrorStatusPending = false;
+ *ErrorStatus = ErrorStatusRegister.All;
+ *Parameter0 =
+ readb(ControllerBaseAddress + DAC960_GEM_CommandMailboxBusAddressOffset + 0);
+ *Parameter1 =
+ readb(ControllerBaseAddress + DAC960_GEM_CommandMailboxBusAddressOffset + 1);
+ writel(0x03000000, ControllerBaseAddress +
+ DAC960_GEM_ErrorStatusRegisterClearOffset);
+ return true;
+}
+
+/*
Define the DAC960 BA Series Controller Interface Register Offsets.
*/
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index e830be1a3ae..b594768b024 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -6,7 +6,7 @@ menu "Block devices"
config BLK_DEV_FD
tristate "Normal floppy disk support"
- depends on (!ARCH_S390 && !M68K && !IA64 && !UML) || Q40 || (SUN3X && BROKEN) || ARCH_RPC || ARCH_EBSA285
+ depends on (!ARCH_S390 && !M68K && !IA64 && !UML && !ARM) || Q40 || (SUN3X && BROKEN) || ARCH_RPC || ARCH_EBSA285
---help---
If you want to use the floppy disk drive(s) of your PC under Linux,
say Y. Information about this driver, especially important for IBM
@@ -105,7 +105,7 @@ config ATARI_SLM
config BLK_DEV_XD
tristate "XT hard disk support"
- depends on ISA
+ depends on ISA && ISA_DMA_API
help
Very old 8 bit hard disk controllers used in the IBM XT computer
will be supported if you say Y here.
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index aa8b547ffaf..721ba808604 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
-#define VERSION "6"
+#define VERSION "10"
#define AOE_MAJOR 152
#define DEVICE_NAME "aoe"
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 4780f7926d4..0e97fcb9f3a 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -37,6 +37,13 @@ static ssize_t aoedisk_show_netif(struct gendisk * disk, char *page)
return snprintf(page, PAGE_SIZE, "%s\n", d->ifp->name);
}
+/* firmware version */
+static ssize_t aoedisk_show_fwver(struct gendisk * disk, char *page)
+{
+ struct aoedev *d = disk->private_data;
+
+ return snprintf(page, PAGE_SIZE, "0x%04x\n", (unsigned int) d->fw_ver);
+}
static struct disk_attribute disk_attr_state = {
.attr = {.name = "state", .mode = S_IRUGO },
@@ -50,6 +57,10 @@ static struct disk_attribute disk_attr_netif = {
.attr = {.name = "netif", .mode = S_IRUGO },
.show = aoedisk_show_netif
};
+static struct disk_attribute disk_attr_fwver = {
+ .attr = {.name = "firmware-version", .mode = S_IRUGO },
+ .show = aoedisk_show_fwver
+};
static void
aoedisk_add_sysfs(struct aoedev *d)
@@ -57,6 +68,7 @@ aoedisk_add_sysfs(struct aoedev *d)
sysfs_create_file(&d->gd->kobj, &disk_attr_state.attr);
sysfs_create_file(&d->gd->kobj, &disk_attr_mac.attr);
sysfs_create_file(&d->gd->kobj, &disk_attr_netif.attr);
+ sysfs_create_file(&d->gd->kobj, &disk_attr_fwver.attr);
}
void
aoedisk_rm_sysfs(struct aoedev *d)
@@ -64,6 +76,7 @@ aoedisk_rm_sysfs(struct aoedev *d)
sysfs_remove_link(&d->gd->kobj, "state");
sysfs_remove_link(&d->gd->kobj, "mac");
sysfs_remove_link(&d->gd->kobj, "netif");
+ sysfs_remove_link(&d->gd->kobj, "firmware-version");
}
static int
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index ec16c64dd11..6e231c5a119 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -109,25 +109,22 @@ aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bu
spin_lock_irqsave(&devlist_lock, flags);
for (d=devlist; d; d=d->next)
- if (d->sysminor == sysminor
- || memcmp(d->addr, addr, sizeof d->addr) == 0)
+ if (d->sysminor == sysminor)
break;
if (d == NULL && (d = aoedev_newdev(bufcnt)) == NULL) {
spin_unlock_irqrestore(&devlist_lock, flags);
printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n");
return NULL;
- }
+ } /* if newdev, (d->flags & DEVFL_UP) == 0 for below */
spin_unlock_irqrestore(&devlist_lock, flags);
spin_lock_irqsave(&d->lock, flags);
d->ifp = ifp;
-
- if (d->sysminor != sysminor
- || (d->flags & DEVFL_UP) == 0) {
+ memcpy(d->addr, addr, sizeof d->addr);
+ if ((d->flags & DEVFL_UP) == 0) {
aoedev_downdev(d); /* flushes outstanding frames */
- memcpy(d->addr, addr, sizeof d->addr);
d->sysminor = sysminor;
d->aoemajor = AOEMAJOR(sysminor);
d->aoeminor = AOEMINOR(sysminor);
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index bc92aacb6da..9e6f51c528b 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -7,6 +7,7 @@
#include <linux/hdreg.h>
#include <linux/blkdev.h>
#include <linux/netdevice.h>
+#include <linux/moduleparam.h>
#include "aoe.h"
#define NECODES 5
@@ -26,6 +27,19 @@ enum {
};
static char aoe_iflist[IFLISTSZ];
+module_param_string(aoe_iflist, aoe_iflist, IFLISTSZ, 0600);
+MODULE_PARM_DESC(aoe_iflist, "aoe_iflist=\"dev1 [dev2 ...]\"\n");
+
+#ifndef MODULE
+static int __init aoe_iflist_setup(char *str)
+{
+ strncpy(aoe_iflist, str, IFLISTSZ);
+ aoe_iflist[IFLISTSZ - 1] = '\0';
+ return 1;
+}
+
+__setup("aoe_iflist=", aoe_iflist_setup);
+#endif
int
is_aoe_netif(struct net_device *ifp)
@@ -36,7 +50,8 @@ is_aoe_netif(struct net_device *ifp)
if (aoe_iflist[0] == '\0')
return 1;
- for (p = aoe_iflist; *p; p = q + strspn(q, WHITESPACE)) {
+ p = aoe_iflist + strspn(aoe_iflist, WHITESPACE);
+ for (; *p; p = q + strspn(q, WHITESPACE)) {
q = p + strcspn(p, WHITESPACE);
if (q != p)
len = q - p;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 42dfa281a88..f0c1084b840 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3345,7 +3345,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
struct block_device *bdev = opened_bdev[cnt];
if (!bdev || ITYPE(drive_state[cnt].fd_device) != type)
continue;
- __invalidate_device(bdev, 0);
+ __invalidate_device(bdev);
}
up(&open_lock);
} else {
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index ab4db71375e..8bbe01d4b48 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/kmod.h>
#include <linux/kobj_map.h>
+#include <linux/buffer_head.h>
#define MAX_PROBE_HASH 255 /* random */
@@ -676,7 +677,8 @@ int invalidate_partition(struct gendisk *disk, int index)
int res = 0;
struct block_device *bdev = bdget_disk(disk, index);
if (bdev) {
- res = __invalidate_device(bdev, 1);
+ fsync_bdev(bdev);
+ res = __invalidate_device(bdev);
bdput(bdev);
}
return res;
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index efdf04450bf..9e268ddedfb 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -78,6 +78,7 @@
#define DBG_RX 0x0200
#define DBG_TX 0x0400
static unsigned int debugflags;
+static unsigned int nbds_max = 16;
#endif /* NDEBUG */
static struct nbd_device nbd_dev[MAX_NBD];
@@ -647,7 +648,13 @@ static int __init nbd_init(void)
return -EIO;
}
- for (i = 0; i < MAX_NBD; i++) {
+ if (nbds_max > MAX_NBD) {
+ printk(KERN_CRIT "nbd: cannot allocate more than %u nbds; %u requested.\n", MAX_NBD,
+ nbds_max);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < nbds_max; i++) {
struct gendisk *disk = alloc_disk(1);
if (!disk)
goto out;
@@ -673,7 +680,7 @@ static int __init nbd_init(void)
dprintk(DBG_INIT, "nbd: debugflags=0x%x\n", debugflags);
devfs_mk_dir("nbd");
- for (i = 0; i < MAX_NBD; i++) {
+ for (i = 0; i < nbds_max; i++) {
struct gendisk *disk = nbd_dev[i].disk;
nbd_dev[i].file = NULL;
nbd_dev[i].magic = LO_MAGIC;
@@ -706,8 +713,9 @@ out:
static void __exit nbd_cleanup(void)
{
int i;
- for (i = 0; i < MAX_NBD; i++) {
+ for (i = 0; i < nbds_max; i++) {
struct gendisk *disk = nbd_dev[i].disk;
+ nbd_dev[i].magic = 0;
if (disk) {
del_gendisk(disk);
blk_cleanup_queue(disk->queue);
@@ -725,6 +733,8 @@ module_exit(nbd_cleanup);
MODULE_DESCRIPTION("Network Block Device");
MODULE_LICENSE("GPL");
+module_param(nbds_max, int, 0444);
+MODULE_PARM_DESC(nbds_max, "How many network block devices to initialize.");
#ifndef NDEBUG
module_param(debugflags, int, 0644);
MODULE_PARM_DESC(debugflags, "flags for controlling debug output");
diff --git a/drivers/block/noop-iosched.c b/drivers/block/noop-iosched.c
index 888c477e02b..b1730b62c37 100644
--- a/drivers/block/noop-iosched.c
+++ b/drivers/block/noop-iosched.c
@@ -13,34 +13,13 @@
static int elevator_noop_merge(request_queue_t *q, struct request **req,
struct bio *bio)
{
- struct list_head *entry = &q->queue_head;
- struct request *__rq;
int ret;
- if ((ret = elv_try_last_merge(q, bio))) {
+ ret = elv_try_last_merge(q, bio);
+ if (ret != ELEVATOR_NO_MERGE)
*req = q->last_merge;
- return ret;
- }
- while ((entry = entry->prev) != &q->queue_head) {
- __rq = list_entry_rq(entry);
-
- if (__rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER))
- break;
- else if (__rq->flags & REQ_STARTED)
- break;
-
- if (!blk_fs_request(__rq))
- continue;
-
- if ((ret = elv_try_merge(__rq, bio))) {
- *req = __rq;
- q->last_merge = __rq;
- return ret;
- }
- }
-
- return ELEVATOR_NO_MERGE;
+ return ret;
}
static void elevator_noop_merge_requests(request_queue_t *q, struct request *req,
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 9deca49c71f..beaa561f2ed 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -645,7 +645,7 @@ static int cdrom_mrw_exit(struct cdrom_device_info *cdi)
ret = cdrom_mrw_bgformat_susp(cdi, 0);
}
- if (!ret)
+ if (!ret && cdi->media_written)
ret = cdrom_flush_cache(cdi);
return ret;
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
index 647a71b12a2..ac96de15d83 100644
--- a/drivers/cdrom/cdu31a.c
+++ b/drivers/cdrom/cdu31a.c
@@ -292,7 +292,7 @@ module_param(cdu31a_irq, int, 0);
/* The interrupt handler will wake this queue up when it gets an
interrupts. */
-DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait);
+static DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait);
static int irq_flag = 0;
static int curr_control_reg = 0; /* Current value of the control register */
@@ -2947,7 +2947,7 @@ static int scd_block_media_changed(struct gendisk *disk)
return cdrom_media_changed(&scd_info);
}
-struct block_device_operations scd_bdops =
+static struct block_device_operations scd_bdops =
{
.owner = THIS_MODULE,
.open = scd_block_open,
@@ -3216,7 +3216,7 @@ errout3:
}
-void __exit cdu31a_exit(void)
+static void __exit cdu31a_exit(void)
{
del_gendisk(scd_gendisk);
put_disk(scd_gendisk);
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
index ccde7ab491d..07bbd24e3c1 100644
--- a/drivers/cdrom/mcdx.c
+++ b/drivers/cdrom/mcdx.c
@@ -107,20 +107,20 @@ static const char *mcdx_c_version
The _direct_ size is the number of sectors we're allowed to skip
directly (performing a read instead of requesting the new sector
needed */
-const int REQUEST_SIZE = 800; /* should be less then 255 * 4 */
-const int DIRECT_SIZE = 400; /* should be less then REQUEST_SIZE */
+static const int REQUEST_SIZE = 800; /* should be less then 255 * 4 */
+static const int DIRECT_SIZE = 400; /* should be less then REQUEST_SIZE */
enum drivemodes { TOC, DATA, RAW, COOKED };
enum datamodes { MODE0, MODE1, MODE2 };
enum resetmodes { SOFT, HARD };
-const int SINGLE = 0x01; /* single speed drive (FX001S, LU) */
-const int DOUBLE = 0x02; /* double speed drive (FX001D, ..? */
-const int DOOR = 0x04; /* door locking capability */
-const int MULTI = 0x08; /* multi session capability */
+static const int SINGLE = 0x01; /* single speed drive (FX001S, LU) */
+static const int DOUBLE = 0x02; /* double speed drive (FX001D, ..? */
+static const int DOOR = 0x04; /* door locking capability */
+static const int MULTI = 0x08; /* multi session capability */
-const unsigned char READ1X = 0xc0;
-const unsigned char READ2X = 0xc1;
+static const unsigned char READ1X = 0xc0;
+static const unsigned char READ2X = 0xc1;
/* DECLARATIONS ****************************************************/
@@ -210,9 +210,7 @@ struct s_drive_stuff {
repeated here to show what's going on. And to sense, if they're
changed elsewhere. */
-/* declared in blk.h */
-int mcdx_init(void);
-void do_mcdx_request(request_queue_t * q);
+static int mcdx_init(void);
static int mcdx_block_open(struct inode *inode, struct file *file)
{
@@ -569,7 +567,7 @@ static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
}
}
-void do_mcdx_request(request_queue_t * q)
+static void do_mcdx_request(request_queue_t * q)
{
struct s_drive_stuff *stuffp;
struct request *req;
@@ -1028,7 +1026,7 @@ int __mcdx_init(void)
return 0;
}
-void __exit mcdx_exit(void)
+static void __exit mcdx_exit(void)
{
int i;
@@ -1075,7 +1073,7 @@ module_exit(mcdx_exit);
/* Support functions ************************************************/
-int __init mcdx_init_drive(int drive)
+static int __init mcdx_init_drive(int drive)
{
struct s_version version;
struct gendisk *disk;
@@ -1261,7 +1259,7 @@ int __init mcdx_init_drive(int drive)
return 0;
}
-int __init mcdx_init(void)
+static int __init mcdx_init(void)
{
int drive;
xwarn("Version 2.14(hs) \n");
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
index fc2c433f6a2..452d3467515 100644
--- a/drivers/cdrom/sbpcd.c
+++ b/drivers/cdrom/sbpcd.c
@@ -5895,7 +5895,7 @@ int __init sbpcd_init(void)
}
/*==========================================================================*/
#ifdef MODULE
-void sbpcd_exit(void)
+static void sbpcd_exit(void)
{
int j;
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 096a1202ea0..5ed6515ae01 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -153,7 +153,7 @@ config DIGIEPCA
config ESPSERIAL
tristate "Hayes ESP serial port support"
- depends on SERIAL_NONSTANDARD && ISA && BROKEN_ON_SMP
+ depends on SERIAL_NONSTANDARD && ISA && BROKEN_ON_SMP && ISA_DMA_API
help
This is a driver which supports Hayes ESP serial ports. Both single
port cards and multiport cards are supported. Make sure to read
@@ -195,7 +195,7 @@ config ISI
config SYNCLINK
tristate "Microgate SyncLink card support"
- depends on SERIAL_NONSTANDARD && PCI
+ depends on SERIAL_NONSTANDARD && PCI && ISA_DMA_API
help
Provides support for the SyncLink ISA and PCI multiprotocol serial
adapters. These adapters support asynchronous and HDLC bit
@@ -399,6 +399,20 @@ config SGI_SNSC
controller communication from user space (you want this!),
say Y. Otherwise, say N.
+config SGI_TIOCX
+ bool "SGI TIO CX driver support"
+ depends on (IA64_SGI_SN2 || IA64_GENERIC)
+ help
+ If you have an SGI Altix and you have fpga devices attached
+ to your TIO, say Y here, otherwise say N.
+
+config SGI_MBCS
+ tristate "SGI FPGA Core Services driver support"
+ depends on SGI_TIOCX
+ help
+ If you have an SGI Altix with an attached SABrick
+ say Y or M here, otherwise say N.
+
source "drivers/serial/Kconfig"
config UNIX98_PTYS
@@ -968,7 +982,7 @@ config MAX_RAW_DEVS
config HANGCHECK_TIMER
tristate "Hangcheck timer"
- depends on X86_64 || X86
+ depends on X86_64 || X86 || IA64 || PPC64 || ARCH_S390
help
The hangcheck-timer module detects when the system has gone
out to lunch past a certain margin. It can reboot the system
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 54ed76af1a4..e3f5c32aac5 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -42,11 +42,12 @@ obj-$(CONFIG_SX) += sx.o generic_serial.o
obj-$(CONFIG_RIO) += rio/ generic_serial.o
obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvsi.o
obj-$(CONFIG_RAW_DRIVER) += raw.o
-obj-$(CONFIG_SGI_SNSC) += snsc.o
+obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
obj-$(CONFIG_MMTIMER) += mmtimer.o
obj-$(CONFIG_VIOCONS) += viocons.o
obj-$(CONFIG_VIOTAPE) += viotape.o
obj-$(CONFIG_HVCS) += hvcs.o
+obj-$(CONFIG_SGI_MBCS) += mbcs.o
obj-$(CONFIG_PRINTER) += lp.o
obj-$(CONFIG_TIPAR) += tipar.o
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index c86a22c5499..0212febda65 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -192,7 +192,7 @@ static struct aper_size_info_32 ali_generic_sizes[7] =
{4, 1024, 0, 3}
};
-struct agp_bridge_driver ali_generic_bridge = {
+static struct agp_bridge_driver ali_generic_bridge = {
.owner = THIS_MODULE,
.aperture_sizes = ali_generic_sizes,
.size_type = U32_APER_SIZE,
@@ -215,7 +215,7 @@ struct agp_bridge_driver ali_generic_bridge = {
.agp_destroy_page = ali_destroy_page,
};
-struct agp_bridge_driver ali_m1541_bridge = {
+static struct agp_bridge_driver ali_m1541_bridge = {
.owner = THIS_MODULE,
.aperture_sizes = ali_generic_sizes,
.size_type = U32_APER_SIZE,
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index f1ea87ea6b6..e62a3c2c44a 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -358,7 +358,7 @@ static struct gatt_mask amd_irongate_masks[] =
{.mask = 1, .type = 0}
};
-struct agp_bridge_driver amd_irongate_driver = {
+static struct agp_bridge_driver amd_irongate_driver = {
.owner = THIS_MODULE,
.aperture_sizes = amd_irongate_sizes,
.size_type = LVL2_APER_SIZE,
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 905f0629c44..399c042f68f 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -243,7 +243,7 @@ static void amd64_cleanup(void)
}
-struct agp_bridge_driver amd_8151_driver = {
+static struct agp_bridge_driver amd_8151_driver = {
.owner = THIS_MODULE,
.aperture_sizes = amd_8151_sizes,
.size_type = U32_APER_SIZE,
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 757dde006fc..a65f8827c28 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -393,7 +393,7 @@ static int ati_free_gatt_table(struct agp_bridge_data *bridge)
return 0;
}
-struct agp_bridge_driver ati_generic_bridge = {
+static struct agp_bridge_driver ati_generic_bridge = {
.owner = THIS_MODULE,
.aperture_sizes = ati_generic_sizes,
.size_type = LVL2_APER_SIZE,
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index c3442f3c648..2f3dfb63bdc 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -97,7 +97,7 @@ void agp_backend_release(struct agp_bridge_data *bridge)
EXPORT_SYMBOL(agp_backend_release);
-struct { int mem, agp; } maxes_table[] = {
+static struct { int mem, agp; } maxes_table[] = {
{0, 0},
{32, 4},
{64, 28},
@@ -322,7 +322,7 @@ static int __init agp_init(void)
return 0;
}
-void __exit agp_exit(void)
+static void __exit agp_exit(void)
{
}
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index 2a87cecdc91..1383c3165ea 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -303,7 +303,7 @@ static int efficeon_remove_memory(struct agp_memory * mem, off_t pg_start, int t
}
-struct agp_bridge_driver efficeon_driver = {
+static struct agp_bridge_driver efficeon_driver = {
.owner = THIS_MODULE,
.aperture_sizes = efficeon_generic_sizes,
.size_type = LVL2_APER_SIZE,
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index f633623ac80..3dfb6648547 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -235,7 +235,7 @@ static void agp_insert_into_pool(struct agp_memory * temp)
/* File private list routines */
-struct agp_file_private *agp_find_private(pid_t pid)
+static struct agp_file_private *agp_find_private(pid_t pid)
{
struct agp_file_private *curr;
@@ -250,7 +250,7 @@ struct agp_file_private *agp_find_private(pid_t pid)
return NULL;
}
-void agp_insert_file_private(struct agp_file_private * priv)
+static void agp_insert_file_private(struct agp_file_private * priv)
{
struct agp_file_private *prev;
@@ -262,7 +262,7 @@ void agp_insert_file_private(struct agp_file_private * priv)
agp_fe.file_priv_list = priv;
}
-void agp_remove_file_private(struct agp_file_private * priv)
+static void agp_remove_file_private(struct agp_file_private * priv)
{
struct agp_file_private *next;
struct agp_file_private *prev;
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 4f7a3e8bc91..80dafa3030b 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -288,7 +288,7 @@ static struct gatt_mask nvidia_generic_masks[] =
};
-struct agp_bridge_driver nvidia_driver = {
+static struct agp_bridge_driver nvidia_driver = {
.owner = THIS_MODULE,
.aperture_sizes = nvidia_generic_sizes,
.size_type = U8_APER_SIZE,
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index cfccacb2a64..ebc05554045 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -119,7 +119,7 @@ static struct aper_size_info_8 sis_generic_sizes[7] =
{4, 1024, 0, 3}
};
-struct agp_bridge_driver sis_driver = {
+static struct agp_bridge_driver sis_driver = {
.owner = THIS_MODULE,
.aperture_sizes = sis_generic_sizes,
.size_type = U8_APER_SIZE,
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index bb338d9134e..10c23302dd8 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -409,7 +409,7 @@ static void serverworks_agp_enable(struct agp_bridge_data *bridge, u32 mode)
agp_device_command(command, 0);
}
-struct agp_bridge_driver sworks_driver = {
+static struct agp_bridge_driver sworks_driver = {
.owner = THIS_MODULE,
.aperture_sizes = serverworks_sizes,
.size_type = LVL2_APER_SIZE,
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index e1451dd9b6a..c847df575cf 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -170,7 +170,7 @@ static void via_tlbflush_agp3(struct agp_memory *mem)
}
-struct agp_bridge_driver via_agp3_driver = {
+static struct agp_bridge_driver via_agp3_driver = {
.owner = THIS_MODULE,
.aperture_sizes = agp3_generic_sizes,
.size_type = U8_APER_SIZE,
@@ -193,7 +193,7 @@ struct agp_bridge_driver via_agp3_driver = {
.agp_destroy_page = agp_generic_destroy_page,
};
-struct agp_bridge_driver via_driver = {
+static struct agp_bridge_driver via_driver = {
.owner = THIS_MODULE,
.aperture_sizes = via_generic_sizes,
.size_type = U8_APER_SIZE,
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index 903e4c3cc20..a229915ce1b 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -52,7 +52,7 @@
#define KERNEL
#include <linux/types.h>
#include <linux/fs.h>
-#include <linux/mm.h> /* for verify_area */
+#include <linux/mm.h>
#include <linux/errno.h> /* for -EBUSY */
#include <linux/ioport.h> /* for request_region */
#include <linux/delay.h> /* for loops_per_jiffy */
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index 83d6b37b36c..78e650fc5b4 100644
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -3,7 +3,7 @@
*
* Driver for a little io fencing timer.
*
- * Copyright (C) 2002 Oracle Corporation. All rights reserved.
+ * Copyright (C) 2002, 2003 Oracle. All rights reserved.
*
* Author: Joel Becker <joel.becker@oracle.com>
*
@@ -44,11 +44,14 @@
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/reboot.h>
+#include <linux/smp_lock.h>
#include <linux/init.h>
+#include <linux/delay.h>
#include <asm/uaccess.h>
+#include <linux/sysrq.h>
-#define VERSION_STR "0.5.0"
+#define VERSION_STR "0.9.0"
#define DEFAULT_IOFENCE_MARGIN 60 /* Default fudge factor, in seconds */
#define DEFAULT_IOFENCE_TICK 180 /* Default timer timeout, in seconds */
@@ -56,18 +59,89 @@
static int hangcheck_tick = DEFAULT_IOFENCE_TICK;
static int hangcheck_margin = DEFAULT_IOFENCE_MARGIN;
static int hangcheck_reboot; /* Defaults to not reboot */
+static int hangcheck_dump_tasks; /* Defaults to not dumping SysRQ T */
-/* Driver options */
+/* options - modular */
module_param(hangcheck_tick, int, 0);
MODULE_PARM_DESC(hangcheck_tick, "Timer delay.");
module_param(hangcheck_margin, int, 0);
MODULE_PARM_DESC(hangcheck_margin, "If the hangcheck timer has been delayed more than hangcheck_margin seconds, the driver will fire.");
module_param(hangcheck_reboot, int, 0);
MODULE_PARM_DESC(hangcheck_reboot, "If nonzero, the machine will reboot when the timer margin is exceeded.");
+module_param(hangcheck_dump_tasks, int, 0);
+MODULE_PARM_DESC(hangcheck_dump_tasks, "If nonzero, the machine will dump the system task state when the timer margin is exceeded.");
-MODULE_AUTHOR("Joel Becker");
+MODULE_AUTHOR("Oracle");
MODULE_DESCRIPTION("Hangcheck-timer detects when the system has gone out to lunch past a certain margin.");
MODULE_LICENSE("GPL");
+MODULE_VERSION(VERSION_STR);
+
+/* options - nonmodular */
+#ifndef MODULE
+
+static int __init hangcheck_parse_tick(char *str)
+{
+ int par;
+ if (get_option(&str,&par))
+ hangcheck_tick = par;
+ return 1;
+}
+
+static int __init hangcheck_parse_margin(char *str)
+{
+ int par;
+ if (get_option(&str,&par))
+ hangcheck_margin = par;
+ return 1;
+}
+
+static int __init hangcheck_parse_reboot(char *str)
+{
+ int par;
+ if (get_option(&str,&par))
+ hangcheck_reboot = par;
+ return 1;
+}
+
+static int __init hangcheck_parse_dump_tasks(char *str)
+{
+ int par;
+ if (get_option(&str,&par))
+ hangcheck_dump_tasks = par;
+ return 1;
+}
+
+__setup("hcheck_tick", hangcheck_parse_tick);
+__setup("hcheck_margin", hangcheck_parse_margin);
+__setup("hcheck_reboot", hangcheck_parse_reboot);
+__setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks);
+#endif /* not MODULE */
+
+#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
+# define HAVE_MONOTONIC
+# define TIMER_FREQ 1000000000ULL
+#elif defined(CONFIG_ARCH_S390)
+/* FA240000 is 1 Second in the IBM time universe (Page 4-38 Principles of Op for zSeries */
+# define TIMER_FREQ 0xFA240000ULL
+#elif defined(CONFIG_IA64)
+# define TIMER_FREQ ((unsigned long long)local_cpu_data->itc_freq)
+#elif defined(CONFIG_PPC64)
+# define TIMER_FREQ (HZ*loops_per_jiffy)
+#endif
+
+#ifdef HAVE_MONOTONIC
+extern unsigned long long monotonic_clock(void);
+#else
+static inline unsigned long long monotonic_clock(void)
+{
+# ifdef __s390__
+ /* returns the TOD. see 4-38 Principles of Op of zSeries */
+ return get_clock();
+# else
+ return get_cycles();
+# endif /* __s390__ */
+}
+#endif /* HAVE_MONOTONIC */
/* Last time scheduled */
@@ -78,7 +152,6 @@ static void hangcheck_fire(unsigned long);
static struct timer_list hangcheck_ticktock =
TIMER_INITIALIZER(hangcheck_fire, 0, 0);
-extern unsigned long long monotonic_clock(void);
static void hangcheck_fire(unsigned long data)
{
@@ -92,6 +165,12 @@ static void hangcheck_fire(unsigned long data)
tsc_diff = (cur_tsc + (~0ULL - hangcheck_tsc)); /* or something */
if (tsc_diff > hangcheck_tsc_margin) {
+ if (hangcheck_dump_tasks) {
+ printk(KERN_CRIT "Hangcheck: Task state:\n");
+#ifdef CONFIG_MAGIC_SYSRQ
+ handle_sysrq('t', NULL, NULL);
+#endif /* CONFIG_MAGIC_SYSRQ */
+ }
if (hangcheck_reboot) {
printk(KERN_CRIT "Hangcheck: hangcheck is restarting the machine.\n");
machine_restart(NULL);
@@ -108,10 +187,16 @@ static int __init hangcheck_init(void)
{
printk("Hangcheck: starting hangcheck timer %s (tick is %d seconds, margin is %d seconds).\n",
VERSION_STR, hangcheck_tick, hangcheck_margin);
-
- hangcheck_tsc_margin = hangcheck_margin + hangcheck_tick;
- hangcheck_tsc_margin *= 1000000000;
-
+#if defined (HAVE_MONOTONIC)
+ printk("Hangcheck: Using monotonic_clock().\n");
+#elif defined(__s390__)
+ printk("Hangcheck: Using TOD.\n");
+#else
+ printk("Hangcheck: Using get_cycles().\n");
+#endif /* HAVE_MONOTONIC */
+ hangcheck_tsc_margin =
+ (unsigned long long)(hangcheck_margin + hangcheck_tick);
+ hangcheck_tsc_margin *= (unsigned long long)TIMER_FREQ;
hangcheck_tsc = monotonic_clock();
mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ));
@@ -123,6 +208,7 @@ static int __init hangcheck_init(void)
static void __exit hangcheck_exit(void)
{
del_timer_sync(&hangcheck_ticktock);
+ printk("Hangcheck: Stopped hangcheck timer.\n");
}
module_init(hangcheck_init);
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c
index 225b330115b..5ce9c626903 100644
--- a/drivers/char/ipmi/ipmi_bt_sm.c
+++ b/drivers/char/ipmi/ipmi_bt_sm.c
@@ -235,7 +235,6 @@ static void reset_flags(struct si_sm_data *bt)
if (BT_STATUS & BT_B_BUSY) BT_CONTROL(BT_B_BUSY);
BT_CONTROL(BT_CLR_WR_PTR);
BT_CONTROL(BT_SMS_ATN);
- BT_INTMASK_W(BT_BMC_HWRST);
#ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION
if (BT_STATUS & BT_B2H_ATN) {
int i;
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index a6606a1aced..d7fb452af7f 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -2588,28 +2588,20 @@ handle_msg_timeout(struct ipmi_recv_msg *msg)
deliver_response(msg);
}
-static void
-send_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg,
- struct ipmi_smi_msg *smi_msg,
- unsigned char seq, long seqid)
+static struct ipmi_smi_msg *
+smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg,
+ unsigned char seq, long seqid)
{
- if (!smi_msg)
- smi_msg = ipmi_alloc_smi_msg();
+ struct ipmi_smi_msg *smi_msg = ipmi_alloc_smi_msg();
if (!smi_msg)
/* If we can't allocate the message, then just return, we
get 4 retries, so this should be ok. */
- return;
+ return NULL;
memcpy(smi_msg->data, recv_msg->msg.data, recv_msg->msg.data_len);
smi_msg->data_size = recv_msg->msg.data_len;
smi_msg->msgid = STORE_SEQ_IN_MSGID(seq, seqid);
- /* Send the new message. We send with a zero priority. It
- timed out, I doubt time is that critical now, and high
- priority messages are really only for messages to the local
- MC, which don't get resent. */
- intf->handlers->sender(intf->send_info, smi_msg, 0);
-
#ifdef DEBUG_MSGING
{
int m;
@@ -2619,6 +2611,7 @@ send_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg,
printk("\n");
}
#endif
+ return smi_msg;
}
static void
@@ -2683,14 +2676,13 @@ ipmi_timeout_handler(long timeout_period)
intf->timed_out_ipmb_commands++;
spin_unlock(&intf->counter_lock);
} else {
+ struct ipmi_smi_msg *smi_msg;
/* More retries, send again. */
/* Start with the max timer, set to normal
timer after the message is sent. */
ent->timeout = MAX_MSG_TIMEOUT;
ent->retries_left--;
- send_from_recv_msg(intf, ent->recv_msg, NULL,
- j, ent->seqid);
spin_lock(&intf->counter_lock);
if (ent->recv_msg->addr.addr_type
== IPMI_LAN_ADDR_TYPE)
@@ -2698,6 +2690,20 @@ ipmi_timeout_handler(long timeout_period)
else
intf->retransmitted_ipmb_commands++;
spin_unlock(&intf->counter_lock);
+ smi_msg = smi_from_recv_msg(intf,
+ ent->recv_msg, j, ent->seqid);
+ if(!smi_msg)
+ continue;
+
+ spin_unlock_irqrestore(&(intf->seq_lock),flags);
+ /* Send the new message. We send with a zero
+ * priority. It timed out, I doubt time is
+ * that critical now, and high priority
+ * messages are really only for messages to the
+ * local MC, which don't get resent. */
+ intf->handlers->sender(intf->send_info,
+ smi_msg, 0);
+ spin_lock_irqsave(&(intf->seq_lock), flags);
}
}
spin_unlock_irqrestore(&(intf->seq_lock), flags);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 29de259a981..298574e1606 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -100,6 +100,11 @@ enum si_intf_state {
/* FIXME - add watchdog stuff. */
};
+/* Some BT-specific defines we need here. */
+#define IPMI_BT_INTMASK_REG 2
+#define IPMI_BT_INTMASK_CLEAR_IRQ_BIT 2
+#define IPMI_BT_INTMASK_ENABLE_IRQ_BIT 1
+
enum si_type {
SI_KCS, SI_SMIC, SI_BT
};
@@ -875,6 +880,17 @@ static irqreturn_t si_irq_handler(int irq, void *data, struct pt_regs *regs)
return IRQ_HANDLED;
}
+static irqreturn_t si_bt_irq_handler(int irq, void *data, struct pt_regs *regs)
+{
+ struct smi_info *smi_info = data;
+ /* We need to clear the IRQ flag for the BT interface. */
+ smi_info->io.outputb(&smi_info->io, IPMI_BT_INTMASK_REG,
+ IPMI_BT_INTMASK_CLEAR_IRQ_BIT
+ | IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
+ return si_irq_handler(irq, data, regs);
+}
+
+
static struct ipmi_smi_handlers handlers =
{
.owner = THIS_MODULE,
@@ -1001,11 +1017,22 @@ static int std_irq_setup(struct smi_info *info)
if (!info->irq)
return 0;
- rv = request_irq(info->irq,
- si_irq_handler,
- SA_INTERRUPT,
- DEVICE_NAME,
- info);
+ if (info->si_type == SI_BT) {
+ rv = request_irq(info->irq,
+ si_bt_irq_handler,
+ SA_INTERRUPT,
+ DEVICE_NAME,
+ info);
+ if (!rv)
+ /* Enable the interrupt in the BT interface. */
+ info->io.outputb(&info->io, IPMI_BT_INTMASK_REG,
+ IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
+ } else
+ rv = request_irq(info->irq,
+ si_irq_handler,
+ SA_INTERRUPT,
+ DEVICE_NAME,
+ info);
if (rv) {
printk(KERN_WARNING
"ipmi_si: %s unable to claim interrupt %d,"
@@ -1024,6 +1051,9 @@ static void std_irq_cleanup(struct smi_info *info)
if (!info->irq)
return;
+ if (info->si_type == SI_BT)
+ /* Disable the interrupt in the BT interface. */
+ info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, 0);
free_irq(info->irq, info);
}
@@ -1526,8 +1556,17 @@ static int try_init_acpi(int intf_num, struct smi_info **new_info)
info->irq_setup = NULL;
}
- regspacings[intf_num] = spmi->addr.register_bit_width / 8;
- info->io.regspacing = spmi->addr.register_bit_width / 8;
+ if (spmi->addr.register_bit_width) {
+ /* A (hopefully) properly formed register bit width. */
+ regspacings[intf_num] = spmi->addr.register_bit_width / 8;
+ info->io.regspacing = spmi->addr.register_bit_width / 8;
+ } else {
+ /* Some broken systems get this wrong and set the value
+ * to zero. Assume it is the default spacing. If that
+ * is wrong, too bad, the vendor should fix the tables. */
+ regspacings[intf_num] = DEFAULT_REGSPACING;
+ info->io.regspacing = DEFAULT_REGSPACING;
+ }
regsizes[intf_num] = regspacings[intf_num];
info->io.regsize = regsizes[intf_num];
regshifts[intf_num] = spmi->addr.register_bit_offset;
@@ -1578,15 +1617,15 @@ typedef struct dmi_header
u16 handle;
} dmi_header_t;
-static int decode_dmi(dmi_header_t *dm, int intf_num)
+static int decode_dmi(dmi_header_t __iomem *dm, int intf_num)
{
- u8 *data = (u8 *)dm;
+ u8 __iomem *data = (u8 __iomem *)dm;
unsigned long base_addr;
u8 reg_spacing;
- u8 len = dm->length;
+ u8 len = readb(&dm->length);
dmi_ipmi_data_t *ipmi_data = dmi_data+intf_num;
- ipmi_data->type = data[4];
+ ipmi_data->type = readb(&data[4]);
memcpy(&base_addr, data+8, sizeof(unsigned long));
if (len >= 0x11) {
@@ -1601,12 +1640,12 @@ static int decode_dmi(dmi_header_t *dm, int intf_num)
}
/* If bit 4 of byte 0x10 is set, then the lsb for the address
is odd. */
- ipmi_data->base_addr = base_addr | ((data[0x10] & 0x10) >> 4);
+ ipmi_data->base_addr = base_addr | ((readb(&data[0x10]) & 0x10) >> 4);
- ipmi_data->irq = data[0x11];
+ ipmi_data->irq = readb(&data[0x11]);
/* The top two bits of byte 0x10 hold the register spacing. */
- reg_spacing = (data[0x10] & 0xC0) >> 6;
+ reg_spacing = (readb(&data[0x10]) & 0xC0) >> 6;
switch(reg_spacing){
case 0x00: /* Byte boundaries */
ipmi_data->offset = 1;
@@ -1623,12 +1662,18 @@ static int decode_dmi(dmi_header_t *dm, int intf_num)
}
} else {
/* Old DMI spec. */
- ipmi_data->base_addr = base_addr;
+ /* Note that technically, the lower bit of the base
+ * address should be 1 if the address is I/O and 0 if
+ * the address is in memory. So many systems get that
+ * wrong (and all that I have seen are I/O) so we just
+ * ignore that bit and assume I/O. Systems that use
+ * memory should use the newer spec, anyway. */
+ ipmi_data->base_addr = base_addr & 0xfffe;
ipmi_data->addr_space = IPMI_IO_ADDR_SPACE;
ipmi_data->offset = 1;
}
- ipmi_data->slave_addr = data[6];
+ ipmi_data->slave_addr = readb(&data[6]);
if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr)) {
dmi_data_entries++;
@@ -1642,9 +1687,9 @@ static int decode_dmi(dmi_header_t *dm, int intf_num)
static int dmi_table(u32 base, int len, int num)
{
- u8 *buf;
- struct dmi_header *dm;
- u8 *data;
+ u8 __iomem *buf;
+ struct dmi_header __iomem *dm;
+ u8 __iomem *data;
int i=1;
int status=-1;
int intf_num = 0;
@@ -1657,12 +1702,12 @@ static int dmi_table(u32 base, int len, int num)
while(i<num && (data - buf) < len)
{
- dm=(dmi_header_t *)data;
+ dm=(dmi_header_t __iomem *)data;
- if((data-buf+dm->length) >= len)
+ if((data-buf+readb(&dm->length)) >= len)
break;
- if (dm->type == 38) {
+ if (readb(&dm->type) == 38) {
if (decode_dmi(dm, intf_num) == 0) {
intf_num++;
if (intf_num >= SI_MAX_DRIVERS)
@@ -1670,8 +1715,8 @@ static int dmi_table(u32 base, int len, int num)
}
}
- data+=dm->length;
- while((data-buf) < len && (*data || data[1]))
+ data+=readb(&dm->length);
+ while((data-buf) < len && (readb(data)||readb(data+1)))
data++;
data+=2;
i++;
@@ -2199,7 +2244,7 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
/* Wait until we know that we are out of any interrupt
handlers might have been running before we freed the
interrupt. */
- synchronize_kernel();
+ synchronize_sched();
if (new_smi->si_sm) {
if (new_smi->handlers)
@@ -2312,7 +2357,7 @@ static void __exit cleanup_one_si(struct smi_info *to_clean)
/* Wait until we know that we are out of any interrupt
handlers might have been running before we freed the
interrupt. */
- synchronize_kernel();
+ synchronize_sched();
/* Wait for the timer to stop. This avoids problems with race
conditions removing the timer here. */
diff --git a/drivers/char/ipmi/ipmi_si_sm.h b/drivers/char/ipmi/ipmi_si_sm.h
index a0212b00401..62791dd4298 100644
--- a/drivers/char/ipmi/ipmi_si_sm.h
+++ b/drivers/char/ipmi/ipmi_si_sm.h
@@ -51,7 +51,7 @@ struct si_sm_io
/* Generic info used by the actual handling routines, the
state machine shouldn't touch these. */
void *info;
- void *addr;
+ void __iomem *addr;
int regspacing;
int regsize;
int regshift;
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index fd7093879c6..fcd1c02a32c 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -709,11 +709,11 @@ static int ipmi_close(struct inode *ino, struct file *filep)
if (expect_close == 42) {
ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
- clear_bit(0, &ipmi_wdog_open);
} else {
printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
ipmi_heartbeat();
}
+ clear_bit(0, &ipmi_wdog_open);
}
ipmi_fasync (-1, filep, 0);
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 3ce51c6a1b1..7b19e02f112 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -1026,7 +1026,8 @@ static void kbd_rawcode(unsigned char data)
put_queue(vc, data);
}
-void kbd_keycode(unsigned int keycode, int down, int hw_raw, struct pt_regs *regs)
+static void kbd_keycode(unsigned int keycode, int down,
+ int hw_raw, struct pt_regs *regs)
{
struct vc_data *vc = vc_cons[fg_console].d;
unsigned short keysym, *key_map;
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
new file mode 100644
index 00000000000..ac9cfa9701e
--- /dev/null
+++ b/drivers/char/mbcs.c
@@ -0,0 +1,849 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2005 Silicon Graphics, Inc. All rights reserved.
+ */
+
+/*
+ * MOATB Core Services driver.
+ */
+
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/uio.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/tiocx.h>
+#include "mbcs.h"
+
+#define MBCS_DEBUG 0
+#if MBCS_DEBUG
+#define DBG(fmt...) printk(KERN_ALERT fmt)
+#else
+#define DBG(fmt...)
+#endif
+int mbcs_major;
+
+LIST_HEAD(soft_list);
+
+/*
+ * file operations
+ */
+struct file_operations mbcs_ops = {
+ .open = mbcs_open,
+ .llseek = mbcs_sram_llseek,
+ .read = mbcs_sram_read,
+ .write = mbcs_sram_write,
+ .mmap = mbcs_gscr_mmap,
+};
+
+struct mbcs_callback_arg {
+ int minor;
+ struct cx_dev *cx_dev;
+};
+
+static inline void mbcs_getdma_init(struct getdma *gdma)
+{
+ memset(gdma, 0, sizeof(struct getdma));
+ gdma->DoneIntEnable = 1;
+}
+
+static inline void mbcs_putdma_init(struct putdma *pdma)
+{
+ memset(pdma, 0, sizeof(struct putdma));
+ pdma->DoneIntEnable = 1;
+}
+
+static inline void mbcs_algo_init(struct algoblock *algo_soft)
+{
+ memset(algo_soft, 0, sizeof(struct algoblock));
+}
+
+static inline void mbcs_getdma_set(void *mmr,
+ uint64_t hostAddr,
+ uint64_t localAddr,
+ uint64_t localRamSel,
+ uint64_t numPkts,
+ uint64_t amoEnable,
+ uint64_t intrEnable,
+ uint64_t peerIO,
+ uint64_t amoHostDest,
+ uint64_t amoModType, uint64_t intrHostDest,
+ uint64_t intrVector)
+{
+ union dma_control rdma_control;
+ union dma_amo_dest amo_dest;
+ union intr_dest intr_dest;
+ union dma_localaddr local_addr;
+ union dma_hostaddr host_addr;
+
+ rdma_control.dma_control_reg = 0;
+ amo_dest.dma_amo_dest_reg = 0;
+ intr_dest.intr_dest_reg = 0;
+ local_addr.dma_localaddr_reg = 0;
+ host_addr.dma_hostaddr_reg = 0;
+
+ host_addr.dma_sys_addr = hostAddr;
+ MBCS_MMR_SET(mmr, MBCS_RD_DMA_SYS_ADDR, host_addr.dma_hostaddr_reg);
+
+ local_addr.dma_ram_addr = localAddr;
+ local_addr.dma_ram_sel = localRamSel;
+ MBCS_MMR_SET(mmr, MBCS_RD_DMA_LOC_ADDR, local_addr.dma_localaddr_reg);
+
+ rdma_control.dma_op_length = numPkts;
+ rdma_control.done_amo_en = amoEnable;
+ rdma_control.done_int_en = intrEnable;
+ rdma_control.pio_mem_n = peerIO;
+ MBCS_MMR_SET(mmr, MBCS_RD_DMA_CTRL, rdma_control.dma_control_reg);
+
+ amo_dest.dma_amo_sys_addr = amoHostDest;
+ amo_dest.dma_amo_mod_type = amoModType;
+ MBCS_MMR_SET(mmr, MBCS_RD_DMA_AMO_DEST, amo_dest.dma_amo_dest_reg);
+
+ intr_dest.address = intrHostDest;
+ intr_dest.int_vector = intrVector;
+ MBCS_MMR_SET(mmr, MBCS_RD_DMA_INT_DEST, intr_dest.intr_dest_reg);
+
+}
+
+static inline void mbcs_putdma_set(void *mmr,
+ uint64_t hostAddr,
+ uint64_t localAddr,
+ uint64_t localRamSel,
+ uint64_t numPkts,
+ uint64_t amoEnable,
+ uint64_t intrEnable,
+ uint64_t peerIO,
+ uint64_t amoHostDest,
+ uint64_t amoModType,
+ uint64_t intrHostDest, uint64_t intrVector)
+{
+ union dma_control wdma_control;
+ union dma_amo_dest amo_dest;
+ union intr_dest intr_dest;
+ union dma_localaddr local_addr;
+ union dma_hostaddr host_addr;
+
+ wdma_control.dma_control_reg = 0;
+ amo_dest.dma_amo_dest_reg = 0;
+ intr_dest.intr_dest_reg = 0;
+ local_addr.dma_localaddr_reg = 0;
+ host_addr.dma_hostaddr_reg = 0;
+
+ host_addr.dma_sys_addr = hostAddr;
+ MBCS_MMR_SET(mmr, MBCS_WR_DMA_SYS_ADDR, host_addr.dma_hostaddr_reg);
+
+ local_addr.dma_ram_addr = localAddr;
+ local_addr.dma_ram_sel = localRamSel;
+ MBCS_MMR_SET(mmr, MBCS_WR_DMA_LOC_ADDR, local_addr.dma_localaddr_reg);
+
+ wdma_control.dma_op_length = numPkts;
+ wdma_control.done_amo_en = amoEnable;
+ wdma_control.done_int_en = intrEnable;
+ wdma_control.pio_mem_n = peerIO;
+ MBCS_MMR_SET(mmr, MBCS_WR_DMA_CTRL, wdma_control.dma_control_reg);
+
+ amo_dest.dma_amo_sys_addr = amoHostDest;
+ amo_dest.dma_amo_mod_type = amoModType;
+ MBCS_MMR_SET(mmr, MBCS_WR_DMA_AMO_DEST, amo_dest.dma_amo_dest_reg);
+
+ intr_dest.address = intrHostDest;
+ intr_dest.int_vector = intrVector;
+ MBCS_MMR_SET(mmr, MBCS_WR_DMA_INT_DEST, intr_dest.intr_dest_reg);
+
+}
+
+static inline void mbcs_algo_set(void *mmr,
+ uint64_t amoHostDest,
+ uint64_t amoModType,
+ uint64_t intrHostDest,
+ uint64_t intrVector, uint64_t algoStepCount)
+{
+ union dma_amo_dest amo_dest;
+ union intr_dest intr_dest;
+ union algo_step step;
+
+ step.algo_step_reg = 0;
+ intr_dest.intr_dest_reg = 0;
+ amo_dest.dma_amo_dest_reg = 0;
+
+ amo_dest.dma_amo_sys_addr = amoHostDest;
+ amo_dest.dma_amo_mod_type = amoModType;
+ MBCS_MMR_SET(mmr, MBCS_ALG_AMO_DEST, amo_dest.dma_amo_dest_reg);
+
+ intr_dest.address = intrHostDest;
+ intr_dest.int_vector = intrVector;
+ MBCS_MMR_SET(mmr, MBCS_ALG_INT_DEST, intr_dest.intr_dest_reg);
+
+ step.alg_step_cnt = algoStepCount;
+ MBCS_MMR_SET(mmr, MBCS_ALG_STEP, step.algo_step_reg);
+}
+
+static inline int mbcs_getdma_start(struct mbcs_soft *soft)
+{
+ void *mmr_base;
+ struct getdma *gdma;
+ uint64_t numPkts;
+ union cm_control cm_control;
+
+ mmr_base = soft->mmr_base;
+ gdma = &soft->getdma;
+
+ /* check that host address got setup */
+ if (!gdma->hostAddr)
+ return -1;
+
+ numPkts =
+ (gdma->bytes + (MBCS_CACHELINE_SIZE - 1)) / MBCS_CACHELINE_SIZE;
+
+ /* program engine */
+ mbcs_getdma_set(mmr_base, tiocx_dma_addr(gdma->hostAddr),
+ gdma->localAddr,
+ (gdma->localAddr < MB2) ? 0 :
+ (gdma->localAddr < MB4) ? 1 :
+ (gdma->localAddr < MB6) ? 2 : 3,
+ numPkts,
+ gdma->DoneAmoEnable,
+ gdma->DoneIntEnable,
+ gdma->peerIO,
+ gdma->amoHostDest,
+ gdma->amoModType,
+ gdma->intrHostDest, gdma->intrVector);
+
+ /* start engine */
+ cm_control.cm_control_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL);
+ cm_control.rd_dma_go = 1;
+ MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, cm_control.cm_control_reg);
+
+ return 0;
+
+}
+
+static inline int mbcs_putdma_start(struct mbcs_soft *soft)
+{
+ void *mmr_base;
+ struct putdma *pdma;
+ uint64_t numPkts;
+ union cm_control cm_control;
+
+ mmr_base = soft->mmr_base;
+ pdma = &soft->putdma;
+
+ /* check that host address got setup */
+ if (!pdma->hostAddr)
+ return -1;
+
+ numPkts =
+ (pdma->bytes + (MBCS_CACHELINE_SIZE - 1)) / MBCS_CACHELINE_SIZE;
+
+ /* program engine */
+ mbcs_putdma_set(mmr_base, tiocx_dma_addr(pdma->hostAddr),
+ pdma->localAddr,
+ (pdma->localAddr < MB2) ? 0 :
+ (pdma->localAddr < MB4) ? 1 :
+ (pdma->localAddr < MB6) ? 2 : 3,
+ numPkts,
+ pdma->DoneAmoEnable,
+ pdma->DoneIntEnable,
+ pdma->peerIO,
+ pdma->amoHostDest,
+ pdma->amoModType,
+ pdma->intrHostDest, pdma->intrVector);
+
+ /* start engine */
+ cm_control.cm_control_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL);
+ cm_control.wr_dma_go = 1;
+ MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, cm_control.cm_control_reg);
+
+ return 0;
+
+}
+
+static inline int mbcs_algo_start(struct mbcs_soft *soft)
+{
+ struct algoblock *algo_soft = &soft->algo;
+ void *mmr_base = soft->mmr_base;
+ union cm_control cm_control;
+
+ if (down_interruptible(&soft->algolock))
+ return -ERESTARTSYS;
+
+ atomic_set(&soft->algo_done, 0);
+
+ mbcs_algo_set(mmr_base,
+ algo_soft->amoHostDest,
+ algo_soft->amoModType,
+ algo_soft->intrHostDest,
+ algo_soft->intrVector, algo_soft->algoStepCount);
+
+ /* start algorithm */
+ cm_control.cm_control_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL);
+ cm_control.alg_done_int_en = 1;
+ cm_control.alg_go = 1;
+ MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, cm_control.cm_control_reg);
+
+ up(&soft->algolock);
+
+ return 0;
+}
+
+static inline ssize_t
+do_mbcs_sram_dmawrite(struct mbcs_soft *soft, uint64_t hostAddr,
+ size_t len, loff_t * off)
+{
+ int rv = 0;
+
+ if (down_interruptible(&soft->dmawritelock))
+ return -ERESTARTSYS;
+
+ atomic_set(&soft->dmawrite_done, 0);
+
+ soft->putdma.hostAddr = hostAddr;
+ soft->putdma.localAddr = *off;
+ soft->putdma.bytes = len;
+
+ if (mbcs_putdma_start(soft) < 0) {
+ DBG(KERN_ALERT "do_mbcs_sram_dmawrite: "
+ "mbcs_putdma_start failed\n");
+ rv = -EAGAIN;
+ goto dmawrite_exit;
+ }
+
+ if (wait_event_interruptible(soft->dmawrite_queue,
+ atomic_read(&soft->dmawrite_done))) {
+ rv = -ERESTARTSYS;
+ goto dmawrite_exit;
+ }
+
+ rv = len;
+ *off += len;
+
+dmawrite_exit:
+ up(&soft->dmawritelock);
+
+ return rv;
+}
+
+static inline ssize_t
+do_mbcs_sram_dmaread(struct mbcs_soft *soft, uint64_t hostAddr,
+ size_t len, loff_t * off)
+{
+ int rv = 0;
+
+ if (down_interruptible(&soft->dmareadlock))
+ return -ERESTARTSYS;
+
+ atomic_set(&soft->dmawrite_done, 0);
+
+ soft->getdma.hostAddr = hostAddr;
+ soft->getdma.localAddr = *off;
+ soft->getdma.bytes = len;
+
+ if (mbcs_getdma_start(soft) < 0) {
+ DBG(KERN_ALERT "mbcs_strategy: mbcs_getdma_start failed\n");
+ rv = -EAGAIN;
+ goto dmaread_exit;
+ }
+
+ if (wait_event_interruptible(soft->dmaread_queue,
+ atomic_read(&soft->dmaread_done))) {
+ rv = -ERESTARTSYS;
+ goto dmaread_exit;
+ }
+
+ rv = len;
+ *off += len;
+
+dmaread_exit:
+ up(&soft->dmareadlock);
+
+ return rv;
+}
+
+int mbcs_open(struct inode *ip, struct file *fp)
+{
+ struct mbcs_soft *soft;
+ int minor;
+
+ minor = iminor(ip);
+
+ list_for_each_entry(soft, &soft_list, list) {
+ if (soft->nasid == minor) {
+ fp->private_data = soft->cxdev;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
+ssize_t mbcs_sram_read(struct file * fp, char __user *buf, size_t len, loff_t * off)
+{
+ struct cx_dev *cx_dev = fp->private_data;
+ struct mbcs_soft *soft = cx_dev->soft;
+ uint64_t hostAddr;
+ int rv = 0;
+
+ hostAddr = __get_dma_pages(GFP_KERNEL, get_order(len));
+ if (hostAddr == 0)
+ return -ENOMEM;
+
+ rv = do_mbcs_sram_dmawrite(soft, hostAddr, len, off);
+ if (rv < 0)
+ goto exit;
+
+ if (copy_to_user(buf, (void *)hostAddr, len))
+ rv = -EFAULT;
+
+ exit:
+ free_pages(hostAddr, get_order(len));
+
+ return rv;
+}
+
+ssize_t
+mbcs_sram_write(struct file * fp, const char __user *buf, size_t len, loff_t * off)
+{
+ struct cx_dev *cx_dev = fp->private_data;
+ struct mbcs_soft *soft = cx_dev->soft;
+ uint64_t hostAddr;
+ int rv = 0;
+
+ hostAddr = __get_dma_pages(GFP_KERNEL, get_order(len));
+ if (hostAddr == 0)
+ return -ENOMEM;
+
+ if (copy_from_user((void *)hostAddr, buf, len)) {
+ rv = -EFAULT;
+ goto exit;
+ }
+
+ rv = do_mbcs_sram_dmaread(soft, hostAddr, len, off);
+
+ exit:
+ free_pages(hostAddr, get_order(len));
+
+ return rv;
+}
+
+loff_t mbcs_sram_llseek(struct file * filp, loff_t off, int whence)
+{
+ loff_t newpos;
+
+ switch (whence) {
+ case 0: /* SEEK_SET */
+ newpos = off;
+ break;
+
+ case 1: /* SEEK_CUR */
+ newpos = filp->f_pos + off;
+ break;
+
+ case 2: /* SEEK_END */
+ newpos = MBCS_SRAM_SIZE + off;
+ break;
+
+ default: /* can't happen */
+ return -EINVAL;
+ }
+
+ if (newpos < 0)
+ return -EINVAL;
+
+ filp->f_pos = newpos;
+
+ return newpos;
+}
+
+static uint64_t mbcs_pioaddr(struct mbcs_soft *soft, uint64_t offset)
+{
+ uint64_t mmr_base;
+
+ mmr_base = (uint64_t) (soft->mmr_base + offset);
+
+ return mmr_base;
+}
+
+static void mbcs_debug_pioaddr_set(struct mbcs_soft *soft)
+{
+ soft->debug_addr = mbcs_pioaddr(soft, MBCS_DEBUG_START);
+}
+
+static void mbcs_gscr_pioaddr_set(struct mbcs_soft *soft)
+{
+ soft->gscr_addr = mbcs_pioaddr(soft, MBCS_GSCR_START);
+}
+
+int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma)
+{
+ struct cx_dev *cx_dev = fp->private_data;
+ struct mbcs_soft *soft = cx_dev->soft;
+
+ if (vma->vm_pgoff != 0)
+ return -EINVAL;
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
+ if (remap_pfn_range(vma,
+ vma->vm_start,
+ __pa(soft->gscr_addr) >> PAGE_SHIFT,
+ PAGE_SIZE,
+ vma->vm_page_prot))
+ return -EAGAIN;
+
+ return 0;
+}
+
+/**
+ * mbcs_completion_intr_handler - Primary completion handler.
+ * @irq: irq
+ * @arg: soft struct for device
+ * @ep: regs
+ *
+ */
+static irqreturn_t
+mbcs_completion_intr_handler(int irq, void *arg, struct pt_regs *ep)
+{
+ struct mbcs_soft *soft = (struct mbcs_soft *)arg;
+ void *mmr_base;
+ union cm_status cm_status;
+ union cm_control cm_control;
+
+ mmr_base = soft->mmr_base;
+ cm_status.cm_status_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_STATUS);
+
+ if (cm_status.rd_dma_done) {
+ /* stop dma-read engine, clear status */
+ cm_control.cm_control_reg =
+ MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL);
+ cm_control.rd_dma_clr = 1;
+ MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL,
+ cm_control.cm_control_reg);
+ atomic_set(&soft->dmaread_done, 1);
+ wake_up(&soft->dmaread_queue);
+ }
+ if (cm_status.wr_dma_done) {
+ /* stop dma-write engine, clear status */
+ cm_control.cm_control_reg =
+ MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL);
+ cm_control.wr_dma_clr = 1;
+ MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL,
+ cm_control.cm_control_reg);
+ atomic_set(&soft->dmawrite_done, 1);
+ wake_up(&soft->dmawrite_queue);
+ }
+ if (cm_status.alg_done) {
+ /* clear status */
+ cm_control.cm_control_reg =
+ MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL);
+ cm_control.alg_done_clr = 1;
+ MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL,
+ cm_control.cm_control_reg);
+ atomic_set(&soft->algo_done, 1);
+ wake_up(&soft->algo_queue);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * mbcs_intr_alloc - Allocate interrupts.
+ * @dev: device pointer
+ *
+ */
+static int mbcs_intr_alloc(struct cx_dev *dev)
+{
+ struct sn_irq_info *sn_irq;
+ struct mbcs_soft *soft;
+ struct getdma *getdma;
+ struct putdma *putdma;
+ struct algoblock *algo;
+
+ soft = dev->soft;
+ getdma = &soft->getdma;
+ putdma = &soft->putdma;
+ algo = &soft->algo;
+
+ soft->get_sn_irq = NULL;
+ soft->put_sn_irq = NULL;
+ soft->algo_sn_irq = NULL;
+
+ sn_irq = tiocx_irq_alloc(dev->cx_id.nasid, TIOCX_CORELET, -1, -1, -1);
+ if (sn_irq == NULL)
+ return -EAGAIN;
+ soft->get_sn_irq = sn_irq;
+ getdma->intrHostDest = sn_irq->irq_xtalkaddr;
+ getdma->intrVector = sn_irq->irq_irq;
+ if (request_irq(sn_irq->irq_irq,
+ (void *)mbcs_completion_intr_handler, SA_SHIRQ,
+ "MBCS get intr", (void *)soft)) {
+ tiocx_irq_free(soft->get_sn_irq);
+ return -EAGAIN;
+ }
+
+ sn_irq = tiocx_irq_alloc(dev->cx_id.nasid, TIOCX_CORELET, -1, -1, -1);
+ if (sn_irq == NULL) {
+ free_irq(soft->get_sn_irq->irq_irq, soft);
+ tiocx_irq_free(soft->get_sn_irq);
+ return -EAGAIN;
+ }
+ soft->put_sn_irq = sn_irq;
+ putdma->intrHostDest = sn_irq->irq_xtalkaddr;
+ putdma->intrVector = sn_irq->irq_irq;
+ if (request_irq(sn_irq->irq_irq,
+ (void *)mbcs_completion_intr_handler, SA_SHIRQ,
+ "MBCS put intr", (void *)soft)) {
+ tiocx_irq_free(soft->put_sn_irq);
+ free_irq(soft->get_sn_irq->irq_irq, soft);
+ tiocx_irq_free(soft->get_sn_irq);
+ return -EAGAIN;
+ }
+
+ sn_irq = tiocx_irq_alloc(dev->cx_id.nasid, TIOCX_CORELET, -1, -1, -1);
+ if (sn_irq == NULL) {
+ free_irq(soft->put_sn_irq->irq_irq, soft);
+ tiocx_irq_free(soft->put_sn_irq);
+ free_irq(soft->get_sn_irq->irq_irq, soft);
+ tiocx_irq_free(soft->get_sn_irq);
+ return -EAGAIN;
+ }
+ soft->algo_sn_irq = sn_irq;
+ algo->intrHostDest = sn_irq->irq_xtalkaddr;
+ algo->intrVector = sn_irq->irq_irq;
+ if (request_irq(sn_irq->irq_irq,
+ (void *)mbcs_completion_intr_handler, SA_SHIRQ,
+ "MBCS algo intr", (void *)soft)) {
+ tiocx_irq_free(soft->algo_sn_irq);
+ free_irq(soft->put_sn_irq->irq_irq, soft);
+ tiocx_irq_free(soft->put_sn_irq);
+ free_irq(soft->get_sn_irq->irq_irq, soft);
+ tiocx_irq_free(soft->get_sn_irq);
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
+/**
+ * mbcs_intr_dealloc - Remove interrupts.
+ * @dev: device pointer
+ *
+ */
+static void mbcs_intr_dealloc(struct cx_dev *dev)
+{
+ struct mbcs_soft *soft;
+
+ soft = dev->soft;
+
+ free_irq(soft->get_sn_irq->irq_irq, soft);
+ tiocx_irq_free(soft->get_sn_irq);
+ free_irq(soft->put_sn_irq->irq_irq, soft);
+ tiocx_irq_free(soft->put_sn_irq);
+ free_irq(soft->algo_sn_irq->irq_irq, soft);
+ tiocx_irq_free(soft->algo_sn_irq);
+}
+
+static inline int mbcs_hw_init(struct mbcs_soft *soft)
+{
+ void *mmr_base = soft->mmr_base;
+ union cm_control cm_control;
+ union cm_req_timeout cm_req_timeout;
+ uint64_t err_stat;
+
+ cm_req_timeout.cm_req_timeout_reg =
+ MBCS_MMR_GET(mmr_base, MBCS_CM_REQ_TOUT);
+
+ cm_req_timeout.time_out = MBCS_CM_CONTROL_REQ_TOUT_MASK;
+ MBCS_MMR_SET(mmr_base, MBCS_CM_REQ_TOUT,
+ cm_req_timeout.cm_req_timeout_reg);
+
+ mbcs_gscr_pioaddr_set(soft);
+ mbcs_debug_pioaddr_set(soft);
+
+ /* clear errors */
+ err_stat = MBCS_MMR_GET(mmr_base, MBCS_CM_ERR_STAT);
+ MBCS_MMR_SET(mmr_base, MBCS_CM_CLR_ERR_STAT, err_stat);
+ MBCS_MMR_ZERO(mmr_base, MBCS_CM_ERROR_DETAIL1);
+
+ /* enable interrupts */
+ /* turn off 2^23 (INT_EN_PIO_REQ_ADDR_INV) */
+ MBCS_MMR_SET(mmr_base, MBCS_CM_ERR_INT_EN, 0x3ffffff7e00ffUL);
+
+ /* arm status regs and clear engines */
+ cm_control.cm_control_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL);
+ cm_control.rearm_stat_regs = 1;
+ cm_control.alg_clr = 1;
+ cm_control.wr_dma_clr = 1;
+ cm_control.rd_dma_clr = 1;
+
+ MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, cm_control.cm_control_reg);
+
+ return 0;
+}
+
+static ssize_t show_algo(struct device *dev, char *buf)
+{
+ struct cx_dev *cx_dev = to_cx_dev(dev);
+ struct mbcs_soft *soft = cx_dev->soft;
+ uint64_t debug0;
+
+ /*
+ * By convention, the first debug register contains the
+ * algorithm number and revision.
+ */
+ debug0 = *(uint64_t *) soft->debug_addr;
+
+ return sprintf(buf, "0x%lx 0x%lx\n",
+ (debug0 >> 32), (debug0 & 0xffffffff));
+}
+
+static ssize_t store_algo(struct device *dev, const char *buf, size_t count)
+{
+ int n;
+ struct cx_dev *cx_dev = to_cx_dev(dev);
+ struct mbcs_soft *soft = cx_dev->soft;
+
+ if (count <= 0)
+ return 0;
+
+ n = simple_strtoul(buf, NULL, 0);
+
+ if (n == 1) {
+ mbcs_algo_start(soft);
+ if (wait_event_interruptible(soft->algo_queue,
+ atomic_read(&soft->algo_done)))
+ return -ERESTARTSYS;
+ }
+
+ return count;
+}
+
+DEVICE_ATTR(algo, 0644, show_algo, store_algo);
+
+/**
+ * mbcs_probe - Initialize for device
+ * @dev: device pointer
+ * @device_id: id table pointer
+ *
+ */
+static int mbcs_probe(struct cx_dev *dev, const struct cx_device_id *id)
+{
+ struct mbcs_soft *soft;
+
+ dev->soft = NULL;
+
+ soft = kcalloc(1, sizeof(struct mbcs_soft), GFP_KERNEL);
+ if (soft == NULL)
+ return -ENOMEM;
+
+ soft->nasid = dev->cx_id.nasid;
+ list_add(&soft->list, &soft_list);
+ soft->mmr_base = (void *)tiocx_swin_base(dev->cx_id.nasid);
+ dev->soft = soft;
+ soft->cxdev = dev;
+
+ init_waitqueue_head(&soft->dmawrite_queue);
+ init_waitqueue_head(&soft->dmaread_queue);
+ init_waitqueue_head(&soft->algo_queue);
+
+ init_MUTEX(&soft->dmawritelock);
+ init_MUTEX(&soft->dmareadlock);
+ init_MUTEX(&soft->algolock);
+
+ mbcs_getdma_init(&soft->getdma);
+ mbcs_putdma_init(&soft->putdma);
+ mbcs_algo_init(&soft->algo);
+
+ mbcs_hw_init(soft);
+
+ /* Allocate interrupts */
+ mbcs_intr_alloc(dev);
+
+ device_create_file(&dev->dev, &dev_attr_algo);
+
+ return 0;
+}
+
+static int mbcs_remove(struct cx_dev *dev)
+{
+ if (dev->soft) {
+ mbcs_intr_dealloc(dev);
+ kfree(dev->soft);
+ }
+
+ device_remove_file(&dev->dev, &dev_attr_algo);
+
+ return 0;
+}
+
+const struct cx_device_id __devinitdata mbcs_id_table[] = {
+ {
+ .part_num = MBCS_PART_NUM,
+ .mfg_num = MBCS_MFG_NUM,
+ },
+ {
+ .part_num = MBCS_PART_NUM_ALG0,
+ .mfg_num = MBCS_MFG_NUM,
+ },
+ {0, 0}
+};
+
+MODULE_DEVICE_TABLE(cx, mbcs_id_table);
+
+struct cx_drv mbcs_driver = {
+ .name = DEVICE_NAME,
+ .id_table = mbcs_id_table,
+ .probe = mbcs_probe,
+ .remove = mbcs_remove,
+};
+
+static void __exit mbcs_exit(void)
+{
+ int rv;
+
+ rv = unregister_chrdev(mbcs_major, DEVICE_NAME);
+ if (rv < 0)
+ DBG(KERN_ALERT "Error in unregister_chrdev: %d\n", rv);
+
+ cx_driver_unregister(&mbcs_driver);
+}
+
+static int __init mbcs_init(void)
+{
+ int rv;
+
+ // Put driver into chrdevs[]. Get major number.
+ rv = register_chrdev(mbcs_major, DEVICE_NAME, &mbcs_ops);
+ if (rv < 0) {
+ DBG(KERN_ALERT "mbcs_init: can't get major number. %d\n", rv);
+ return rv;
+ }
+ mbcs_major = rv;
+
+ return cx_driver_register(&mbcs_driver);
+}
+
+module_init(mbcs_init);
+module_exit(mbcs_exit);
+
+MODULE_AUTHOR("Bruce Losure <blosure@sgi.com>");
+MODULE_DESCRIPTION("Driver for MOATB Core Services");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/mbcs.h b/drivers/char/mbcs.h
new file mode 100644
index 00000000000..e7fd47e4325
--- /dev/null
+++ b/drivers/char/mbcs.h
@@ -0,0 +1,553 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2005 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#ifndef __MBCS_H__
+#define __MBCS_H__
+
+/*
+ * General macros
+ */
+#define MB (1024*1024)
+#define MB2 (2*MB)
+#define MB4 (4*MB)
+#define MB6 (6*MB)
+
+/*
+ * Offsets and masks
+ */
+#define MBCS_CM_ID 0x0000 /* Identification */
+#define MBCS_CM_STATUS 0x0008 /* Status */
+#define MBCS_CM_ERROR_DETAIL1 0x0010 /* Error Detail1 */
+#define MBCS_CM_ERROR_DETAIL2 0x0018 /* Error Detail2 */
+#define MBCS_CM_CONTROL 0x0020 /* Control */
+#define MBCS_CM_REQ_TOUT 0x0028 /* Request Time-out */
+#define MBCS_CM_ERR_INT_DEST 0x0038 /* Error Interrupt Destination */
+#define MBCS_CM_TARG_FL 0x0050 /* Target Flush */
+#define MBCS_CM_ERR_STAT 0x0060 /* Error Status */
+#define MBCS_CM_CLR_ERR_STAT 0x0068 /* Clear Error Status */
+#define MBCS_CM_ERR_INT_EN 0x0070 /* Error Interrupt Enable */
+#define MBCS_RD_DMA_SYS_ADDR 0x0100 /* Read DMA System Address */
+#define MBCS_RD_DMA_LOC_ADDR 0x0108 /* Read DMA Local Address */
+#define MBCS_RD_DMA_CTRL 0x0110 /* Read DMA Control */
+#define MBCS_RD_DMA_AMO_DEST 0x0118 /* Read DMA AMO Destination */
+#define MBCS_RD_DMA_INT_DEST 0x0120 /* Read DMA Interrupt Destination */
+#define MBCS_RD_DMA_AUX_STAT 0x0130 /* Read DMA Auxillary Status */
+#define MBCS_WR_DMA_SYS_ADDR 0x0200 /* Write DMA System Address */
+#define MBCS_WR_DMA_LOC_ADDR 0x0208 /* Write DMA Local Address */
+#define MBCS_WR_DMA_CTRL 0x0210 /* Write DMA Control */
+#define MBCS_WR_DMA_AMO_DEST 0x0218 /* Write DMA AMO Destination */
+#define MBCS_WR_DMA_INT_DEST 0x0220 /* Write DMA Interrupt Destination */
+#define MBCS_WR_DMA_AUX_STAT 0x0230 /* Write DMA Auxillary Status */
+#define MBCS_ALG_AMO_DEST 0x0300 /* Algorithm AMO Destination */
+#define MBCS_ALG_INT_DEST 0x0308 /* Algorithm Interrupt Destination */
+#define MBCS_ALG_OFFSETS 0x0310
+#define MBCS_ALG_STEP 0x0318 /* Algorithm Step */
+
+#define MBCS_GSCR_START 0x0000000
+#define MBCS_DEBUG_START 0x0100000
+#define MBCS_RAM0_START 0x0200000
+#define MBCS_RAM1_START 0x0400000
+#define MBCS_RAM2_START 0x0600000
+
+#define MBCS_CM_CONTROL_REQ_TOUT_MASK 0x0000000000ffffffUL
+//#define PIO_BASE_ADDR_BASE_OFFSET_MASK 0x00fffffffff00000UL
+
+#define MBCS_SRAM_SIZE (1024*1024)
+#define MBCS_CACHELINE_SIZE 128
+
+/*
+ * MMR get's and put's
+ */
+#define MBCS_MMR_ADDR(mmr_base, offset)((uint64_t *)(mmr_base + offset))
+#define MBCS_MMR_SET(mmr_base, offset, value) { \
+ uint64_t *mbcs_mmr_set_u64p, readback; \
+ mbcs_mmr_set_u64p = (uint64_t *)(mmr_base + offset); \
+ *mbcs_mmr_set_u64p = value; \
+ readback = *mbcs_mmr_set_u64p; \
+}
+#define MBCS_MMR_GET(mmr_base, offset) *(uint64_t *)(mmr_base + offset)
+#define MBCS_MMR_ZERO(mmr_base, offset) MBCS_MMR_SET(mmr_base, offset, 0)
+
+/*
+ * MBCS mmr structures
+ */
+union cm_id {
+ uint64_t cm_id_reg;
+ struct {
+ uint64_t always_one:1, // 0
+ mfg_id:11, // 11:1
+ part_num:16, // 27:12
+ bitstream_rev:8, // 35:28
+ :28; // 63:36
+ };
+};
+
+union cm_status {
+ uint64_t cm_status_reg;
+ struct {
+ uint64_t pending_reads:8, // 7:0
+ pending_writes:8, // 15:8
+ ice_rsp_credits:8, // 23:16
+ ice_req_credits:8, // 31:24
+ cm_req_credits:8, // 39:32
+ :1, // 40
+ rd_dma_in_progress:1, // 41
+ rd_dma_done:1, // 42
+ :1, // 43
+ wr_dma_in_progress:1, // 44
+ wr_dma_done:1, // 45
+ alg_waiting:1, // 46
+ alg_pipe_running:1, // 47
+ alg_done:1, // 48
+ :3, // 51:49
+ pending_int_reqs:8, // 59:52
+ :3, // 62:60
+ alg_half_speed_sel:1; // 63
+ };
+};
+
+union cm_error_detail1 {
+ uint64_t cm_error_detail1_reg;
+ struct {
+ uint64_t packet_type:4, // 3:0
+ source_id:2, // 5:4
+ data_size:2, // 7:6
+ tnum:8, // 15:8
+ byte_enable:8, // 23:16
+ gfx_cred:8, // 31:24
+ read_type:2, // 33:32
+ pio_or_memory:1, // 34
+ head_cw_error:1, // 35
+ :12, // 47:36
+ head_error_bit:1, // 48
+ data_error_bit:1, // 49
+ :13, // 62:50
+ valid:1; // 63
+ };
+};
+
+union cm_error_detail2 {
+ uint64_t cm_error_detail2_reg;
+ struct {
+ uint64_t address:56, // 55:0
+ :8; // 63:56
+ };
+};
+
+union cm_control {
+ uint64_t cm_control_reg;
+ struct {
+ uint64_t cm_id:2, // 1:0
+ :2, // 3:2
+ max_trans:5, // 8:4
+ :3, // 11:9
+ address_mode:1, // 12
+ :7, // 19:13
+ credit_limit:8, // 27:20
+ :5, // 32:28
+ rearm_stat_regs:1, // 33
+ prescalar_byp:1, // 34
+ force_gap_war:1, // 35
+ rd_dma_go:1, // 36
+ wr_dma_go:1, // 37
+ alg_go:1, // 38
+ rd_dma_clr:1, // 39
+ wr_dma_clr:1, // 40
+ alg_clr:1, // 41
+ :2, // 43:42
+ alg_wait_step:1, // 44
+ alg_done_amo_en:1, // 45
+ alg_done_int_en:1, // 46
+ :1, // 47
+ alg_sram0_locked:1, // 48
+ alg_sram1_locked:1, // 49
+ alg_sram2_locked:1, // 50
+ alg_done_clr:1, // 51
+ :12; // 63:52
+ };
+};
+
+union cm_req_timeout {
+ uint64_t cm_req_timeout_reg;
+ struct {
+ uint64_t time_out:24, // 23:0
+ :40; // 63:24
+ };
+};
+
+union intr_dest {
+ uint64_t intr_dest_reg;
+ struct {
+ uint64_t address:56, // 55:0
+ int_vector:8; // 63:56
+ };
+};
+
+union cm_error_status {
+ uint64_t cm_error_status_reg;
+ struct {
+ uint64_t ecc_sbe:1, // 0
+ ecc_mbe:1, // 1
+ unsupported_req:1, // 2
+ unexpected_rsp:1, // 3
+ bad_length:1, // 4
+ bad_datavalid:1, // 5
+ buffer_overflow:1, // 6
+ request_timeout:1, // 7
+ :8, // 15:8
+ head_inv_data_size:1, // 16
+ rsp_pactype_inv:1, // 17
+ head_sb_err:1, // 18
+ missing_head:1, // 19
+ head_inv_rd_type:1, // 20
+ head_cmd_err_bit:1, // 21
+ req_addr_align_inv:1, // 22
+ pio_req_addr_inv:1, // 23
+ req_range_dsize_inv:1, // 24
+ early_term:1, // 25
+ early_tail:1, // 26
+ missing_tail:1, // 27
+ data_flit_sb_err:1, // 28
+ cm2hcm_req_cred_of:1, // 29
+ cm2hcm_rsp_cred_of:1, // 30
+ rx_bad_didn:1, // 31
+ rd_dma_err_rsp:1, // 32
+ rd_dma_tnum_tout:1, // 33
+ rd_dma_multi_tnum_tou:1, // 34
+ wr_dma_err_rsp:1, // 35
+ wr_dma_tnum_tout:1, // 36
+ wr_dma_multi_tnum_tou:1, // 37
+ alg_data_overflow:1, // 38
+ alg_data_underflow:1, // 39
+ ram0_access_conflict:1, // 40
+ ram1_access_conflict:1, // 41
+ ram2_access_conflict:1, // 42
+ ram0_perr:1, // 43
+ ram1_perr:1, // 44
+ ram2_perr:1, // 45
+ int_gen_rsp_err:1, // 46
+ int_gen_tnum_tout:1, // 47
+ rd_dma_prog_err:1, // 48
+ wr_dma_prog_err:1, // 49
+ :14; // 63:50
+ };
+};
+
+union cm_clr_error_status {
+ uint64_t cm_clr_error_status_reg;
+ struct {
+ uint64_t clr_ecc_sbe:1, // 0
+ clr_ecc_mbe:1, // 1
+ clr_unsupported_req:1, // 2
+ clr_unexpected_rsp:1, // 3
+ clr_bad_length:1, // 4
+ clr_bad_datavalid:1, // 5
+ clr_buffer_overflow:1, // 6
+ clr_request_timeout:1, // 7
+ :8, // 15:8
+ clr_head_inv_data_siz:1, // 16
+ clr_rsp_pactype_inv:1, // 17
+ clr_head_sb_err:1, // 18
+ clr_missing_head:1, // 19
+ clr_head_inv_rd_type:1, // 20
+ clr_head_cmd_err_bit:1, // 21
+ clr_req_addr_align_in:1, // 22
+ clr_pio_req_addr_inv:1, // 23
+ clr_req_range_dsize_i:1, // 24
+ clr_early_term:1, // 25
+ clr_early_tail:1, // 26
+ clr_missing_tail:1, // 27
+ clr_data_flit_sb_err:1, // 28
+ clr_cm2hcm_req_cred_o:1, // 29
+ clr_cm2hcm_rsp_cred_o:1, // 30
+ clr_rx_bad_didn:1, // 31
+ clr_rd_dma_err_rsp:1, // 32
+ clr_rd_dma_tnum_tout:1, // 33
+ clr_rd_dma_multi_tnum:1, // 34
+ clr_wr_dma_err_rsp:1, // 35
+ clr_wr_dma_tnum_tout:1, // 36
+ clr_wr_dma_multi_tnum:1, // 37
+ clr_alg_data_overflow:1, // 38
+ clr_alg_data_underflo:1, // 39
+ clr_ram0_access_confl:1, // 40
+ clr_ram1_access_confl:1, // 41
+ clr_ram2_access_confl:1, // 42
+ clr_ram0_perr:1, // 43
+ clr_ram1_perr:1, // 44
+ clr_ram2_perr:1, // 45
+ clr_int_gen_rsp_err:1, // 46
+ clr_int_gen_tnum_tout:1, // 47
+ clr_rd_dma_prog_err:1, // 48
+ clr_wr_dma_prog_err:1, // 49
+ :14; // 63:50
+ };
+};
+
+union cm_error_intr_enable {
+ uint64_t cm_error_intr_enable_reg;
+ struct {
+ uint64_t int_en_ecc_sbe:1, // 0
+ int_en_ecc_mbe:1, // 1
+ int_en_unsupported_re:1, // 2
+ int_en_unexpected_rsp:1, // 3
+ int_en_bad_length:1, // 4
+ int_en_bad_datavalid:1, // 5
+ int_en_buffer_overflo:1, // 6
+ int_en_request_timeou:1, // 7
+ :8, // 15:8
+ int_en_head_inv_data_:1, // 16
+ int_en_rsp_pactype_in:1, // 17
+ int_en_head_sb_err:1, // 18
+ int_en_missing_head:1, // 19
+ int_en_head_inv_rd_ty:1, // 20
+ int_en_head_cmd_err_b:1, // 21
+ int_en_req_addr_align:1, // 22
+ int_en_pio_req_addr_i:1, // 23
+ int_en_req_range_dsiz:1, // 24
+ int_en_early_term:1, // 25
+ int_en_early_tail:1, // 26
+ int_en_missing_tail:1, // 27
+ int_en_data_flit_sb_e:1, // 28
+ int_en_cm2hcm_req_cre:1, // 29
+ int_en_cm2hcm_rsp_cre:1, // 30
+ int_en_rx_bad_didn:1, // 31
+ int_en_rd_dma_err_rsp:1, // 32
+ int_en_rd_dma_tnum_to:1, // 33
+ int_en_rd_dma_multi_t:1, // 34
+ int_en_wr_dma_err_rsp:1, // 35
+ int_en_wr_dma_tnum_to:1, // 36
+ int_en_wr_dma_multi_t:1, // 37
+ int_en_alg_data_overf:1, // 38
+ int_en_alg_data_under:1, // 39
+ int_en_ram0_access_co:1, // 40
+ int_en_ram1_access_co:1, // 41
+ int_en_ram2_access_co:1, // 42
+ int_en_ram0_perr:1, // 43
+ int_en_ram1_perr:1, // 44
+ int_en_ram2_perr:1, // 45
+ int_en_int_gen_rsp_er:1, // 46
+ int_en_int_gen_tnum_t:1, // 47
+ int_en_rd_dma_prog_er:1, // 48
+ int_en_wr_dma_prog_er:1, // 49
+ :14; // 63:50
+ };
+};
+
+struct cm_mmr {
+ union cm_id id;
+ union cm_status status;
+ union cm_error_detail1 err_detail1;
+ union cm_error_detail2 err_detail2;
+ union cm_control control;
+ union cm_req_timeout req_timeout;
+ uint64_t reserved1[1];
+ union intr_dest int_dest;
+ uint64_t reserved2[2];
+ uint64_t targ_flush;
+ uint64_t reserved3[1];
+ union cm_error_status err_status;
+ union cm_clr_error_status clr_err_status;
+ union cm_error_intr_enable int_enable;
+};
+
+union dma_hostaddr {
+ uint64_t dma_hostaddr_reg;
+ struct {
+ uint64_t dma_sys_addr:56, // 55:0
+ :8; // 63:56
+ };
+};
+
+union dma_localaddr {
+ uint64_t dma_localaddr_reg;
+ struct {
+ uint64_t dma_ram_addr:21, // 20:0
+ dma_ram_sel:2, // 22:21
+ :41; // 63:23
+ };
+};
+
+union dma_control {
+ uint64_t dma_control_reg;
+ struct {
+ uint64_t dma_op_length:16, // 15:0
+ :18, // 33:16
+ done_amo_en:1, // 34
+ done_int_en:1, // 35
+ :1, // 36
+ pio_mem_n:1, // 37
+ :26; // 63:38
+ };
+};
+
+union dma_amo_dest {
+ uint64_t dma_amo_dest_reg;
+ struct {
+ uint64_t dma_amo_sys_addr:56, // 55:0
+ dma_amo_mod_type:3, // 58:56
+ :5; // 63:59
+ };
+};
+
+union rdma_aux_status {
+ uint64_t rdma_aux_status_reg;
+ struct {
+ uint64_t op_num_pacs_left:17, // 16:0
+ :5, // 21:17
+ lrsp_buff_empty:1, // 22
+ :17, // 39:23
+ pending_reqs_left:6, // 45:40
+ :18; // 63:46
+ };
+};
+
+struct rdma_mmr {
+ union dma_hostaddr host_addr;
+ union dma_localaddr local_addr;
+ union dma_control control;
+ union dma_amo_dest amo_dest;
+ union intr_dest intr_dest;
+ union rdma_aux_status aux_status;
+};
+
+union wdma_aux_status {
+ uint64_t wdma_aux_status_reg;
+ struct {
+ uint64_t op_num_pacs_left:17, // 16:0
+ :4, // 20:17
+ lreq_buff_empty:1, // 21
+ :18, // 39:22
+ pending_reqs_left:6, // 45:40
+ :18; // 63:46
+ };
+};
+
+struct wdma_mmr {
+ union dma_hostaddr host_addr;
+ union dma_localaddr local_addr;
+ union dma_control control;
+ union dma_amo_dest amo_dest;
+ union intr_dest intr_dest;
+ union wdma_aux_status aux_status;
+};
+
+union algo_step {
+ uint64_t algo_step_reg;
+ struct {
+ uint64_t alg_step_cnt:16, // 15:0
+ :48; // 63:16
+ };
+};
+
+struct algo_mmr {
+ union dma_amo_dest amo_dest;
+ union intr_dest intr_dest;
+ union {
+ uint64_t algo_offset_reg;
+ struct {
+ uint64_t sram0_offset:7, // 6:0
+ reserved0:1, // 7
+ sram1_offset:7, // 14:8
+ reserved1:1, // 15
+ sram2_offset:7, // 22:16
+ reserved2:14; // 63:23
+ };
+ } sram_offset;
+ union algo_step step;
+};
+
+struct mbcs_mmr {
+ struct cm_mmr cm;
+ uint64_t reserved1[17];
+ struct rdma_mmr rdDma;
+ uint64_t reserved2[25];
+ struct wdma_mmr wrDma;
+ uint64_t reserved3[25];
+ struct algo_mmr algo;
+ uint64_t reserved4[156];
+};
+
+/*
+ * defines
+ */
+#define DEVICE_NAME "mbcs"
+#define MBCS_PART_NUM 0xfff0
+#define MBCS_PART_NUM_ALG0 0xf001
+#define MBCS_MFG_NUM 0x1
+
+struct algoblock {
+ uint64_t amoHostDest;
+ uint64_t amoModType;
+ uint64_t intrHostDest;
+ uint64_t intrVector;
+ uint64_t algoStepCount;
+};
+
+struct getdma {
+ uint64_t hostAddr;
+ uint64_t localAddr;
+ uint64_t bytes;
+ uint64_t DoneAmoEnable;
+ uint64_t DoneIntEnable;
+ uint64_t peerIO;
+ uint64_t amoHostDest;
+ uint64_t amoModType;
+ uint64_t intrHostDest;
+ uint64_t intrVector;
+};
+
+struct putdma {
+ uint64_t hostAddr;
+ uint64_t localAddr;
+ uint64_t bytes;
+ uint64_t DoneAmoEnable;
+ uint64_t DoneIntEnable;
+ uint64_t peerIO;
+ uint64_t amoHostDest;
+ uint64_t amoModType;
+ uint64_t intrHostDest;
+ uint64_t intrVector;
+};
+
+struct mbcs_soft {
+ struct list_head list;
+ struct cx_dev *cxdev;
+ int major;
+ int nasid;
+ void *mmr_base;
+ wait_queue_head_t dmawrite_queue;
+ wait_queue_head_t dmaread_queue;
+ wait_queue_head_t algo_queue;
+ struct sn_irq_info *get_sn_irq;
+ struct sn_irq_info *put_sn_irq;
+ struct sn_irq_info *algo_sn_irq;
+ struct getdma getdma;
+ struct putdma putdma;
+ struct algoblock algo;
+ uint64_t gscr_addr; // pio addr
+ uint64_t ram0_addr; // pio addr
+ uint64_t ram1_addr; // pio addr
+ uint64_t ram2_addr; // pio addr
+ uint64_t debug_addr; // pio addr
+ atomic_t dmawrite_done;
+ atomic_t dmaread_done;
+ atomic_t algo_done;
+ struct semaphore dmawritelock;
+ struct semaphore dmareadlock;
+ struct semaphore algolock;
+};
+
+extern int mbcs_open(struct inode *ip, struct file *fp);
+extern ssize_t mbcs_sram_read(struct file *fp, char __user *buf, size_t len,
+ loff_t * off);
+extern ssize_t mbcs_sram_write(struct file *fp, const char __user *buf, size_t len,
+ loff_t * off);
+extern loff_t mbcs_sram_llseek(struct file *filp, loff_t off, int whence);
+extern int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma);
+
+#endif // __MBCS_H__
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index a91ae271cf0..763893e289b 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -221,7 +221,7 @@ static int rio_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000};
/* Set the mask to all-ones. This alas, only supports 32 interrupts.
Some architectures may need more. -- Changed to LONG to
support up to 64 bits on 64bit architectures. -- REW 20/06/99 */
-long rio_irqmask = -1;
+static long rio_irqmask = -1;
MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.nl>");
MODULE_DESCRIPTION("RIO driver");
diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c
index 8e61be34a1d..ed867db550a 100644
--- a/drivers/char/s3c2410-rtc.c
+++ b/drivers/char/s3c2410-rtc.c
@@ -116,7 +116,7 @@ static void s3c2410_rtc_setfreq(int freq)
/* Time read/write */
-static void s3c2410_rtc_gettime(struct rtc_time *rtc_tm)
+static int s3c2410_rtc_gettime(struct rtc_time *rtc_tm)
{
unsigned int have_retried = 0;
@@ -151,6 +151,8 @@ static void s3c2410_rtc_gettime(struct rtc_time *rtc_tm)
rtc_tm->tm_year += 100;
rtc_tm->tm_mon -= 1;
+
+ return 0;
}
@@ -171,7 +173,7 @@ static int s3c2410_rtc_settime(struct rtc_time *tm)
return 0;
}
-static void s3c2410_rtc_getalarm(struct rtc_wkalrm *alrm)
+static int s3c2410_rtc_getalarm(struct rtc_wkalrm *alrm)
{
struct rtc_time *alm_tm = &alrm->time;
unsigned int alm_en;
@@ -231,6 +233,8 @@ static void s3c2410_rtc_getalarm(struct rtc_wkalrm *alrm)
}
/* todo - set alrm->enabled ? */
+
+ return 0;
}
static int s3c2410_rtc_setalarm(struct rtc_wkalrm *alrm)
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index ffb9143376b..e3c0b52d943 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -374,6 +374,7 @@ scdrv_init(void)
void *salbuf;
struct class_simple *snsc_class;
dev_t first_dev, dev;
+ nasid_t event_nasid = ia64_sn_get_console_nasid();
if (alloc_chrdev_region(&first_dev, 0, numionodes,
SYSCTL_BASENAME) < 0) {
@@ -441,6 +442,13 @@ scdrv_init(void)
ia64_sn_irtr_intr_enable(scd->scd_nasid,
0 /*ignored */ ,
SAL_IROUTER_INTR_RECV);
+
+ /* on the console nasid, prepare to receive
+ * system controller environmental events
+ */
+ if(scd->scd_nasid == event_nasid) {
+ scdrv_event_init(scd);
+ }
}
return 0;
}
diff --git a/drivers/char/snsc.h b/drivers/char/snsc.h
index c22c6c55e25..a9efc13cc85 100644
--- a/drivers/char/snsc.h
+++ b/drivers/char/snsc.h
@@ -47,4 +47,44 @@ struct sysctl_data_s {
nasid_t scd_nasid; /* Node on which subchannels are opened. */
};
+
+/* argument types */
+#define IR_ARG_INT 0x00 /* 4-byte integer (big-endian) */
+#define IR_ARG_ASCII 0x01 /* null-terminated ASCII string */
+#define IR_ARG_UNKNOWN 0x80 /* unknown data type. The low
+ * 7 bits will contain the data
+ * length. */
+#define IR_ARG_UNKNOWN_LENGTH_MASK 0x7f
+
+
+/* system controller event codes */
+#define EV_CLASS_MASK 0xf000ul
+#define EV_SEVERITY_MASK 0x0f00ul
+#define EV_COMPONENT_MASK 0x00fful
+
+#define EV_CLASS_POWER 0x1000ul
+#define EV_CLASS_FAN 0x2000ul
+#define EV_CLASS_TEMP 0x3000ul
+#define EV_CLASS_ENV 0x4000ul
+#define EV_CLASS_TEST_FAULT 0x5000ul
+#define EV_CLASS_TEST_WARNING 0x6000ul
+#define EV_CLASS_PWRD_NOTIFY 0x8000ul
+
+#define EV_SEVERITY_POWER_STABLE 0x0000ul
+#define EV_SEVERITY_POWER_LOW_WARNING 0x0100ul
+#define EV_SEVERITY_POWER_HIGH_WARNING 0x0200ul
+#define EV_SEVERITY_POWER_HIGH_FAULT 0x0300ul
+#define EV_SEVERITY_POWER_LOW_FAULT 0x0400ul
+
+#define EV_SEVERITY_FAN_STABLE 0x0000ul
+#define EV_SEVERITY_FAN_WARNING 0x0100ul
+#define EV_SEVERITY_FAN_FAULT 0x0200ul
+
+#define EV_SEVERITY_TEMP_STABLE 0x0000ul
+#define EV_SEVERITY_TEMP_ADVISORY 0x0100ul
+#define EV_SEVERITY_TEMP_CRITICAL 0x0200ul
+#define EV_SEVERITY_TEMP_FAULT 0x0300ul
+
+void scdrv_event_init(struct sysctl_data_s *);
+
#endif /* _SN_SYSCTL_H_ */
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
new file mode 100644
index 00000000000..d692af57213
--- /dev/null
+++ b/drivers/char/snsc_event.c
@@ -0,0 +1,304 @@
+/*
+ * SN Platform system controller communication support
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved.
+ */
+
+/*
+ * System controller event handler
+ *
+ * These routines deal with environmental events arriving from the
+ * system controllers.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/byteorder/generic.h>
+#include <asm/sn/sn_sal.h>
+#include "snsc.h"
+
+static struct subch_data_s *event_sd;
+
+void scdrv_event(unsigned long);
+DECLARE_TASKLET(sn_sysctl_event, scdrv_event, 0);
+
+/*
+ * scdrv_event_interrupt
+ *
+ * Pull incoming environmental events off the physical link to the
+ * system controller and put them in a temporary holding area in SAL.
+ * Schedule scdrv_event() to move them along to their ultimate
+ * destination.
+ */
+static irqreturn_t
+scdrv_event_interrupt(int irq, void *subch_data, struct pt_regs *regs)
+{
+ struct subch_data_s *sd = subch_data;
+ unsigned long flags;
+ int status;
+
+ spin_lock_irqsave(&sd->sd_rlock, flags);
+ status = ia64_sn_irtr_intr(sd->sd_nasid, sd->sd_subch);
+
+ if ((status > 0) && (status & SAL_IROUTER_INTR_RECV)) {
+ tasklet_schedule(&sn_sysctl_event);
+ }
+ spin_unlock_irqrestore(&sd->sd_rlock, flags);
+ return IRQ_HANDLED;
+}
+
+
+/*
+ * scdrv_parse_event
+ *
+ * Break an event (as read from SAL) into useful pieces so we can decide
+ * what to do with it.
+ */
+static int
+scdrv_parse_event(char *event, int *src, int *code, int *esp_code, char *desc)
+{
+ char *desc_end;
+
+ /* record event source address */
+ *src = be32_to_cpup((__be32 *)event);
+ event += 4; /* move on to event code */
+
+ /* record the system controller's event code */
+ *code = be32_to_cpup((__be32 *)event);
+ event += 4; /* move on to event arguments */
+
+ /* how many arguments are in the packet? */
+ if (*event++ != 2) {
+ /* if not 2, give up */
+ return -1;
+ }
+
+ /* parse out the ESP code */
+ if (*event++ != IR_ARG_INT) {
+ /* not an integer argument, so give up */
+ return -1;
+ }
+ *esp_code = be32_to_cpup((__be32 *)event);
+ event += 4;
+
+ /* parse out the event description */
+ if (*event++ != IR_ARG_ASCII) {
+ /* not an ASCII string, so give up */
+ return -1;
+ }
+ event[CHUNKSIZE-1] = '\0'; /* ensure this string ends! */
+ event += 2; /* skip leading CR/LF */
+ desc_end = desc + sprintf(desc, "%s", event);
+
+ /* strip trailing CR/LF (if any) */
+ for (desc_end--;
+ (desc_end != desc) && ((*desc_end == 0xd) || (*desc_end == 0xa));
+ desc_end--) {
+ *desc_end = '\0';
+ }
+
+ return 0;
+}
+
+
+/*
+ * scdrv_event_severity
+ *
+ * Figure out how urgent a message we should write to the console/syslog
+ * via printk.
+ */
+static char *
+scdrv_event_severity(int code)
+{
+ int ev_class = (code & EV_CLASS_MASK);
+ int ev_severity = (code & EV_SEVERITY_MASK);
+ char *pk_severity = KERN_NOTICE;
+
+ switch (ev_class) {
+ case EV_CLASS_POWER:
+ switch (ev_severity) {
+ case EV_SEVERITY_POWER_LOW_WARNING:
+ case EV_SEVERITY_POWER_HIGH_WARNING:
+ pk_severity = KERN_WARNING;
+ break;
+ case EV_SEVERITY_POWER_HIGH_FAULT:
+ case EV_SEVERITY_POWER_LOW_FAULT:
+ pk_severity = KERN_ALERT;
+ break;
+ }
+ break;
+ case EV_CLASS_FAN:
+ switch (ev_severity) {
+ case EV_SEVERITY_FAN_WARNING:
+ pk_severity = KERN_WARNING;
+ break;
+ case EV_SEVERITY_FAN_FAULT:
+ pk_severity = KERN_CRIT;
+ break;
+ }
+ break;
+ case EV_CLASS_TEMP:
+ switch (ev_severity) {
+ case EV_SEVERITY_TEMP_ADVISORY:
+ pk_severity = KERN_WARNING;
+ break;
+ case EV_SEVERITY_TEMP_CRITICAL:
+ pk_severity = KERN_CRIT;
+ break;
+ case EV_SEVERITY_TEMP_FAULT:
+ pk_severity = KERN_ALERT;
+ break;
+ }
+ break;
+ case EV_CLASS_ENV:
+ pk_severity = KERN_ALERT;
+ break;
+ case EV_CLASS_TEST_FAULT:
+ pk_severity = KERN_ALERT;
+ break;
+ case EV_CLASS_TEST_WARNING:
+ pk_severity = KERN_WARNING;
+ break;
+ case EV_CLASS_PWRD_NOTIFY:
+ pk_severity = KERN_ALERT;
+ break;
+ }
+
+ return pk_severity;
+}
+
+
+/*
+ * scdrv_dispatch_event
+ *
+ * Do the right thing with an incoming event. That's often nothing
+ * more than printing it to the system log. For power-down notifications
+ * we start a graceful shutdown.
+ */
+static void
+scdrv_dispatch_event(char *event, int len)
+{
+ int code, esp_code, src;
+ char desc[CHUNKSIZE];
+ char *severity;
+
+ if (scdrv_parse_event(event, &src, &code, &esp_code, desc) < 0) {
+ /* ignore uninterpretible event */
+ return;
+ }
+
+ /* how urgent is the message? */
+ severity = scdrv_event_severity(code);
+
+ if ((code & EV_CLASS_MASK) == EV_CLASS_PWRD_NOTIFY) {
+ struct task_struct *p;
+
+ /* give a SIGPWR signal to init proc */
+
+ /* first find init's task */
+ read_lock(&tasklist_lock);
+ for_each_process(p) {
+ if (p->pid == 1)
+ break;
+ }
+ if (p) { /* we found init's task */
+ printk(KERN_EMERG "Power off indication received. Initiating power fail sequence...\n");
+ force_sig(SIGPWR, p);
+ } else { /* failed to find init's task - just give message(s) */
+ printk(KERN_WARNING "Failed to find init proc to handle power off!\n");
+ printk("%s|$(0x%x)%s\n", severity, esp_code, desc);
+ }
+ read_unlock(&tasklist_lock);
+ } else {
+ /* print to system log */
+ printk("%s|$(0x%x)%s\n", severity, esp_code, desc);
+ }
+}
+
+
+/*
+ * scdrv_event
+ *
+ * Called as a tasklet when an event arrives from the L1. Read the event
+ * from where it's temporarily stored in SAL and call scdrv_dispatch_event()
+ * to send it on its way. Keep trying to read events until SAL indicates
+ * that there are no more immediately available.
+ */
+void
+scdrv_event(unsigned long dummy)
+{
+ int status;
+ int len;
+ unsigned long flags;
+ struct subch_data_s *sd = event_sd;
+
+ /* anything to read? */
+ len = CHUNKSIZE;
+ spin_lock_irqsave(&sd->sd_rlock, flags);
+ status = ia64_sn_irtr_recv(sd->sd_nasid, sd->sd_subch,
+ sd->sd_rb, &len);
+
+ while (!(status < 0)) {
+ spin_unlock_irqrestore(&sd->sd_rlock, flags);
+ scdrv_dispatch_event(sd->sd_rb, len);
+ len = CHUNKSIZE;
+ spin_lock_irqsave(&sd->sd_rlock, flags);
+ status = ia64_sn_irtr_recv(sd->sd_nasid, sd->sd_subch,
+ sd->sd_rb, &len);
+ }
+ spin_unlock_irqrestore(&sd->sd_rlock, flags);
+}
+
+
+/*
+ * scdrv_event_init
+ *
+ * Sets up a system controller subchannel to begin receiving event
+ * messages. This is sort of a specialized version of scdrv_open()
+ * in drivers/char/sn_sysctl.c.
+ */
+void
+scdrv_event_init(struct sysctl_data_s *scd)
+{
+ int rv;
+
+ event_sd = kmalloc(sizeof (struct subch_data_s), GFP_KERNEL);
+ if (event_sd == NULL) {
+ printk(KERN_WARNING "%s: couldn't allocate subchannel info"
+ " for event monitoring\n", __FUNCTION__);
+ return;
+ }
+
+ /* initialize subch_data_s fields */
+ memset(event_sd, 0, sizeof (struct subch_data_s));
+ event_sd->sd_nasid = scd->scd_nasid;
+ spin_lock_init(&event_sd->sd_rlock);
+
+ /* ask the system controllers to send events to this node */
+ event_sd->sd_subch = ia64_sn_sysctl_event_init(scd->scd_nasid);
+
+ if (event_sd->sd_subch < 0) {
+ kfree(event_sd);
+ printk(KERN_WARNING "%s: couldn't open event subchannel\n",
+ __FUNCTION__);
+ return;
+ }
+
+ /* hook event subchannel up to the system controller interrupt */
+ rv = request_irq(SGI_UART_VECTOR, scdrv_event_interrupt,
+ SA_SHIRQ | SA_INTERRUPT,
+ "system controller events", event_sd);
+ if (rv) {
+ printk(KERN_WARNING "%s: irq request failed (%d)\n",
+ __FUNCTION__, rv);
+ ia64_sn_irtr_close(event_sd->sd_nasid, event_sd->sd_subch);
+ kfree(event_sd);
+ return;
+ }
+}
+
+
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index c812191417c..fd042060809 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -1021,11 +1021,11 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
ret = -EIO;
break;
}
- if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
+ if (copy_to_user(argp, &val8, sizeof(val8)))
ret = -EFAULT;
break;
case SONYPI_IOCSFAN:
- if (copy_from_user(&val8, (u8 *)arg, sizeof(val8))) {
+ if (copy_from_user(&val8, argp, sizeof(val8))) {
ret = -EFAULT;
break;
}
@@ -1038,7 +1038,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
ret = -EIO;
break;
}
- if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
+ if (copy_to_user(argp, &val8, sizeof(val8)))
ret = -EFAULT;
break;
default:
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index c789d5ceac7..50e0b612a8a 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -1987,10 +1987,9 @@ static inline int sx_set_serial_info(struct specialix_port * port,
func_enter();
/*
- error = verify_area(VERIFY_READ, (void *) newinfo, sizeof(tmp));
- if (error) {
+ if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
func_exit();
- return error;
+ return -EFAULT;
}
*/
if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
@@ -2046,14 +2045,12 @@ static inline int sx_get_serial_info(struct specialix_port * port,
{
struct serial_struct tmp;
struct specialix_board *bp = port_Board(port);
- // int error;
func_enter();
/*
- error = verify_area(VERIFY_WRITE, (void *) retinfo, sizeof(tmp));
- if (error)
- return error;
+ if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
+ return -EFAULT;
*/
memset(&tmp, 0, sizeof(tmp));
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index de166608c59..b8899f560b5 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -466,7 +466,7 @@ static int stl_parsebrd(stlconf_t *confp, char **argp);
static unsigned long stl_atol(char *str);
-int stl_init(void);
+static int stl_init(void);
static int stl_open(struct tty_struct *tty, struct file *filp);
static void stl_close(struct tty_struct *tty, struct file *filp);
static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count);
@@ -3063,7 +3063,7 @@ static struct tty_operations stl_ops = {
/*****************************************************************************/
-int __init stl_init(void)
+static int __init stl_init(void)
{
int i;
printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index ca36087d4f8..87235330fdb 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -143,7 +143,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
return -ENODATA;
if (count > bufsiz) {
dev_err(&chip->pci_dev->dev,
- "invalid count value %x %x \n", count, bufsiz);
+ "invalid count value %x %zx \n", count, bufsiz);
return -E2BIG;
}
@@ -151,7 +151,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
if ((len = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
dev_err(&chip->pci_dev->dev,
- "tpm_transmit: tpm_send: error %d\n", len);
+ "tpm_transmit: tpm_send: error %zd\n", len);
return len;
}
@@ -188,7 +188,7 @@ out_recv:
len = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
if (len < 0)
dev_err(&chip->pci_dev->dev,
- "tpm_transmit: tpm_recv: error %d\n", len);
+ "tpm_transmit: tpm_recv: error %zd\n", len);
up(&chip->tpm_mutex);
return len;
}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 06e5a3f1836..26e5e19ed85 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -185,7 +185,7 @@ char *tty_name(struct tty_struct *tty, char *buf)
EXPORT_SYMBOL(tty_name);
-inline int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
+int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
const char *routine)
{
#ifdef TTY_PARANOIA_CHECK
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 5d386f4bea4..8971484b956 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -24,6 +24,7 @@
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/console.h>
+#include <linux/signal.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -641,7 +642,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
extern int spawnpid, spawnsig;
if (!perm || !capable(CAP_KILL))
return -EPERM;
- if (arg < 1 || arg > _NSIG || arg == SIGKILL)
+ if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
return -EINVAL;
spawnpid = current->pid;
spawnsig = arg;
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index b30001f3161..8e561313d09 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -223,7 +223,7 @@ static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
}
if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) ||
(val == CPUFREQ_POSTCHANGE && ci->old > ci->new) ||
- (val == CPUFREQ_RESUMECHANGE)) {
+ (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new);
dprintk("scaling loops_per_jiffy to %lu for frequency %u kHz\n", loops_per_jiffy, ci->new);
}
@@ -866,11 +866,90 @@ EXPORT_SYMBOL(cpufreq_get);
/**
+ * cpufreq_suspend - let the low level driver prepare for suspend
+ */
+
+static int cpufreq_suspend(struct sys_device * sysdev, u32 state)
+{
+ int cpu = sysdev->id;
+ unsigned int ret = 0;
+ unsigned int cur_freq = 0;
+ struct cpufreq_policy *cpu_policy;
+
+ dprintk("resuming cpu %u\n", cpu);
+
+ if (!cpu_online(cpu))
+ return 0;
+
+ /* we may be lax here as interrupts are off. Nonetheless
+ * we need to grab the correct cpu policy, as to check
+ * whether we really run on this CPU.
+ */
+
+ cpu_policy = cpufreq_cpu_get(cpu);
+ if (!cpu_policy)
+ return -EINVAL;
+
+ /* only handle each CPU group once */
+ if (unlikely(cpu_policy->cpu != cpu)) {
+ cpufreq_cpu_put(cpu_policy);
+ return 0;
+ }
+
+ if (cpufreq_driver->suspend) {
+ ret = cpufreq_driver->suspend(cpu_policy, state);
+ if (ret) {
+ printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
+ "step on CPU %u\n", cpu_policy->cpu);
+ cpufreq_cpu_put(cpu_policy);
+ return ret;
+ }
+ }
+
+
+ if (cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)
+ goto out;
+
+ if (cpufreq_driver->get)
+ cur_freq = cpufreq_driver->get(cpu_policy->cpu);
+
+ if (!cur_freq || !cpu_policy->cur) {
+ printk(KERN_ERR "cpufreq: suspend failed to assert current "
+ "frequency is what timing core thinks it is.\n");
+ goto out;
+ }
+
+ if (unlikely(cur_freq != cpu_policy->cur)) {
+ struct cpufreq_freqs freqs;
+
+ if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
+ printk(KERN_DEBUG "Warning: CPU frequency is %u, "
+ "cpufreq assumed %u kHz.\n",
+ cur_freq, cpu_policy->cur);
+
+ freqs.cpu = cpu;
+ freqs.old = cpu_policy->cur;
+ freqs.new = cur_freq;
+
+ notifier_call_chain(&cpufreq_transition_notifier_list,
+ CPUFREQ_SUSPENDCHANGE, &freqs);
+ adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs);
+
+ cpu_policy->cur = cur_freq;
+ }
+
+ out:
+ cpufreq_cpu_put(cpu_policy);
+ return 0;
+}
+
+/**
* cpufreq_resume - restore proper CPU frequency handling after resume
*
* 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
* 2.) if ->target and !CPUFREQ_CONST_LOOPS: verify we're in sync
- * 3.) schedule call cpufreq_update_policy() ASAP as interrupts are restored.
+ * 3.) schedule call cpufreq_update_policy() ASAP as interrupts are
+ * restored.
*/
static int cpufreq_resume(struct sys_device * sysdev)
{
@@ -915,21 +994,26 @@ static int cpufreq_resume(struct sys_device * sysdev)
cur_freq = cpufreq_driver->get(cpu_policy->cpu);
if (!cur_freq || !cpu_policy->cur) {
- printk(KERN_ERR "cpufreq: resume failed to assert current frequency is what timing core thinks it is.\n");
+ printk(KERN_ERR "cpufreq: resume failed to assert "
+ "current frequency is what timing core "
+ "thinks it is.\n");
goto out;
}
if (unlikely(cur_freq != cpu_policy->cur)) {
struct cpufreq_freqs freqs;
- printk(KERN_WARNING "Warning: CPU frequency is %u, "
- "cpufreq assumed %u kHz.\n", cur_freq, cpu_policy->cur);
+ if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
+ printk(KERN_WARNING "Warning: CPU frequency"
+ "is %u, cpufreq assumed %u kHz.\n",
+ cur_freq, cpu_policy->cur);
freqs.cpu = cpu;
freqs.old = cpu_policy->cur;
freqs.new = cur_freq;
- notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_RESUMECHANGE, &freqs);
+ notifier_call_chain(&cpufreq_transition_notifier_list,
+ CPUFREQ_RESUMECHANGE, &freqs);
adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);
cpu_policy->cur = cur_freq;
@@ -945,6 +1029,7 @@ out:
static struct sysdev_driver cpufreq_sysdev_driver = {
.add = cpufreq_add_dev,
.remove = cpufreq_remove_dev,
+ .suspend = cpufreq_suspend,
.resume = cpufreq_resume,
};
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index a2827e43f0f..a0018de3bef 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -237,7 +237,7 @@ config I2C_KEYWEST
config I2C_MPC
tristate "MPC107/824x/85xx/52xx"
- depends on I2C && PPC
+ depends on I2C && PPC32
help
If you say yes to this option, support will be included for the
built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 75b8d867dae..6f33496d31c 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -55,7 +55,7 @@
#define CSR_RXAK 0x01
struct mpc_i2c {
- char *base;
+ void __iomem *base;
u32 interrupt;
wait_queue_head_t queue;
struct i2c_adapter adap;
@@ -444,7 +444,7 @@ static int fsl_i2c_probe(struct device *device)
fail_add:
if (i2c->irq != 0)
- free_irq(i2c->irq, 0);
+ free_irq(i2c->irq, NULL);
fail_irq:
iounmap(i2c->base);
fail_map:
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 9d70ba5ea59..16b3e2d8bfb 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -726,7 +726,7 @@ static int sis5513_config_xfer_rate (ide_drive_t *drive)
*/
/* Chip detection and general config */
-static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name)
{
struct pci_dev *host;
int i = 0;
@@ -879,7 +879,7 @@ static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char
return 0;
}
-static unsigned int __init ata66_sis5513 (ide_hwif_t *hwif)
+static unsigned int __devinit ata66_sis5513 (ide_hwif_t *hwif)
{
u8 ata66 = 0;
@@ -897,7 +897,7 @@ static unsigned int __init ata66_sis5513 (ide_hwif_t *hwif)
return ata66;
}
-static void __init init_hwif_sis5513 (ide_hwif_t *hwif)
+static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
{
hwif->autodma = 0;
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 6dc273a8132..569f1676744 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1204,6 +1204,8 @@ pmac_ide_do_suspend(ide_hwif_t *hwif)
}
#endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */
+ disable_irq(pmif->irq);
+
/* The media bay will handle itself just fine */
if (pmif->mediabay)
return 0;
@@ -1236,7 +1238,6 @@ pmac_ide_do_resume(ide_hwif_t *hwif)
ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1);
msleep(10);
ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 0);
- msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY));
/* Kauai has it different */
if (pmif->kauai_fcr) {
@@ -1244,11 +1245,15 @@ pmac_ide_do_resume(ide_hwif_t *hwif)
fcr |= KAUAI_FCR_UATA_RESET_N | KAUAI_FCR_UATA_ENABLE;
writel(fcr, pmif->kauai_fcr);
}
+
+ msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY));
}
/* Sanitize drive timings */
sanitize_timings(pmif);
+ enable_irq(pmif->irq);
+
return 0;
}
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index 97ff364c043..6cb0b586c29 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -539,10 +539,8 @@ static void ohci_initialize(struct ti_ohci *ohci)
initialize_dma_trm_ctx(&ohci->at_req_context);
initialize_dma_trm_ctx(&ohci->at_resp_context);
- /* Initialize IR Legacy DMA */
+ /* Initialize IR Legacy DMA channel mask */
ohci->ir_legacy_channels = 0;
- initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1);
- DBGMSG("ISO receive legacy context activated");
/*
* Accept AT requests from all nodes. This probably
@@ -1032,6 +1030,8 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
case ISO_LISTEN_CHANNEL:
{
u64 mask;
+ struct dma_rcv_ctx *d = &ohci->ir_legacy_context;
+ int ir_legacy_active;
if (arg<0 || arg>63) {
PRINT(KERN_ERR,
@@ -1052,9 +1052,37 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
return -EFAULT;
}
+ ir_legacy_active = ohci->ir_legacy_channels;
+
ohci->ISO_channel_usage |= mask;
ohci->ir_legacy_channels |= mask;
+ spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
+
+ if (!ir_legacy_active) {
+ if (ohci1394_register_iso_tasklet(ohci,
+ &ohci->ir_legacy_tasklet) < 0) {
+ PRINT(KERN_ERR, "No IR DMA context available");
+ return -EBUSY;
+ }
+
+ /* the IR context can be assigned to any DMA context
+ * by ohci1394_register_iso_tasklet */
+ d->ctx = ohci->ir_legacy_tasklet.context;
+ d->ctrlSet = OHCI1394_IsoRcvContextControlSet +
+ 32*d->ctx;
+ d->ctrlClear = OHCI1394_IsoRcvContextControlClear +
+ 32*d->ctx;
+ d->cmdPtr = OHCI1394_IsoRcvCommandPtr + 32*d->ctx;
+ d->ctxtMatch = OHCI1394_IsoRcvContextMatch + 32*d->ctx;
+
+ initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1);
+
+ PRINT(KERN_ERR, "IR legacy activated");
+ }
+
+ spin_lock_irqsave(&ohci->IR_channel_lock, flags);
+
if (arg>31)
reg_write(ohci, OHCI1394_IRMultiChanMaskHiSet,
1<<(arg-32));
@@ -1101,6 +1129,12 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
DBGMSG("Listening disabled on channel %d", arg);
+
+ if (ohci->ir_legacy_channels == 0) {
+ stop_dma_rcv_ctx(&ohci->ir_legacy_context);
+ DBGMSG("ISO legacy receive context stopped");
+ }
+
break;
}
default:
@@ -1270,8 +1304,10 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso)
OHCI_ISO_RECEIVE,
ohci_iso_recv_task, (unsigned long) iso);
- if (ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0)
+ if (ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0) {
+ ret = -EBUSY;
goto err;
+ }
recv->task_active = 1;
@@ -1896,8 +1932,10 @@ static int ohci_iso_xmit_init(struct hpsb_iso *iso)
ohci1394_init_iso_tasklet(&xmit->task, OHCI_ISO_TRANSMIT,
ohci_iso_xmit_task, (unsigned long) iso);
- if (ohci1394_register_iso_tasklet(xmit->ohci, &xmit->task) < 0)
+ if (ohci1394_register_iso_tasklet(xmit->ohci, &xmit->task) < 0) {
+ ret = -EBUSY;
goto err;
+ }
xmit->task_active = 1;
@@ -2691,7 +2729,7 @@ static void dma_rcv_tasklet (unsigned long data)
(cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f,
(cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>21)&0x3,
tcode, length, d->ctx,
- (cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>10)&0x3f);
+ (cond_le32_to_cpu(d->spb[0], ohci->no_swap_incoming)>>10)&0x3f);
ack = (((cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f)
== 0x11) ? 1 : 0;
@@ -2754,7 +2792,7 @@ static void dma_trm_tasklet (unsigned long data)
d->ctx);
else
DBGMSG("Packet sent to node %d tcode=0x%X tLabel="
- "0x%02X ack=0x%X spd=%d dataLength=%d ctx=%d",
+ "%d ack=0x%X spd=%d dataLength=%d ctx=%d",
(le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])>>16)&0x3f,
(le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf,
(le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>10)&0x3f,
@@ -2763,7 +2801,7 @@ static void dma_trm_tasklet (unsigned long data)
d->ctx);
else
DBGMSG("Packet sent to node %d tcode=0x%X tLabel="
- "0x%02X ack=0x%X spd=%d data=0x%08X ctx=%d",
+ "%d ack=0x%X spd=%d data=0x%08X ctx=%d",
(le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])
>>16)&0x3f,
(le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])
@@ -2999,20 +3037,6 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
ohci1394_init_iso_tasklet(&ohci->ir_legacy_tasklet,
OHCI_ISO_MULTICHANNEL_RECEIVE,
dma_rcv_tasklet, (unsigned long) d);
- if (ohci1394_register_iso_tasklet(ohci,
- &ohci->ir_legacy_tasklet) < 0) {
- PRINT(KERN_ERR, "No IR DMA context available");
- free_dma_rcv_ctx(d);
- return -EBUSY;
- }
-
- /* the IR context can be assigned to any DMA context
- * by ohci1394_register_iso_tasklet */
- d->ctx = ohci->ir_legacy_tasklet.context;
- d->ctrlSet = OHCI1394_IsoRcvContextControlSet + 32*d->ctx;
- d->ctrlClear = OHCI1394_IsoRcvContextControlClear + 32*d->ctx;
- d->cmdPtr = OHCI1394_IsoRcvCommandPtr + 32*d->ctx;
- d->ctxtMatch = OHCI1394_IsoRcvContextMatch + 32*d->ctx;
} else {
d->ctrlSet = context_base + OHCI1394_ContextControlSet;
d->ctrlClear = context_base + OHCI1394_ContextControlClear;
@@ -3413,7 +3437,6 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
switch (ohci->init_state) {
case OHCI_INIT_DONE:
- stop_dma_rcv_ctx(&ohci->ir_legacy_context);
hpsb_remove_host(ohci->host);
/* Clear out BUS Options */
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 5824b6d3769..637b30e3559 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -32,6 +32,8 @@
* $Id$
*/
+#include <linux/mm.h>
+
#include "mthca_memfree.h"
#include "mthca_dev.h"
#include "mthca_cmd.h"
diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
index c76cf8ff29c..874367bfab0 100644
--- a/drivers/input/joystick/spaceorb.c
+++ b/drivers/input/joystick/spaceorb.c
@@ -116,7 +116,7 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r
case 'K': /* Button data */
if (spaceorb->idx != 5) return;
- for (i = 0; i < 7; i++)
+ for (i = 0; i < 6; i++)
input_report_key(dev, spaceorb_buttons[i], (data[2] >> i) & 1);
break;
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index f7304f0ce54..ff66ed4ee2c 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -678,7 +678,7 @@ static void atkbd_disconnect(struct serio *serio)
atkbd_disable(atkbd);
/* make sure we don't have a command in flight */
- synchronize_kernel();
+ synchronize_sched(); /* Allow atkbd_interrupt()s to complete. */
flush_scheduled_work();
device_remove_file(&serio->dev, &atkbd_attr_extra);
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 06163538bb2..12dee8e9fbb 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -60,12 +60,12 @@ MODULE_LICENSE("GPL");
static struct class_simple *capi_class;
-int capi_major = 68; /* allocated */
+static int capi_major = 68; /* allocated */
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
#define CAPINC_NR_PORTS 32
#define CAPINC_MAX_PORTS 256
-int capi_ttymajor = 191;
-int capi_ttyminors = CAPINC_NR_PORTS;
+static int capi_ttymajor = 191;
+static int capi_ttyminors = CAPINC_NR_PORTS;
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
module_param_named(major, capi_major, uint, 0);
@@ -268,7 +268,7 @@ static void capiminor_free(struct capiminor *mp)
kfree(mp);
}
-struct capiminor *capiminor_find(unsigned int minor)
+static struct capiminor *capiminor_find(unsigned int minor)
{
struct list_head *l;
struct capiminor *p = NULL;
@@ -1166,7 +1166,7 @@ static int capinc_tty_write_room(struct tty_struct *tty)
return room;
}
-int capinc_tty_chars_in_buffer(struct tty_struct *tty)
+static int capinc_tty_chars_in_buffer(struct tty_struct *tty)
{
struct capiminor *mp = (struct capiminor *)tty->driver_data;
if (!mp || !mp->nccip) {
diff --git a/drivers/isdn/capi/kcapi_proc.c b/drivers/isdn/capi/kcapi_proc.c
index 16dc5418ff4..2cc8b27e4c3 100644
--- a/drivers/isdn/capi/kcapi_proc.c
+++ b/drivers/isdn/capi/kcapi_proc.c
@@ -89,14 +89,14 @@ static int contrstats_show(struct seq_file *seq, void *v)
return 0;
}
-struct seq_operations seq_controller_ops = {
+static struct seq_operations seq_controller_ops = {
.start = controller_start,
.next = controller_next,
.stop = controller_stop,
.show = controller_show,
};
-struct seq_operations seq_contrstats_ops = {
+static struct seq_operations seq_contrstats_ops = {
.start = controller_start,
.next = controller_next,
.stop = controller_stop,
@@ -192,14 +192,14 @@ applstats_show(struct seq_file *seq, void *v)
return 0;
}
-struct seq_operations seq_applications_ops = {
+static struct seq_operations seq_applications_ops = {
.start = applications_start,
.next = applications_next,
.stop = applications_stop,
.show = applications_show,
};
-struct seq_operations seq_applstats_ops = {
+static struct seq_operations seq_applstats_ops = {
.start = applications_start,
.next = applications_next,
.stop = applications_stop,
@@ -287,7 +287,7 @@ static int capi_driver_show(struct seq_file *seq, void *v)
return 0;
}
-struct seq_operations seq_capi_driver_ops = {
+static struct seq_operations seq_capi_driver_ops = {
.start = capi_driver_start,
.next = capi_driver_next,
.stop = capi_driver_stop,
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 1eb112213f0..0bfd698726a 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -383,7 +383,7 @@ divert_rule *getruleptr(int idx)
/*************************************************/
/* called from common module on an incoming call */
/*************************************************/
-int isdn_divert_icall(isdn_ctrl *ic)
+static int isdn_divert_icall(isdn_ctrl *ic)
{ int retval = 0;
unsigned long flags;
struct call_struc *cs = NULL;
@@ -552,7 +552,7 @@ void deleteprocs(void)
/****************************************************/
/* put a address including address type into buffer */
/****************************************************/
-int put_address(char *st, u_char *p, int len)
+static int put_address(char *st, u_char *p, int len)
{ u_char retval = 0;
u_char adr_typ = 0; /* network standard */
@@ -595,7 +595,7 @@ int put_address(char *st, u_char *p, int len)
/*************************************/
/* report a succesfull interrogation */
/*************************************/
-int interrogate_success(isdn_ctrl *ic, struct call_struc *cs)
+static int interrogate_success(isdn_ctrl *ic, struct call_struc *cs)
{ char *src = ic->parm.dss1_io.data;
int restlen = ic->parm.dss1_io.datalen;
int cnt = 1;
@@ -689,7 +689,7 @@ int interrogate_success(isdn_ctrl *ic, struct call_struc *cs)
/*********************************************/
/* callback for protocol specific extensions */
/*********************************************/
-int prot_stat_callback(isdn_ctrl *ic)
+static int prot_stat_callback(isdn_ctrl *ic)
{ struct call_struc *cs, *cs1;
int i;
unsigned long flags;
@@ -781,7 +781,7 @@ int prot_stat_callback(isdn_ctrl *ic)
/***************************/
/* status callback from HL */
/***************************/
-int isdn_divert_stat_callback(isdn_ctrl *ic)
+static int isdn_divert_stat_callback(isdn_ctrl *ic)
{ struct call_struc *cs, *cs1;
unsigned long flags;
int retval;
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index 1ac46c26b93..ba1d028343e 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -29,6 +29,7 @@
#include <linux/timer.h>
#include <linux/skbuff.h>
#include <linux/wait.h>
+#include <asm/io.h>
#include "hisax_if.h"
#include "hfc4s8s_l1.h"
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index 8f93d01d892..db654e8bd67 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -555,6 +555,42 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
#endif /* CONFIG_PMAC_BACKLIGHT */
input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSUP, down);
break;
+
+ case 0xc: /* videomode switch */
+ input_report_key(&adbhid[id]->input, KEY_SWITCHVIDEOMODE, down);
+ break;
+
+ case 0xd: /* keyboard illumination toggle */
+ input_report_key(&adbhid[id]->input, KEY_KBDILLUMTOGGLE, down);
+ break;
+
+ case 0xe: /* keyboard illumination decrease */
+ input_report_key(&adbhid[id]->input, KEY_KBDILLUMDOWN, down);
+ break;
+
+ case 0xf:
+ switch (data[1]) {
+ case 0x8f:
+ case 0x0f:
+ /* keyboard illumination increase */
+ input_report_key(&adbhid[id]->input, KEY_KBDILLUMUP, down);
+ break;
+
+ case 0x7f:
+ case 0xff:
+ /* keypad overlay toogle */
+ break;
+
+ default:
+ printk(KERN_INFO "Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n",
+ data[0], data[1], data[2], data[3]);
+ break;
+ }
+ break;
+ default:
+ printk(KERN_INFO "Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n",
+ data[0], data[1], data[2], data[3]);
+ break;
}
}
break;
@@ -775,6 +811,10 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
set_bit(KEY_BRIGHTNESSUP, adbhid[id]->input.keybit);
set_bit(KEY_BRIGHTNESSDOWN, adbhid[id]->input.keybit);
set_bit(KEY_EJECTCD, adbhid[id]->input.keybit);
+ set_bit(KEY_SWITCHVIDEOMODE, adbhid[id]->input.keybit);
+ set_bit(KEY_KBDILLUMTOGGLE, adbhid[id]->input.keybit);
+ set_bit(KEY_KBDILLUMDOWN, adbhid[id]->input.keybit);
+ set_bit(KEY_KBDILLUMUP, adbhid[id]->input.keybit);
break;
}
if (adbhid[id]->name[0])
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index fdea1a3a631..e654aa5eecd 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -2351,6 +2351,10 @@ pmac_suspend_devices(void)
return -EBUSY;
}
+ /* Disable clock spreading on some machines */
+ pmac_tweak_clock_spreading(0);
+
+ /* Stop preemption */
preempt_disable();
/* Make sure the decrementer won't interrupt us */
@@ -2417,11 +2421,12 @@ pmac_wakeup_devices(void)
/* Re-enable local CPU interrupts */
local_irq_enable();
-
mdelay(100);
-
preempt_enable();
+ /* Re-enable clock spreading on some machines */
+ pmac_tweak_clock_spreading(1);
+
/* Resume devices */
device_resume();
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 77619a56e2b..0dd6c2b5391 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -331,25 +331,19 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size,
struct bio *bio;
unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
int gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
- unsigned long flags = current->flags;
unsigned int i;
/*
- * Tell VM to act less aggressively and fail earlier.
- * This is not necessary but increases throughput.
+ * Use __GFP_NOMEMALLOC to tell the VM to act less aggressively and
+ * to fail earlier. This is not necessary but increases throughput.
* FIXME: Is this really intelligent?
*/
- current->flags &= ~PF_MEMALLOC;
-
if (base_bio)
- bio = bio_clone(base_bio, GFP_NOIO);
+ bio = bio_clone(base_bio, GFP_NOIO|__GFP_NOMEMALLOC);
else
- bio = bio_alloc(GFP_NOIO, nr_iovecs);
- if (!bio) {
- if (flags & PF_MEMALLOC)
- current->flags |= PF_MEMALLOC;
+ bio = bio_alloc(GFP_NOIO|__GFP_NOMEMALLOC, nr_iovecs);
+ if (!bio)
return NULL;
- }
/* if the last bio was not complete, continue where that one ended */
bio->bi_idx = *bio_vec_idx;
@@ -386,9 +380,6 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size,
size -= bv->bv_len;
}
- if (flags & PF_MEMALLOC)
- current->flags |= PF_MEMALLOC;
-
if (!bio->bi_size) {
bio_put(bio);
return NULL;
diff --git a/drivers/md/dm-emc.c b/drivers/md/dm-emc.c
index 70065866459..c7067674dcb 100644
--- a/drivers/md/dm-emc.c
+++ b/drivers/md/dm-emc.c
@@ -223,8 +223,10 @@ static struct emc_handler *alloc_emc_handler(void)
{
struct emc_handler *h = kmalloc(sizeof(*h), GFP_KERNEL);
- if (h)
+ if (h) {
+ memset(h, 0, sizeof(*h));
spin_lock_init(&h->lock);
+ }
return h;
}
@@ -259,8 +261,6 @@ static int emc_create(struct hw_handler *hwh, unsigned argc, char **argv)
if (!h)
return -ENOMEM;
- memset(h, 0, sizeof(*h));
-
hwh->context = h;
if ((h->short_trespass = short_trespass))
diff --git a/drivers/md/dm-hw-handler.c b/drivers/md/dm-hw-handler.c
index ae63772e44c..4cc0010e015 100644
--- a/drivers/md/dm-hw-handler.c
+++ b/drivers/md/dm-hw-handler.c
@@ -23,7 +23,7 @@ struct hwh_internal {
static LIST_HEAD(_hw_handlers);
static DECLARE_RWSEM(_hwh_lock);
-struct hwh_internal *__find_hw_handler_type(const char *name)
+static struct hwh_internal *__find_hw_handler_type(const char *name)
{
struct hwh_internal *hwhi;
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 43763a0bd09..1e97b3c12bd 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -101,6 +101,7 @@ typedef int (*action_fn) (struct pgpath *pgpath);
static kmem_cache_t *_mpio_cache;
+struct workqueue_struct *kmultipathd;
static void process_queued_ios(void *data);
static void trigger_event(void *data);
@@ -308,7 +309,7 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
bio_list_add(&m->queued_ios, bio);
m->queue_size++;
if (m->pg_init_required || !m->queue_io)
- schedule_work(&m->process_queued_ios);
+ queue_work(kmultipathd, &m->process_queued_ios);
pgpath = NULL;
r = 0;
} else if (!pgpath)
@@ -334,7 +335,7 @@ static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path)
m->queue_if_no_path = queue_if_no_path;
if (!m->queue_if_no_path)
- schedule_work(&m->process_queued_ios);
+ queue_work(kmultipathd, &m->process_queued_ios);
spin_unlock_irqrestore(&m->lock, flags);
@@ -800,7 +801,7 @@ static int fail_path(struct pgpath *pgpath)
if (pgpath == m->current_pgpath)
m->current_pgpath = NULL;
- schedule_work(&m->trigger_event);
+ queue_work(kmultipathd, &m->trigger_event);
out:
spin_unlock_irqrestore(&m->lock, flags);
@@ -837,9 +838,9 @@ static int reinstate_path(struct pgpath *pgpath)
m->current_pgpath = NULL;
if (!m->nr_valid_paths++)
- schedule_work(&m->process_queued_ios);
+ queue_work(kmultipathd, &m->process_queued_ios);
- schedule_work(&m->trigger_event);
+ queue_work(kmultipathd, &m->trigger_event);
out:
spin_unlock_irqrestore(&m->lock, flags);
@@ -883,7 +884,7 @@ static void bypass_pg(struct multipath *m, struct priority_group *pg,
spin_unlock_irqrestore(&m->lock, flags);
- schedule_work(&m->trigger_event);
+ queue_work(kmultipathd, &m->trigger_event);
}
/*
@@ -913,7 +914,7 @@ static int switch_pg_num(struct multipath *m, const char *pgstr)
}
spin_unlock_irqrestore(&m->lock, flags);
- schedule_work(&m->trigger_event);
+ queue_work(kmultipathd, &m->trigger_event);
return 0;
}
@@ -968,7 +969,7 @@ void dm_pg_init_complete(struct path *path, unsigned err_flags)
m->current_pgpath = NULL;
m->current_pg = NULL;
}
- schedule_work(&m->process_queued_ios);
+ queue_work(kmultipathd, &m->process_queued_ios);
spin_unlock_irqrestore(&m->lock, flags);
}
@@ -1018,7 +1019,7 @@ static int do_end_io(struct multipath *m, struct bio *bio,
bio_list_add(&m->queued_ios, bio);
m->queue_size++;
if (!m->queue_io)
- schedule_work(&m->process_queued_ios);
+ queue_work(kmultipathd, &m->process_queued_ios);
spin_unlock(&m->lock);
return 1; /* io not complete */
@@ -1057,7 +1058,7 @@ static void multipath_presuspend(struct dm_target *ti)
spin_lock_irqsave(&m->lock, flags);
m->suspended = 1;
if (m->queue_if_no_path)
- schedule_work(&m->process_queued_ios);
+ queue_work(kmultipathd, &m->process_queued_ios);
spin_unlock_irqrestore(&m->lock, flags);
}
@@ -1274,6 +1275,15 @@ static int __init dm_multipath_init(void)
return -EINVAL;
}
+ kmultipathd = create_workqueue("kmpathd");
+ if (!kmultipathd) {
+ DMERR("%s: failed to create workqueue kmpathd",
+ multipath_target.name);
+ dm_unregister_target(&multipath_target);
+ kmem_cache_destroy(_mpio_cache);
+ return -ENOMEM;
+ }
+
DMINFO("dm-multipath version %u.%u.%u loaded",
multipath_target.version[0], multipath_target.version[1],
multipath_target.version[2]);
@@ -1285,6 +1295,8 @@ static void __exit dm_multipath_exit(void)
{
int r;
+ destroy_workqueue(kmultipathd);
+
r = dm_unregister_target(&multipath_target);
if (r < 0)
DMERR("%s: target unregister failed %d",
diff --git a/drivers/md/dm-path-selector.c b/drivers/md/dm-path-selector.c
index ac5c4bbec6c..a28c1c2b4ef 100644
--- a/drivers/md/dm-path-selector.c
+++ b/drivers/md/dm-path-selector.c
@@ -26,7 +26,7 @@ struct ps_internal {
static LIST_HEAD(_path_selectors);
static DECLARE_RWSEM(_ps_lock);
-struct ps_internal *__find_path_selector_type(const char *name)
+static struct ps_internal *__find_path_selector_type(const char *name)
{
struct ps_internal *psi;
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index ee175d4906c..18e9b9953fc 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -242,7 +242,7 @@ static void free_devices(struct list_head *devices)
}
}
-void table_destroy(struct dm_table *t)
+static void table_destroy(struct dm_table *t)
{
unsigned int i;
diff --git a/drivers/md/dm-zero.c b/drivers/md/dm-zero.c
index 7febc2cac73..51c0639b248 100644
--- a/drivers/md/dm-zero.c
+++ b/drivers/md/dm-zero.c
@@ -55,7 +55,7 @@ static struct target_type zero_target = {
.map = zero_map,
};
-int __init dm_zero_init(void)
+static int __init dm_zero_init(void)
{
int r = dm_register_target(&zero_target);
@@ -65,7 +65,7 @@ int __init dm_zero_init(void)
return r;
}
-void __exit dm_zero_exit(void)
+static void __exit dm_zero_exit(void)
{
int r = dm_unregister_target(&zero_target);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 243ff6884e8..f6b03957efc 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -97,6 +97,7 @@ struct mapped_device {
* freeze/thaw support require holding onto a super block
*/
struct super_block *frozen_sb;
+ struct block_device *frozen_bdev;
};
#define MIN_IOS 256
@@ -990,44 +991,50 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table)
*/
static int __lock_fs(struct mapped_device *md)
{
- struct block_device *bdev;
+ int error = -ENOMEM;
if (test_and_set_bit(DMF_FS_LOCKED, &md->flags))
return 0;
- bdev = bdget_disk(md->disk, 0);
- if (!bdev) {
+ md->frozen_bdev = bdget_disk(md->disk, 0);
+ if (!md->frozen_bdev) {
DMWARN("bdget failed in __lock_fs");
- return -ENOMEM;
+ goto out;
}
WARN_ON(md->frozen_sb);
- md->frozen_sb = freeze_bdev(bdev);
+
+ md->frozen_sb = freeze_bdev(md->frozen_bdev);
+ if (IS_ERR(md->frozen_sb)) {
+ error = PTR_ERR(md->frozen_sb);
+ goto out_bdput;
+ }
+
/* don't bdput right now, we don't want the bdev
* to go away while it is locked. We'll bdput
* in __unlock_fs
*/
return 0;
+
+out_bdput:
+ bdput(md->frozen_bdev);
+ md->frozen_sb = NULL;
+ md->frozen_bdev = NULL;
+out:
+ clear_bit(DMF_FS_LOCKED, &md->flags);
+ return error;
}
-static int __unlock_fs(struct mapped_device *md)
+static void __unlock_fs(struct mapped_device *md)
{
- struct block_device *bdev;
-
if (!test_and_clear_bit(DMF_FS_LOCKED, &md->flags))
- return 0;
+ return;
- bdev = bdget_disk(md->disk, 0);
- if (!bdev) {
- DMWARN("bdget failed in __unlock_fs");
- return -ENOMEM;
- }
+ thaw_bdev(md->frozen_bdev, md->frozen_sb);
+ bdput(md->frozen_bdev);
- thaw_bdev(bdev, md->frozen_sb);
md->frozen_sb = NULL;
- bdput(bdev);
- bdput(bdev);
- return 0;
+ md->frozen_bdev = NULL;
}
/*
@@ -1041,37 +1048,37 @@ int dm_suspend(struct mapped_device *md)
{
struct dm_table *map;
DECLARE_WAITQUEUE(wait, current);
+ int error = -EINVAL;
/* Flush I/O to the device. */
down_read(&md->lock);
- if (test_bit(DMF_BLOCK_IO, &md->flags)) {
- up_read(&md->lock);
- return -EINVAL;
- }
+ if (test_bit(DMF_BLOCK_IO, &md->flags))
+ goto out_read_unlock;
+
+ error = __lock_fs(md);
+ if (error)
+ goto out_read_unlock;
map = dm_get_table(md);
if (map)
dm_table_presuspend_targets(map);
- __lock_fs(md);
up_read(&md->lock);
/*
- * First we set the BLOCK_IO flag so no more ios will be
- * mapped.
+ * First we set the BLOCK_IO flag so no more ios will be mapped.
+ *
+ * If the flag is already set we know another thread is trying to
+ * suspend as well, so we leave the fs locked for this thread.
*/
+ error = -EINVAL;
down_write(&md->lock);
- if (test_bit(DMF_BLOCK_IO, &md->flags)) {
- /*
- * If we get here we know another thread is
- * trying to suspend as well, so we leave the fs
- * locked for this thread.
- */
- up_write(&md->lock);
- return -EINVAL;
+ if (test_and_set_bit(DMF_BLOCK_IO, &md->flags)) {
+ if (map)
+ dm_table_put(map);
+ goto out_write_unlock;
}
- set_bit(DMF_BLOCK_IO, &md->flags);
add_wait_queue(&md->wait, &wait);
up_write(&md->lock);
@@ -1099,12 +1106,9 @@ int dm_suspend(struct mapped_device *md)
remove_wait_queue(&md->wait, &wait);
/* were we interrupted ? */
- if (atomic_read(&md->pending)) {
- __unlock_fs(md);
- clear_bit(DMF_BLOCK_IO, &md->flags);
- up_write(&md->lock);
- return -EINTR;
- }
+ error = -EINTR;
+ if (atomic_read(&md->pending))
+ goto out_unfreeze;
set_bit(DMF_SUSPENDED, &md->flags);
@@ -1115,6 +1119,18 @@ int dm_suspend(struct mapped_device *md)
up_write(&md->lock);
return 0;
+
+out_unfreeze:
+ /* FIXME Undo dm_table_presuspend_targets */
+ __unlock_fs(md);
+ clear_bit(DMF_BLOCK_IO, &md->flags);
+out_write_unlock:
+ up_write(&md->lock);
+ return error;
+
+out_read_unlock:
+ up_read(&md->lock);
+ return error;
}
int dm_resume(struct mapped_device *md)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 97af857d8a8..d899204d374 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -957,7 +957,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
}
-struct super_type super_types[] = {
+static struct super_type super_types[] = {
[0] = {
.name = "0.90.0",
.owner = THIS_MODULE,
@@ -2740,7 +2740,7 @@ static struct block_device_operations md_fops =
.revalidate_disk= md_revalidate,
};
-int md_thread(void * arg)
+static int md_thread(void * arg)
{
mdk_thread_t *thread = arg;
@@ -3232,7 +3232,7 @@ void md_handle_safemode(mddev_t *mddev)
}
-DECLARE_WAIT_QUEUE_HEAD(resync_wait);
+static DECLARE_WAIT_QUEUE_HEAD(resync_wait);
#define SYNC_MARKS 10
#define SYNC_MARK_STEP (3*HZ)
@@ -3575,8 +3575,8 @@ void md_check_recovery(mddev_t *mddev)
}
}
-int md_notify_reboot(struct notifier_block *this,
- unsigned long code, void *x)
+static int md_notify_reboot(struct notifier_block *this,
+ unsigned long code, void *x)
{
struct list_head *tmp;
mddev_t *mddev;
@@ -3599,7 +3599,7 @@ int md_notify_reboot(struct notifier_block *this,
return NOTIFY_DONE;
}
-struct notifier_block md_notifier = {
+static struct notifier_block md_notifier = {
.notifier_call = md_notify_reboot,
.next = NULL,
.priority = INT_MAX, /* before any real devices */
@@ -3616,7 +3616,7 @@ static void md_geninit(void)
p->proc_fops = &md_seq_fops;
}
-int __init md_init(void)
+static int __init md_init(void)
{
int minor;
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index c9b134cd153..4e4bfde3db5 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -103,7 +103,8 @@ static void multipath_end_bh_io (struct multipath_bh *mp_bh, int err)
mempool_free(mp_bh, conf->pool);
}
-int multipath_end_request(struct bio *bio, unsigned int bytes_done, int error)
+static int multipath_end_request(struct bio *bio, unsigned int bytes_done,
+ int error)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
struct multipath_bh * mp_bh = (struct multipath_bh *)(bio->bi_private);
@@ -355,7 +356,7 @@ static int multipath_remove_disk(mddev_t *mddev, int number)
goto abort;
}
p->rdev = NULL;
- synchronize_kernel();
+ synchronize_rcu();
if (atomic_read(&rdev->nr_pending)) {
/* lost the race, try later */
err = -EBUSY;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index a389394b52f..83380b5d659 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -797,7 +797,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
goto abort;
}
p->rdev = NULL;
- synchronize_kernel();
+ synchronize_rcu();
if (atomic_read(&rdev->nr_pending)) {
/* lost the race, try later */
err = -EBUSY;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index b100bfe4fdc..e9dc2876a62 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -977,7 +977,7 @@ static int raid10_remove_disk(mddev_t *mddev, int number)
goto abort;
}
p->rdev = NULL;
- synchronize_kernel();
+ synchronize_rcu();
if (atomic_read(&rdev->nr_pending)) {
/* lost the race, try later */
err = -EBUSY;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 52c3a81c4aa..e96e2a10a9c 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1873,7 +1873,7 @@ static int raid5_remove_disk(mddev_t *mddev, int number)
goto abort;
}
p->rdev = NULL;
- synchronize_kernel();
+ synchronize_rcu();
if (atomic_read(&rdev->nr_pending)) {
/* lost the race, try later */
err = -EBUSY;
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 7e30ab29691..8a33f351e09 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -2038,7 +2038,7 @@ static int raid6_remove_disk(mddev_t *mddev, int number)
goto abort;
}
p->rdev = NULL;
- synchronize_kernel();
+ synchronize_rcu();
if (atomic_read(&rdev->nr_pending)) {
/* lost the race, try later */
err = -EBUSY;
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index 8c842e2f59a..84a49d2ec91 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -131,10 +131,10 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
[ 18 ] = KEY_KP0,
[ 0 ] = KEY_POWER,
-// [ 27 ] = MTS button
+ [ 27 ] = KEY_LANGUAGE, //MTS button
[ 2 ] = KEY_TUNER, // TV/FM
[ 30 ] = KEY_VIDEO,
-// [ 22 ] = display button
+ [ 22 ] = KEY_INFO, //display button
[ 4 ] = KEY_VOLUMEUP,
[ 8 ] = KEY_VOLUMEDOWN,
[ 12 ] = KEY_CHANNELUP,
@@ -142,7 +142,7 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
[ 3 ] = KEY_ZOOM, // fullscreen
[ 31 ] = KEY_SUBTITLE, // closed caption/teletext
[ 32 ] = KEY_SLEEP,
-// [ 41 ] = boss key
+ [ 41 ] = KEY_SEARCH, //boss key
[ 20 ] = KEY_MUTE,
[ 43 ] = KEY_RED,
[ 44 ] = KEY_GREEN,
@@ -150,17 +150,17 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
[ 46 ] = KEY_BLUE,
[ 24 ] = KEY_KPPLUS, //fine tune +
[ 25 ] = KEY_KPMINUS, //fine tune -
-// [ 42 ] = picture in picture
- [ 33 ] = KEY_KPDOT,
+ [ 42 ] = KEY_ANGLE, //picture in picture
+ [ 33 ] = KEY_KPDOT,
[ 19 ] = KEY_KPENTER,
-// [ 17 ] = recall
+ [ 17 ] = KEY_AGAIN, //recall
[ 34 ] = KEY_BACK,
[ 35 ] = KEY_PLAYPAUSE,
[ 36 ] = KEY_NEXT,
-// [ 37 ] = time shifting
+ [ 37 ] = KEY_T, //time shifting
[ 38 ] = KEY_STOP,
- [ 39 ] = KEY_RECORD
-// [ 40 ] = snapshot
+ [ 39 ] = KEY_RECORD,
+ [ 40 ] = KEY_SHUFFLE //snapshot
};
EXPORT_SYMBOL_GPL(ir_codes_winfast);
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index 1930b513eef..011860ce36c 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -32,6 +32,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include "dvb_frontend.h"
+#include "dvb-pll.h"
#include "cx22702.h"
@@ -203,7 +204,19 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
/* set PLL */
cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
- state->config->pll_set(fe, p);
+ if (state->config->pll_set) {
+ state->config->pll_set(fe, p);
+ } else if (state->config->pll_desc) {
+ u8 pllbuf[4];
+ struct i2c_msg msg = { .addr = state->config->pll_address,
+ .buf = pllbuf, .len = 4 };
+ dvb_pll_configure(state->config->pll_desc, pllbuf,
+ p->frequency,
+ p->u.ofdm.bandwidth);
+ i2c_transfer(state->i2c, &msg, 1);
+ } else {
+ BUG();
+ }
cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
/* set inversion */
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
index 6e34f997aba..559fdb90666 100644
--- a/drivers/media/dvb/frontends/cx22702.h
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -36,6 +36,9 @@ struct cx22702_config
u8 demod_address;
/* PLL maintenance */
+ u8 pll_address;
+ struct dvb_pll_desc *pll_desc;
+
int (*pll_init)(struct dvb_frontend* fe);
int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
};
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index c1b3542dad8..d3dd4228b72 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -252,6 +252,7 @@ config VIDEO_SAA7134_DVB
depends on VIDEO_SAA7134 && DVB_CORE
select VIDEO_BUF_DVB
select DVB_MT352
+ select DVB_CX22702
---help---
This adds support for DVB cards based on the
Philips saa7134 chip.
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index c13f222fe6b..033cc5498f2 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -3169,7 +3169,7 @@ static struct video_device radio_template =
/* ----------------------------------------------------------------------- */
/* some debug code */
-int bttv_risc_decode(u32 risc)
+static int bttv_risc_decode(u32 risc)
{
static char *instr[16] = {
[ BT848_RISC_WRITE >> 28 ] = "write",
@@ -3206,8 +3206,8 @@ int bttv_risc_decode(u32 risc)
return incr[risc >> 28] ? incr[risc >> 28] : 1;
}
-void bttv_risc_disasm(struct bttv *btv,
- struct btcx_riscmem *risc)
+static void bttv_risc_disasm(struct bttv *btv,
+ struct btcx_riscmem *risc)
{
unsigned int i,j,n;
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index e42f1ec13f3..e3f477dff82 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -29,6 +29,7 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
#include <asm/io.h>
#include "bttvp.h"
@@ -130,17 +131,14 @@ static u32 functionality(struct i2c_adapter *adap)
static int
bttv_i2c_wait_done(struct bttv *btv)
{
- DECLARE_WAITQUEUE(wait, current);
int rc = 0;
- add_wait_queue(&btv->i2c_queue, &wait);
- if (0 == btv->i2c_done)
- msleep_interruptible(20);
- remove_wait_queue(&btv->i2c_queue, &wait);
+ /* timeout */
+ if (wait_event_interruptible_timeout(btv->i2c_queue,
+ btv->i2c_done, msecs_to_jiffies(85)) == -ERESTARTSYS)
+
+ rc = -EIO;
- if (0 == btv->i2c_done)
- /* timeout */
- rc = -EIO;
if (btv->i2c_done & BT848_INT_RACK)
rc = 1;
btv->i2c_done = 0;
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 26a6138015c..1ff79b5a883 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -429,7 +429,7 @@ int cx88_sram_channel_setup(struct cx88_core *core,
/* ------------------------------------------------------------------ */
/* debug helper code */
-int cx88_risc_decode(u32 risc)
+static int cx88_risc_decode(u32 risc)
{
static char *instr[16] = {
[ RISC_SYNC >> 28 ] = "sync",
@@ -542,7 +542,7 @@ void cx88_sram_channel_dump(struct cx88_core *core,
core->name,cx_read(ch->cnt2_reg));
}
-char *cx88_pci_irqs[32] = {
+static char *cx88_pci_irqs[32] = {
"vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",
"src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",
"brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
@@ -1206,7 +1206,6 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
/* ------------------------------------------------------------------ */
EXPORT_SYMBOL(cx88_print_ioctl);
-EXPORT_SYMBOL(cx88_pci_irqs);
EXPORT_SYMBOL(cx88_vid_irqs);
EXPORT_SYMBOL(cx88_mpeg_irqs);
EXPORT_SYMBOL(cx88_print_irqbits);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index bc6f18c4535..9d15d3d5a2b 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -31,7 +31,7 @@
#include <linux/suspend.h>
/* those two frontends need merging via linuxtv cvs ... */
-#define HAVE_CX22702 0
+#define HAVE_CX22702 1
#define HAVE_OR51132 1
#include "cx88.h"
@@ -91,7 +91,7 @@ static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb
cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb);
}
-struct videobuf_queue_ops dvb_qops = {
+static struct videobuf_queue_ops dvb_qops = {
.buf_setup = dvb_buf_setup,
.buf_prepare = dvb_buf_prepare,
.buf_queue = dvb_buf_queue,
@@ -191,7 +191,7 @@ static int or51132_set_ts_param(struct dvb_frontend* fe,
return 0;
}
-struct or51132_config pchdtv_hd3000 = {
+static struct or51132_config pchdtv_hd3000 = {
.demod_address = 0x15,
.pll_address = 0x61,
.pll_desc = &dvb_pll_thomson_dtt7610,
@@ -243,10 +243,8 @@ static int dvb_register(struct cx8802_dev *dev)
break;
#endif
default:
- printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n"
- "%s: you might want to look out for patches here:\n"
- "%s: http://dl.bytesex.org/patches/\n",
- dev->core->name, dev->core->name, dev->core->name);
+ printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
+ dev->core->name);
break;
}
if (NULL == dev->dvb.frontend) {
@@ -308,9 +306,11 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
dev);
err = dvb_register(dev);
if (0 != err)
- goto fail_free;
+ goto fail_fini;
return 0;
+ fail_fini:
+ cx8802_fini_common(dev);
fail_free:
kfree(dev);
fail_core:
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 60800172c02..0725b1288f4 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -45,7 +45,7 @@ MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
/* ----------------------------------------------------------------------- */
-void cx8800_bit_setscl(void *data, int state)
+static void cx8800_bit_setscl(void *data, int state)
{
struct cx88_core *core = data;
@@ -57,7 +57,7 @@ void cx8800_bit_setscl(void *data, int state)
cx_read(MO_I2C);
}
-void cx8800_bit_setsda(void *data, int state)
+static void cx8800_bit_setsda(void *data, int state)
{
struct cx88_core *core = data;
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c
index 471e508b074..0584ff47638 100644
--- a/drivers/media/video/cx88/cx88-vbi.c
+++ b/drivers/media/video/cx88/cx88-vbi.c
@@ -46,9 +46,9 @@ void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f)
}
}
-int cx8800_start_vbi_dma(struct cx8800_dev *dev,
- struct cx88_dmaqueue *q,
- struct cx88_buffer *buf)
+static int cx8800_start_vbi_dma(struct cx8800_dev *dev,
+ struct cx88_dmaqueue *q,
+ struct cx88_buffer *buf)
{
struct cx88_core *core = dev->core;
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 701f594e181..d1f5c92f0ce 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -325,7 +325,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
.shift = 0,
}
};
-const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls);
+static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls);
/* ------------------------------------------------------------------- */
/* resource management */
@@ -665,7 +665,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
cx88_free_buffer(fh->dev->pci,buf);
}
-struct videobuf_queue_ops cx8800_video_qops = {
+static struct videobuf_queue_ops cx8800_video_qops = {
.buf_setup = buffer_setup,
.buf_prepare = buffer_prepare,
.buf_queue = buffer_queue,
@@ -1924,7 +1924,7 @@ static struct file_operations video_fops =
.llseek = no_llseek,
};
-struct video_device cx8800_video_template =
+static struct video_device cx8800_video_template =
{
.name = "cx8800-video",
.type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES,
@@ -1933,7 +1933,7 @@ struct video_device cx8800_video_template =
.minor = -1,
};
-struct video_device cx8800_vbi_template =
+static struct video_device cx8800_vbi_template =
{
.name = "cx8800-vbi",
.type = VID_TYPE_TELETEXT|VID_TYPE_TUNER,
@@ -1951,7 +1951,7 @@ static struct file_operations radio_fops =
.llseek = no_llseek,
};
-struct video_device cx8800_radio_template =
+static struct video_device cx8800_radio_template =
{
.name = "cx8800-radio",
.type = VID_TYPE_TUNER,
@@ -2226,7 +2226,7 @@ static int cx8800_resume(struct pci_dev *pci_dev)
/* ----------------------------------------------------------- */
-struct pci_device_id cx8800_pci_tbl[] = {
+static struct pci_device_id cx8800_pci_tbl[] = {
{
.vendor = 0x14f1,
.device = 0x8800,
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index b351d9eae61..88eaaaba5ad 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -420,7 +420,6 @@ struct cx8802_dev {
/* ----------------------------------------------------------- */
/* cx88-core.c */
-extern char *cx88_pci_irqs[32];
extern char *cx88_vid_irqs[32];
extern char *cx88_mpeg_irqs[32];
extern void cx88_print_irqbits(char *name, char *tag, char **strings,
@@ -472,9 +471,6 @@ extern void cx88_core_put(struct cx88_core *core,
/* cx88-vbi.c */
void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f);
-int cx8800_start_vbi_dma(struct cx8800_dev *dev,
- struct cx88_dmaqueue *q,
- struct cx88_buffer *buf);
int cx8800_stop_vbi_dma(struct cx8800_dev *dev);
int cx8800_restart_vbi_queue(struct cx8800_dev *dev,
struct cx88_dmaqueue *q);
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index c97df705df5..7fbb8581a87 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -380,7 +380,9 @@ static void msp3400c_setvolume(struct i2c_client *client,
int val = 0, bal = 0;
if (!muted) {
- val = (volume * 0x7F / 65535) << 8;
+ /* 0x7f instead if 0x73 here has sound quality issues,
+ * probably due to overmodulation + clipping ... */
+ val = (volume * 0x73 / 65535) << 8;
}
if (val) {
bal = (balance / 256) - 128;
@@ -997,7 +999,13 @@ static int msp34xx_modus(int norm)
{
switch (norm) {
case VIDEO_MODE_PAL:
+#if 1
+ /* experimental: not sure this works with all chip versions */
+ return 0x7003;
+#else
+ /* previous value, try this if it breaks ... */
return 0x1003;
+#endif
case VIDEO_MODE_NTSC: /* BTSC */
return 0x2003;
case VIDEO_MODE_SECAM:
@@ -1264,6 +1272,7 @@ static int msp34xxg_thread(void *data)
int val, std, i;
printk("msp34xxg: daemon started\n");
+ msp->source = 1; /* default */
for (;;) {
d2printk(KERN_DEBUG "msp34xxg: thread: sleep\n");
msp34xx_sleep(msp,-1);
@@ -1334,8 +1343,9 @@ static void msp34xxg_set_source(struct i2c_client *client, int source)
/* fix matrix mode to stereo and let the msp choose what
* to output according to 'source', as recommended
+ * for MONO (source==0) downmixing set bit[7:0] to 0x30
*/
- int value = (source&0x07)<<8|(source==0 ? 0x00:0x20);
+ int value = (source&0x07)<<8|(source==0 ? 0x30:0x20);
dprintk("msp34xxg: set source to %d (0x%x)\n", source, value);
msp3400c_write(client,
I2C_MSP3400C_DFP,
@@ -1359,7 +1369,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source)
msp3400c_write(client,
I2C_MSP3400C_DEM,
0x22, /* a2 threshold for stereo/bilingual */
- source==0 ? 0x7f0:stereo_threshold);
+ stereo_threshold);
msp->source=source;
}
@@ -1394,7 +1404,7 @@ static void msp34xxg_detect_stereo(struct i2c_client *client)
static void msp34xxg_set_audmode(struct i2c_client *client, int audmode)
{
struct msp3400c *msp = i2c_get_clientdata(client);
- int source = 0;
+ int source;
switch (audmode) {
case V4L2_TUNER_MODE_MONO:
@@ -1410,9 +1420,10 @@ static void msp34xxg_set_audmode(struct i2c_client *client, int audmode)
case V4L2_TUNER_MODE_LANG2:
source=4; /* stereo or B */
break;
- default: /* doing nothing: a safe, sane default */
+ default:
audmode = 0;
- return;
+ source = 1;
+ break;
}
msp->audmode = audmode;
msp34xxg_set_source(client, source);
@@ -1514,12 +1525,9 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
msp->opmode = opmode;
if (OPMODE_AUTO == msp->opmode) {
-#if 0 /* seems to work for ivtv only, disable by default for now ... */
if (HAVE_SIMPLER(msp))
msp->opmode = OPMODE_SIMPLER;
- else
-#endif
- if (HAVE_SIMPLE(msp))
+ else if (HAVE_SIMPLE(msp))
msp->opmode = OPMODE_SIMPLE;
else
msp->opmode = OPMODE_MANUAL;
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index cee13584c9c..fe6abe34168 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -32,9 +32,32 @@ MODULE_LICENSE("GPL");
static struct i2c_driver driver;
static struct i2c_client client_template;
+enum saa6752hs_videoformat {
+ SAA6752HS_VF_D1 = 0, /* standard D1 video format: 720x576 */
+ SAA6752HS_VF_2_3_D1 = 1,/* 2/3D1 video format: 480x576 */
+ SAA6752HS_VF_1_2_D1 = 2,/* 1/2D1 video format: 352x576 */
+ SAA6752HS_VF_SIF = 3, /* SIF video format: 352x288 */
+ SAA6752HS_VF_UNKNOWN,
+};
+
+static const struct v4l2_format v4l2_format_table[] =
+{
+ [SAA6752HS_VF_D1] = {
+ .fmt.pix.width = 720, .fmt.pix.height = 576 },
+ [SAA6752HS_VF_2_3_D1] = {
+ .fmt.pix.width = 480, .fmt.pix.height = 576 },
+ [SAA6752HS_VF_1_2_D1] = {
+ .fmt.pix.width = 352, .fmt.pix.height = 576 },
+ [SAA6752HS_VF_SIF] = {
+ .fmt.pix.width = 352, .fmt.pix.height = 288 },
+ [SAA6752HS_VF_UNKNOWN] = {
+ .fmt.pix.width = 0, .fmt.pix.height = 0},
+};
+
struct saa6752hs_state {
struct i2c_client client;
struct v4l2_mpeg_compression params;
+ enum saa6752hs_videoformat video_format;
};
enum saa6752hs_command {
@@ -256,6 +279,51 @@ static int saa6752hs_set_bitrate(struct i2c_client* client,
return 0;
}
+static void saa6752hs_set_subsampling(struct i2c_client* client,
+ struct v4l2_format* f)
+{
+ struct saa6752hs_state *h = i2c_get_clientdata(client);
+ int dist_352, dist_480, dist_720;
+
+ /*
+ FIXME: translate and round width/height into EMPRESS
+ subsample type:
+
+ type | PAL | NTSC
+ ---------------------------
+ SIF | 352x288 | 352x240
+ 1/2 D1 | 352x576 | 352x480
+ 2/3 D1 | 480x576 | 480x480
+ D1 | 720x576 | 720x480
+ */
+
+ dist_352 = abs(f->fmt.pix.width - 352);
+ dist_480 = abs(f->fmt.pix.width - 480);
+ dist_720 = abs(f->fmt.pix.width - 720);
+ if (dist_720 < dist_480) {
+ f->fmt.pix.width = 720;
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_D1;
+ }
+ else if (dist_480 < dist_352) {
+ f->fmt.pix.width = 480;
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_2_3_D1;
+ }
+ else {
+ f->fmt.pix.width = 352;
+ if (abs(f->fmt.pix.height - 576) <
+ abs(f->fmt.pix.height - 288)) {
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_1_2_D1;
+ }
+ else {
+ f->fmt.pix.height = 288;
+ h->video_format = SAA6752HS_VF_SIF;
+ }
+ }
+}
+
static void saa6752hs_set_params(struct i2c_client* client,
struct v4l2_mpeg_compression* params)
@@ -315,7 +383,7 @@ static int saa6752hs_init(struct i2c_client* client)
// Set video format - must be done first as it resets other settings
buf[0] = 0x41;
- buf[1] = 0 /* MPEG_VIDEO_FORMAT_D1 */;
+ buf[1] = h->video_format;
i2c_master_send(client, buf, 2);
// set bitrate
@@ -494,6 +562,25 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
case VIDIOC_G_MPEGCOMP:
*params = h->params;
break;
+ case VIDIOC_G_FMT:
+ {
+ struct v4l2_format *f = arg;
+
+ if (h->video_format == SAA6752HS_VF_UNKNOWN)
+ h->video_format = SAA6752HS_VF_D1;
+ f->fmt.pix.width =
+ v4l2_format_table[h->video_format].fmt.pix.width;
+ f->fmt.pix.height =
+ v4l2_format_table[h->video_format].fmt.pix.height;
+ break ;
+ }
+ case VIDIOC_S_FMT:
+ {
+ struct v4l2_format *f = arg;
+
+ saa6752hs_set_subsampling(client, f);
+ break;
+ }
default:
/* nothing */
break;
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 180d3175ea5..c51eb7f078d 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -183,12 +183,12 @@ struct saa7134_board saa7134_boards[] = {
.name = "LifeView FlyTV Platinum FM",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_TDA8290,
-// .gpiomask = 0xe000,
+ .gpiomask = 0x1E000, /* Set GP16 and unused 15,14,13 to Output */
.inputs = {{
.name = name_tv,
.vmux = 1,
.amux = TV,
-// .gpio = 0x0000,
+ .gpio = 0x10000, /* GP16=1 selects TV input */
.tv = 1,
},{
/* .name = name_tv_mono,
@@ -212,12 +212,12 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
// .gpio = 0x4000,
}},
-/* .radio = {
+ .radio = {
.name = name_radio,
- .amux = LINE2,
- .gpio = 0x2000,
+ .amux = TV,
+ .gpio = 0x00000, /* GP16=0 selects FM radio antenna */
},
-*/ },
+ },
[SAA7134_BOARD_EMPRESS] = {
/* "Gert Vervoort" <gert.vervoort@philips.com> */
.name = "EMPRESS",
@@ -1628,11 +1628,17 @@ struct pci_device_id saa7134_pci_tbl[] = {
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168,
+ .subvendor = 0x5168, /* Animation Technologies (LifeView) */
.subdevice = 0x0214, /* Standard PCI, LR214WF */
.driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1489, /* KYE */
+ .subdevice = 0x0214, /* Genius VideoWonder ProTV */
+ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, /* is an LR214WF actually */
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = 0x16be,
.subdevice = 0x0003,
@@ -1948,6 +1954,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
dev->has_remote = 1;
board_flyvideo(dev);
break;
+ case SAA7134_BOARD_FLYTVPLATINUM_FM:
case SAA7134_BOARD_CINERGY400:
case SAA7134_BOARD_CINERGY600:
case SAA7134_BOARD_CINERGY600_MK3:
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index dd4a6c8ee65..c2873ae029f 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -172,7 +172,7 @@ static int fe_request_firmware(struct dvb_frontend* fe,
return request_firmware(fw, name, &dev->pci->dev);
}
-struct tda1004x_config medion_cardbus = {
+static struct tda1004x_config medion_cardbus = {
.demod_address = 0x08, /* not sure this is correct */
.invert = 0,
.invert_oclk = 0,
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 2021e099e35..fa135733690 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -233,10 +233,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
memset(f,0,sizeof(*f));
f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- /* FIXME: translate subsampling type EMPRESS into
- * width/height: */
- f->fmt.pix.width = 720; /* D1 */
- f->fmt.pix.height = 576;
+ saa7134_i2c_call_clients(dev, cmd, arg);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
return 0;
@@ -249,20 +246,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- /*
- FIXME: translate and round width/height into EMPRESS
- subsample type:
-
- type | PAL | NTSC
- ---------------------------
- SIF | 352x288 | 352x240
- 1/2 D1 | 352x576 | 352x480
- 2/3 D1 | 480x576 | 480x480
- D1 | 720x576 | 720x480
- */
-
- f->fmt.pix.width = 720; /* D1 */
- f->fmt.pix.height = 576;
+ saa7134_i2c_call_clients(dev, cmd, arg);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE* dev->ts.nr_packets;
return 0;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 727d437e07d..ca50cf531f2 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -379,6 +379,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
switch (dev->board) {
case SAA7134_BOARD_FLYVIDEO2000:
case SAA7134_BOARD_FLYVIDEO3000:
+ case SAA7134_BOARD_FLYTVPLATINUM_FM:
ir_codes = flyvideo_codes;
mask_keycode = 0xEC00000;
mask_keydown = 0x0040000;
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 881a0539fc1..6212388edb7 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -357,8 +357,16 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
V4L2_TUNER_RADIO != t->mode)
set_tv_freq(client,400*16);
t->mode = f->type;
- t->freq = f->frequency;
- set_freq(client,t->freq);
+ set_freq(client,f->frequency);
+ break;
+ }
+ case VIDIOC_G_FREQUENCY:
+ {
+ struct v4l2_frequency *f = arg;
+
+ SWITCH_V4L2;
+ f->type = t->mode;
+ f->frequency = t->freq;
break;
}
case VIDIOC_G_TUNER:
@@ -368,6 +376,8 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
SWITCH_V4L2;
if (V4L2_TUNER_RADIO == t->mode && t->has_signal)
tuner->signal = t->has_signal(client);
+ tuner->rangelow = tv_range[0] * 16;
+ tuner->rangehigh = tv_range[1] * 16;
break;
}
default:
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 065eb4007b1..80dc34f18c2 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -991,7 +991,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
{
if (tda9874a_SIF > 2)
tda9874a_SIF = 1;
- if (tda9874a_STD >= 8)
+ if (tda9874a_STD > 8)
tda9874a_STD = 0;
if(tda9874a_AMSEL > 1)
tda9874a_AMSEL = 0;
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 72f2b466b81..2e70d74fbde 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -51,7 +51,7 @@ config MMC_PXA
config MMC_WBSD
tristate "Winbond W83L51xD SD/MMC Card Interface support"
- depends on MMC && ISA
+ depends on MMC && ISA && ISA_DMA_API
help
This selects the Winbond(R) W83L51xD Secure digital and
Multimedia card Interface.
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 43e2ac532f8..b5e07604343 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1581,7 +1581,8 @@ vortex_up(struct net_device *dev)
if (VORTEX_PCI(vp)) {
pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */
- pci_restore_state(VORTEX_PCI(vp));
+ if (vp->pm_state_valid)
+ pci_restore_state(VORTEX_PCI(vp));
pci_enable_device(VORTEX_PCI(vp));
}
@@ -2741,6 +2742,7 @@ vortex_down(struct net_device *dev, int final_down)
outl(0, ioaddr + DownListPtr);
if (final_down && VORTEX_PCI(vp)) {
+ vp->pm_state_valid = 1;
pci_save_state(VORTEX_PCI(vp));
acpi_set_WOL(dev);
}
@@ -3243,9 +3245,10 @@ static void acpi_set_WOL(struct net_device *dev)
outw(RxEnable, ioaddr + EL3_CMD);
pci_enable_wake(VORTEX_PCI(vp), 0, 1);
+
+ /* Change the power state to D3; RxEnable doesn't take effect. */
+ pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot);
}
- /* Change the power state to D3; RxEnable doesn't take effect. */
- pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot);
}
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 68242bda4b9..3a0a55b62aa 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -589,7 +589,7 @@ config EL2
config ELPLUS
tristate "3c505 \"EtherLink Plus\" support"
- depends on NET_VENDOR_3COM && ISA
+ depends on NET_VENDOR_3COM && ISA && ISA_DMA_API
---help---
Information about this network (Ethernet) card can be found in
<file:Documentation/networking/3c505.txt>. If you have a card of
@@ -630,7 +630,7 @@ config EL3
config 3C515
tristate "3c515 ISA \"Fast EtherLink\""
- depends on NET_VENDOR_3COM && (ISA || EISA)
+ depends on NET_VENDOR_3COM && (ISA || EISA) && ISA_DMA_API
help
If you have a 3Com ISA EtherLink XL "Corkscrew" 3c515 Fast Ethernet
network card, say Y and read the Ethernet-HOWTO, available from
@@ -708,7 +708,7 @@ config TYPHOON
config LANCE
tristate "AMD LANCE and PCnet (AT1500 and NE2100) support"
- depends on NET_ETHERNET && ISA
+ depends on NET_ETHERNET && ISA && ISA_DMA_API
help
If you have a network (Ethernet) card of this type, say Y and read
the Ethernet-HOWTO, available from
@@ -864,7 +864,7 @@ config NI52
config NI65
tristate "NI6510 support"
- depends on NET_VENDOR_RACAL && ISA
+ depends on NET_VENDOR_RACAL && ISA && ISA_DMA_API
help
If you have a network (Ethernet) card of this type, say Y and read
the Ethernet-HOWTO, available from
@@ -1072,7 +1072,7 @@ config NE2000
config ZNET
tristate "Zenith Z-Note support (EXPERIMENTAL)"
- depends on NET_ISA && EXPERIMENTAL
+ depends on NET_ISA && EXPERIMENTAL && ISA_DMA_API
help
The Zenith Z-Note notebook computer has a built-in network
(Ethernet) card, and this is the Linux driver for it. Note that the
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index fc519377b5a..fb433325aa2 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -7,7 +7,7 @@
*
* Version: @(#)Space.c 1.0.7 08/12/93
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Donald J. Becker, <becker@scyld.com>
*
diff --git a/drivers/net/appletalk/Kconfig b/drivers/net/appletalk/Kconfig
index 60b19679ca5..69c488d933a 100644
--- a/drivers/net/appletalk/Kconfig
+++ b/drivers/net/appletalk/Kconfig
@@ -13,7 +13,7 @@ config DEV_APPLETALK
config LTPC
tristate "Apple/Farallon LocalTalk PC support"
- depends on DEV_APPLETALK && (ISA || EISA)
+ depends on DEV_APPLETALK && (ISA || EISA) && ISA_DMA_API
help
This allows you to use the AppleTalk PC card to connect to LocalTalk
networks. The card is also known as the Farallon PhoneNet PC card.
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index 2161c2d585f..9edaa183227 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -65,7 +65,7 @@ static const char *version =
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
-#include <linux/if_ltalk.h> /* For ltalk_setup() */
+#include <linux/if_ltalk.h>
#include <linux/delay.h> /* For udelay() */
#include <linux/atalk.h>
#include <linux/spinlock.h>
@@ -223,7 +223,7 @@ struct net_device * __init cops_probe(int unit)
int base_addr;
int err = 0;
- dev = alloc_netdev(sizeof(struct cops_local), "lt%d", ltalk_setup);
+ dev = alloc_ltalkdev(sizeof(struct cops_local));
if (!dev)
return ERR_PTR(-ENOMEM);
diff --git a/drivers/net/appletalk/cops_ffdrv.h b/drivers/net/appletalk/cops_ffdrv.h
index 4131b4a7a65..31cf8c9c947 100644
--- a/drivers/net/appletalk/cops_ffdrv.h
+++ b/drivers/net/appletalk/cops_ffdrv.h
@@ -28,7 +28,7 @@
#ifdef CONFIG_COPS_DAYNA
-unsigned char ffdrv_code[] = {
+static const unsigned char ffdrv_code[] = {
58,3,0,50,228,149,33,255,255,34,226,149,
249,17,40,152,33,202,154,183,237,82,77,68,
11,107,98,19,54,0,237,176,175,50,80,0,
diff --git a/drivers/net/appletalk/cops_ltdrv.h b/drivers/net/appletalk/cops_ltdrv.h
index 05de66dd920..4afb8e18ba6 100644
--- a/drivers/net/appletalk/cops_ltdrv.h
+++ b/drivers/net/appletalk/cops_ltdrv.h
@@ -27,7 +27,7 @@
#ifdef CONFIG_COPS_TANGENT
-unsigned char ltdrv_code[] = {
+static const unsigned char ltdrv_code[] = {
58,3,0,50,148,10,33,143,15,62,85,119,
190,32,9,62,170,119,190,32,3,35,24,241,
34,146,10,249,17,150,10,33,143,15,183,237,
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
index ad8e943231a..db4f369637b 100644
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -1039,7 +1039,7 @@ struct net_device * __init ltpc_probe(void)
unsigned long f;
unsigned long timeout;
- dev = alloc_netdev(sizeof(struct ltpc_private), "lt%d", ltalk_setup);
+ dev = alloc_ltalkdev(sizeof(struct ltpc_private));
if (!dev)
goto out;
diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c
index 16e155b0412..66485585ab3 100644
--- a/drivers/net/arcnet/capmode.c
+++ b/drivers/net/arcnet/capmode.c
@@ -48,7 +48,7 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
static int ack_tx(struct net_device *dev, int acked);
-struct ArcProto capmode_proto =
+static struct ArcProto capmode_proto =
{
'r',
XMTU,
diff --git a/drivers/net/gt96100eth.h b/drivers/net/gt96100eth.h
index 2f4bfd4dacb..395869c5ed3 100644
--- a/drivers/net/gt96100eth.h
+++ b/drivers/net/gt96100eth.h
@@ -214,7 +214,7 @@ typedef struct {
u32 cmdstat;
u32 next;
u32 buff_ptr;
-} gt96100_td_t __attribute__ ((packed));
+} __attribute__ ((packed)) gt96100_td_t;
typedef struct {
#ifdef DESC_BE
@@ -227,7 +227,7 @@ typedef struct {
u32 cmdstat;
u32 next;
u32 buff_ptr;
-} gt96100_rd_t __attribute__ ((packed));
+} __attribute__ ((packed)) gt96100_rd_t;
/* Values for the Tx command-status descriptor entry. */
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 067b353e1cb..89454915b85 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -394,13 +394,11 @@ static void sp_bump(struct sixpack *sp, char cmd)
if ((skb = dev_alloc_skb(count)) == NULL)
goto out_mem;
- skb->dev = sp->dev;
ptr = skb_put(skb, count);
*ptr++ = cmd; /* KISS command */
memcpy(ptr, sp->cooked_buf + 1, count);
- skb->mac.raw = skb->data;
- skb->protocol = htons(ETH_P_AX25);
+ skb->protocol = ax25_type_trans(skb, sp->dev);
netif_rx(skb);
sp->dev->last_rx = jiffies;
sp->stats.rx_packets++;
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
index 34068f81d45..7cdebe1a0b6 100644
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -45,7 +45,7 @@ config BPQETHER
config DMASCC
tristate "High-speed (DMA) SCC driver for AX.25"
- depends on ISA && AX25 && BROKEN_ON_SMP
+ depends on ISA && AX25 && BROKEN_ON_SMP && ISA_DMA_API
---help---
This is a driver for high-speed SCC boards, i.e. those supporting
DMA on one port. You usually use those boards to connect your
@@ -78,7 +78,7 @@ config DMASCC
config SCC
tristate "Z8530 SCC driver"
- depends on ISA && AX25
+ depends on ISA && AX25 && ISA_DMA_API
---help---
These cards are used to connect your Linux box to an amateur radio
in order to communicate with other computers. If you want to use
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index e8cb87d906f..1c563f905a5 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -601,12 +601,10 @@ static void do_rxpacket(struct net_device *dev)
bc->stats.rx_dropped++;
return;
}
- skb->dev = dev;
cp = skb_put(skb, pktlen);
*cp++ = 0; /* KISS kludge */
memcpy(cp, bc->hdlcrx.buf, pktlen - 1);
- skb->protocol = htons(ETH_P_AX25);
- skb->mac.raw = skb->data;
+ skb->protocol = ax25_type_trans(skb, dev);
netif_rx(skb);
dev->last_rx = jiffies;
bc->stats.rx_packets++;
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index ef1a359e227..ba9f0580e1f 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -211,11 +211,7 @@ static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ty
ptr = skb_push(skb, 1);
*ptr = 0;
- skb->dev = dev;
- skb->protocol = htons(ETH_P_AX25);
- skb->mac.raw = skb->data;
- skb->pkt_type = PACKET_HOST;
-
+ skb->protocol = ax25_type_trans(skb, dev);
netif_rx(skb);
dev->last_rx = jiffies;
unlock:
@@ -272,8 +268,6 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
skb = newskb;
}
- skb->protocol = htons(ETH_P_AX25);
-
ptr = skb_push(skb, 2);
*ptr++ = (size + 5) % 256;
@@ -287,7 +281,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
return -ENODEV;
}
- skb->dev = dev;
+ skb->protocol = ax25_type_trans(skb, dev);
skb->nh.raw = skb->data;
dev->hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
bpq->stats.tx_packets++;
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index f3269b70a8c..f515245a3fd 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -1306,9 +1306,7 @@ static void rx_bh(void *arg)
data = skb_put(skb, cb + 1);
data[0] = 0;
memcpy(&data[1], priv->rx_buf[i], cb);
- skb->dev = priv->dev;
- skb->protocol = ntohs(ETH_P_AX25);
- skb->mac.raw = skb->data;
+ skb->protocol = ax25_type_trans(skb, priv->dev);
netif_rx(skb);
priv->dev->last_rx = jiffies;
priv->stats.rx_packets++;
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index b89959a596d..b4c836e4fe8 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -174,12 +174,10 @@ static void hdlc_rx_flag(struct net_device *dev, struct hdlcdrv_state *s)
s->stats.rx_dropped++;
return;
}
- skb->dev = dev;
cp = skb_put(skb, pkt_len);
*cp++ = 0; /* KISS kludge */
memcpy(cp, s->hdlcrx.buffer, pkt_len - 1);
- skb->protocol = htons(ETH_P_AX25);
- skb->mac.raw = skb->data;
+ skb->protocol = ax25_type_trans(skb, dev);
netif_rx(skb);
dev->last_rx = jiffies;
s->stats.rx_packets++;
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index d9ea080aea0..62790511098 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -332,12 +332,10 @@ static void ax_bump(struct ax_disp *ax)
return;
}
- skb->dev = ax->dev;
spin_lock_bh(&ax->buflock);
memcpy(skb_put(skb,count), ax->rbuff, count);
spin_unlock_bh(&ax->buflock);
- skb->mac.raw = skb->data;
- skb->protocol = htons(ETH_P_AX25);
+ skb->protocol = ax25_type_trans(skb, ax->dev);
netif_rx(skb);
ax->dev->last_rx = jiffies;
ax->rx_packets++;
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index ce9e7af020d..ece1b1a1318 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -1630,10 +1630,7 @@ static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb)
scc->dev_stat.rx_packets++;
scc->dev_stat.rx_bytes += skb->len;
- skb->dev = scc->dev;
- skb->protocol = htons(ETH_P_AX25);
- skb->mac.raw = skb->data;
- skb->pkt_type = PACKET_HOST;
+ skb->protocol = ax25_type_trans(skb, scc->dev);
netif_rx(skb);
scc->dev->last_rx = jiffies;
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index fd7b00fe38e..41213ef602d 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -522,12 +522,10 @@ static inline void yam_rx_flag(struct net_device *dev, struct yam_port *yp)
++yp->stats.rx_dropped;
} else {
unsigned char *cp;
- skb->dev = dev;
cp = skb_put(skb, pkt_len);
*cp++ = 0; /* KISS kludge */
memcpy(cp, yp->rx_buf, pkt_len - 1);
- skb->protocol = htons(ETH_P_AX25);
- skb->mac.raw = skb->data;
+ skb->protocol = ax25_type_trans(skb, dev);
netif_rx(skb);
dev->last_rx = jiffies;
++yp->stats.rx_packets;
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index acb170152bb..b3a898c5a58 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -13,8 +13,8 @@
** This driver has only been tested with
** -- HP J2585B 10/100 Mbit/s PCI Busmaster
** -- HP J2585A 10/100 Mbit/s PCI
-** -- HP J2970 10 Mbit/s PCI Combo 10base-T/BNC
-** -- HP J2973 10 Mbit/s PCI 10base-T
+** -- HP J2970A 10 Mbit/s PCI Combo 10base-T/BNC
+** -- HP J2973A 10 Mbit/s PCI 10base-T
** -- HP J2573 10/100 ISA
** -- Compex ReadyLink ENET100-VG4 10/100 Mbit/s PCI / EISA
** -- Compex FreedomLine 100/VG 10/100 Mbit/s ISA / EISA / PCI
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index 6bf76a444d4..1c553d7efdd 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -310,7 +310,7 @@ config SIGMATEL_FIR
config NSC_FIR
tristate "NSC PC87108/PC87338"
- depends on IRDA
+ depends on IRDA && ISA_DMA_API
help
Say Y here if you want to build support for the NSC PC87108 and
PC87338 IrDA chipsets. This driver supports SIR,
@@ -321,7 +321,7 @@ config NSC_FIR
config WINBOND_FIR
tristate "Winbond W83977AF (IR)"
- depends on IRDA
+ depends on IRDA && ISA_DMA_API
help
Say Y here if you want to build IrDA support for the Winbond
W83977AF super-io chipset. This driver should be used for the IrDA
@@ -347,7 +347,7 @@ config AU1000_FIR
config SMC_IRCC_FIR
tristate "SMSC IrCC (EXPERIMENTAL)"
- depends on EXPERIMENTAL && IRDA
+ depends on EXPERIMENTAL && IRDA && ISA_DMA_API
help
Say Y here if you want to build support for the SMC Infrared
Communications Controller. It is used in a wide variety of
@@ -357,7 +357,7 @@ config SMC_IRCC_FIR
config ALI_FIR
tristate "ALi M5123 FIR (EXPERIMENTAL)"
- depends on EXPERIMENTAL && IRDA
+ depends on EXPERIMENTAL && IRDA && ISA_DMA_API
help
Say Y here if you want to build support for the ALi M5123 FIR
Controller. The ALi M5123 FIR Controller is embedded in ALi M1543C,
@@ -385,7 +385,7 @@ config SA1100_FIR
config VIA_FIR
tristate "VIA VT8231/VT1211 SIR/MIR/FIR"
- depends on IRDA
+ depends on IRDA && ISA_DMA_API
help
Say Y here if you want to build support for the VIA VT8231
and VIA VT1211 IrDA controllers, found on the motherboards using
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 2ffc31708d5..b33111e2131 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -7,7 +7,7 @@
*
* Version: @(#)loopback.c 1.0.4b 08/16/93
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Donald Becker, <becker@scyld.com>
*
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 7e94d455533..0405e1f0d3d 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -99,7 +99,7 @@ static spinlock_t mv643xx_eth_phy_lock = SPIN_LOCK_UNLOCKED;
static inline u32 mv_read(int offset)
{
- void *__iomem reg_base;
+ void __iomem *reg_base;
reg_base = mv643xx_eth_shared_base - MV643XX_ETH_SHARED_REGS;
@@ -108,7 +108,7 @@ static inline u32 mv_read(int offset)
static inline void mv_write(int offset, u32 data)
{
- void * __iomem reg_base;
+ void __iomem *reg_base;
reg_base = mv643xx_eth_shared_base - MV643XX_ETH_SHARED_REGS;
writel(data, reg_base + offset);
diff --git a/drivers/net/ppp_deflate.c b/drivers/net/ppp_deflate.c
index 507d6328d4e..3872088fdd1 100644
--- a/drivers/net/ppp_deflate.c
+++ b/drivers/net/ppp_deflate.c
@@ -87,8 +87,7 @@ static void z_comp_free(void *arg)
if (state) {
zlib_deflateEnd(&state->strm);
- if (state->strm.workspace)
- vfree(state->strm.workspace);
+ vfree(state->strm.workspace);
kfree(state);
}
}
@@ -308,8 +307,7 @@ static void z_decomp_free(void *arg)
if (state) {
zlib_inflateEnd(&state->strm);
- if (state->strm.workspace)
- kfree(state->strm.workspace);
+ kfree(state->strm.workspace);
kfree(state);
}
}
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index c456dc81b87..3b377f6cd4a 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -2467,14 +2467,10 @@ static void ppp_destroy_interface(struct ppp *ppp)
skb_queue_purge(&ppp->mrq);
#endif /* CONFIG_PPP_MULTILINK */
#ifdef CONFIG_PPP_FILTER
- if (ppp->pass_filter) {
- kfree(ppp->pass_filter);
- ppp->pass_filter = NULL;
- }
- if (ppp->active_filter) {
- kfree(ppp->active_filter);
- ppp->active_filter = NULL;
- }
+ kfree(ppp->pass_filter);
+ ppp->pass_filter = NULL;
+ kfree(ppp->active_filter);
+ ppp->active_filter = NULL;
#endif /* CONFIG_PPP_FILTER */
kfree(ppp);
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 07e2df09491..c59507f8a76 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -2385,7 +2385,7 @@ core_down:
}
/* Give a racing hard_start_xmit a few cycles to complete. */
- synchronize_kernel();
+ synchronize_sched(); /* FIXME: should this be synchronize_irq()? */
/*
* And now for the 50k$ question: are IRQ disabled or not ?
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 4ce52f5f241..8f7841c0374 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -185,15 +185,12 @@ sl_alloc_bufs(struct slip *sl, int mtu)
/* Cleanup */
err_exit:
#ifdef SL_INCLUDE_CSLIP
- if (cbuff)
- kfree(cbuff);
+ kfree(cbuff);
if (slcomp)
slhc_free(slcomp);
#endif
- if (xbuff)
- kfree(xbuff);
- if (rbuff)
- kfree(rbuff);
+ kfree(xbuff);
+ kfree(rbuff);
return err;
}
@@ -204,13 +201,13 @@ sl_free_bufs(struct slip *sl)
void * tmp;
/* Free all SLIP frame buffers. */
- if ((tmp = xchg(&sl->rbuff, NULL)) != NULL)
- kfree(tmp);
- if ((tmp = xchg(&sl->xbuff, NULL)) != NULL)
- kfree(tmp);
+ tmp = xchg(&sl->rbuff, NULL);
+ kfree(tmp);
+ tmp = xchg(&sl->xbuff, NULL);
+ kfree(tmp);
#ifdef SL_INCLUDE_CSLIP
- if ((tmp = xchg(&sl->cbuff, NULL)) != NULL)
- kfree(tmp);
+ tmp = xchg(&sl->cbuff, NULL);
+ kfree(tmp);
if ((tmp = xchg(&sl->slcomp, NULL)) != NULL)
slhc_free(tmp);
#endif
@@ -297,13 +294,10 @@ done_on_bh:
spin_unlock_bh(&sl->lock);
done:
- if (xbuff)
- kfree(xbuff);
- if (rbuff)
- kfree(rbuff);
+ kfree(xbuff);
+ kfree(rbuff);
#ifdef SL_INCLUDE_CSLIP
- if (cbuff)
- kfree(cbuff);
+ kfree(cbuff);
#endif
return err;
}
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index 025dcd867ea..f88f5e32b71 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -37,8 +37,18 @@
#include "sunbmac.h"
+#define DRV_NAME "sunbmac"
+#define DRV_VERSION "2.0"
+#define DRV_RELDATE "11/24/03"
+#define DRV_AUTHOR "David S. Miller (davem@redhat.com)"
+
static char version[] __initdata =
- "sunbmac.c:v2.0 24/Nov/03 David S. Miller (davem@redhat.com)\n";
+ DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
+
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION("Sun BigMAC 100baseT ethernet driver");
+MODULE_LICENSE("GPL");
#undef DEBUG_PROBE
#undef DEBUG_TX
@@ -1321,4 +1331,3 @@ static void __exit bigmac_cleanup(void)
module_init(bigmac_probe);
module_exit(bigmac_cleanup);
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index d837b3c3572..f02fe4119b2 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -13,9 +13,6 @@
* argument : macaddr=0x00,0x10,0x20,0x30,0x40,0x50
*/
-static char version[] =
- "sunhme.c:v2.02 24/Aug/2003 David S. Miller (davem@redhat.com)\n";
-
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -67,15 +64,24 @@ static char version[] =
#include "sunhme.h"
+#define DRV_NAME "sunhme"
+#define DRV_VERSION "2.02"
+#define DRV_RELDATE "8/24/03"
+#define DRV_AUTHOR "David S. Miller (davem@redhat.com)"
+
+static char version[] =
+ DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
-#define DRV_NAME "sunhme"
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION("Sun HappyMealEthernet(HME) 10/100baseT ethernet driver");
+MODULE_LICENSE("GPL");
static int macaddr[6];
/* accept MAC address of the form macaddr=0x08,0x00,0x20,0x30,0x40,0x50 */
module_param_array(macaddr, int, NULL, 0);
MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set");
-MODULE_LICENSE("GPL");
static struct happy_meal *root_happy_dev;
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 62d464c7ef5..b7d87d4690b 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -69,9 +69,6 @@
#undef DEBUG_DRIVER
-static char version[] =
- "sunlance.c:v2.02 24/Aug/03 Miguel de Icaza (miguel@nuclecu.unam.mx)\n";
-
static char lancestr[] = "LANCE";
#include <linux/config.h>
@@ -108,6 +105,19 @@ static char lancestr[] = "LANCE";
#include <asm/auxio.h> /* For tpe-link-test? setting */
#include <asm/irq.h>
+#define DRV_NAME "sunlance"
+#define DRV_VERSION "2.02"
+#define DRV_RELDATE "8/24/03"
+#define DRV_AUTHOR "Miguel de Icaza (miguel@nuclecu.unam.mx)"
+
+static char version[] =
+ DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
+
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION("Sun Lance ethernet driver");
+MODULE_LICENSE("GPL");
+
/* Define: 2^4 Tx buffers and 2^4 Rx buffers */
#ifndef LANCE_LOG_TX_BUFFERS
#define LANCE_LOG_TX_BUFFERS 4
@@ -1611,4 +1621,3 @@ static void __exit sparc_lance_cleanup(void)
module_init(sparc_lance_probe);
module_exit(sparc_lance_cleanup);
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index 37ef1b82a6c..1f2323be60d 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -7,9 +7,6 @@
* Copyright (C) 1996, 1999, 2003 David S. Miller (davem@redhat.com)
*/
-static char version[] =
- "sunqe.c:v3.0 8/24/03 David S. Miller (davem@redhat.com)\n";
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
@@ -43,6 +40,19 @@ static char version[] =
#include "sunqe.h"
+#define DRV_NAME "sunqe"
+#define DRV_VERSION "3.0"
+#define DRV_RELDATE "8/24/03"
+#define DRV_AUTHOR "David S. Miller (davem@redhat.com)"
+
+static char version[] =
+ DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
+
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION("Sun QuadEthernet 10baseT SBUS card driver");
+MODULE_LICENSE("GPL");
+
static struct sunqec *root_qec_dev;
static void qe_set_multicast(struct net_device *dev);
@@ -1040,4 +1050,3 @@ static void __exit qec_cleanup(void)
module_init(qec_probe);
module_exit(qec_cleanup);
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 12de80884b1..f79b02e80e7 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -61,8 +61,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.25"
-#define DRV_MODULE_RELDATE "March 24, 2005"
+#define DRV_MODULE_VERSION "3.27"
+#define DRV_MODULE_RELDATE "May 5, 2005"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -85,8 +85,7 @@
/* hardware minimum and maximum for a single frame's data payload */
#define TG3_MIN_MTU 60
#define TG3_MAX_MTU(tp) \
- ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && \
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) ? 9000 : 1500)
+ (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ? 9000 : 1500)
/* These numbers seem to be hard coded in the NIC firmware somehow.
* You can't change the ring sizes, but you can change where you place
@@ -205,6 +204,8 @@ static struct pci_device_id tg3_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751F,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753M,
@@ -425,9 +426,30 @@ static void tg3_enable_ints(struct tg3 *tp)
tg3_cond_int(tp);
}
+static inline unsigned int tg3_has_work(struct tg3 *tp)
+{
+ struct tg3_hw_status *sblk = tp->hw_status;
+ unsigned int work_exists = 0;
+
+ /* check for phy events */
+ if (!(tp->tg3_flags &
+ (TG3_FLAG_USE_LINKCHG_REG |
+ TG3_FLAG_POLL_SERDES))) {
+ if (sblk->status & SD_STATUS_LINK_CHG)
+ work_exists = 1;
+ }
+ /* check for RX/TX work to do */
+ if (sblk->idx[0].tx_consumer != tp->tx_cons ||
+ sblk->idx[0].rx_producer != tp->rx_rcb_ptr)
+ work_exists = 1;
+
+ return work_exists;
+}
+
/* tg3_restart_ints
- * similar to tg3_enable_ints, but it can return without flushing the
- * PIO write which reenables interrupts
+ * similar to tg3_enable_ints, but it accurately determines whether there
+ * is new work pending and can return without flushing the PIO write
+ * which reenables interrupts
*/
static void tg3_restart_ints(struct tg3 *tp)
{
@@ -436,7 +458,9 @@ static void tg3_restart_ints(struct tg3 *tp)
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000);
mmiowb();
- tg3_cond_int(tp);
+ if (tg3_has_work(tp))
+ tw32(HOSTCC_MODE, tp->coalesce_mode |
+ (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW));
}
static inline void tg3_netif_stop(struct tg3 *tp)
@@ -860,8 +884,7 @@ out:
if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
/* Cannot do read-modify-write on 5401 */
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
- } else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) {
+ } else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
u32 phy_reg;
/* Set bit 14 with read-modify-write to preserve other bits */
@@ -873,8 +896,7 @@ out:
/* Set phy register 0x10 bit 0 to high fifo elasticity to support
* jumbo frames transmission.
*/
- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750) {
+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
u32 phy_reg;
if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &phy_reg))
@@ -1006,8 +1028,13 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
pci_write_config_word(tp->pdev,
pm + PCI_PM_CTRL,
power_control);
- tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
- udelay(100);
+ udelay(100); /* Delay after power state change */
+
+ /* Switch out of Vaux if it is not a LOM */
+ if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)) {
+ tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
+ udelay(100);
+ }
return 0;
@@ -1068,7 +1095,7 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
mac_mode = MAC_MODE_PORT_MODE_TBI;
}
- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750)
+ if (!(tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
tw32(MAC_LED_CTRL, tp->led_ctrl);
if (((power_caps & PCI_PM_CAP_PME_D3cold) &&
@@ -1095,7 +1122,7 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
CLOCK_CTRL_ALTCLK |
CLOCK_CTRL_PWRDOWN_PLL133);
udelay(40);
- } else if (!((GET_ASIC_REV(tp->pci_chip_rev_id) == 5750) &&
+ } else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) {
u32 newbits1, newbits2;
@@ -1152,6 +1179,7 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
/* Finally, set the new power state. */
pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control);
+ udelay(100); /* Delay after power state change */
tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
@@ -2681,8 +2709,8 @@ static int tg3_vlan_rx(struct tg3 *tp, struct sk_buff *skb, u16 vlan_tag)
static int tg3_rx(struct tg3 *tp, int budget)
{
u32 work_mask;
- u32 rx_rcb_ptr = tp->rx_rcb_ptr;
- u16 hw_idx, sw_idx;
+ u32 sw_idx = tp->rx_rcb_ptr;
+ u16 hw_idx;
int received;
hw_idx = tp->hw_status->idx[0].rx_producer;
@@ -2691,7 +2719,6 @@ static int tg3_rx(struct tg3 *tp, int budget)
* the opaque cookie.
*/
rmb();
- sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp);
work_mask = 0;
received = 0;
while (sw_idx != hw_idx && budget > 0) {
@@ -2796,14 +2823,19 @@ static int tg3_rx(struct tg3 *tp, int budget)
next_pkt:
(*post_ptr)++;
next_pkt_nopost:
- rx_rcb_ptr++;
- sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp);
+ sw_idx++;
+ sw_idx %= TG3_RX_RCB_RING_SIZE(tp);
+
+ /* Refresh hw_idx to see if there is new work */
+ if (sw_idx == hw_idx) {
+ hw_idx = tp->hw_status->idx[0].rx_producer;
+ rmb();
+ }
}
/* ACK the status ring. */
- tp->rx_rcb_ptr = rx_rcb_ptr;
- tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW,
- (rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp)));
+ tp->rx_rcb_ptr = sw_idx;
+ tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, sw_idx);
/* Refill RX ring(s). */
if (work_mask & RXD_OPAQUE_RING_STD) {
@@ -2882,24 +2914,41 @@ static int tg3_poll(struct net_device *netdev, int *budget)
return (done ? 0 : 1);
}
-static inline unsigned int tg3_has_work(struct net_device *dev, struct tg3 *tp)
+/* MSI ISR - No need to check for interrupt sharing and no need to
+ * flush status block and interrupt mailbox. PCI ordering rules
+ * guarantee that MSI will arrive after the status block.
+ */
+static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs)
{
+ struct net_device *dev = dev_id;
+ struct tg3 *tp = netdev_priv(dev);
struct tg3_hw_status *sblk = tp->hw_status;
- unsigned int work_exists = 0;
+ unsigned long flags;
- /* check for phy events */
- if (!(tp->tg3_flags &
- (TG3_FLAG_USE_LINKCHG_REG |
- TG3_FLAG_POLL_SERDES))) {
- if (sblk->status & SD_STATUS_LINK_CHG)
- work_exists = 1;
+ spin_lock_irqsave(&tp->lock, flags);
+
+ /*
+ * writing any value to intr-mbox-0 clears PCI INTA# and
+ * chip-internal interrupt pending events.
+ * writing non-zero to intr-mbox-0 additional tells the
+ * NIC to stop sending us irqs, engaging "in-intr-handler"
+ * event coalescing.
+ */
+ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+ sblk->status &= ~SD_STATUS_UPDATED;
+
+ if (likely(tg3_has_work(tp)))
+ netif_rx_schedule(dev); /* schedule NAPI poll */
+ else {
+ /* no work, re-enable interrupts
+ */
+ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+ 0x00000000);
}
- /* check for RX/TX work to do */
- if (sblk->idx[0].tx_consumer != tp->tx_cons ||
- sblk->idx[0].rx_producer != tp->rx_rcb_ptr)
- work_exists = 1;
- return work_exists;
+ spin_unlock_irqrestore(&tp->lock, flags);
+
+ return IRQ_RETVAL(1);
}
static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -2935,7 +2984,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
sblk->status &= ~SD_STATUS_UPDATED;
- if (likely(tg3_has_work(dev, tp)))
+ if (likely(tg3_has_work(tp)))
netif_rx_schedule(dev); /* schedule NAPI poll */
else {
/* no work, shared interrupt perhaps? re-enable
@@ -2954,13 +3003,31 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_RETVAL(handled);
}
+/* ISR for interrupt test */
+static irqreturn_t tg3_test_isr(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+ struct tg3 *tp = netdev_priv(dev);
+ struct tg3_hw_status *sblk = tp->hw_status;
+
+ if (sblk->status & SD_STATUS_UPDATED) {
+ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+ 0x00000001);
+ return IRQ_RETVAL(1);
+ }
+ return IRQ_RETVAL(0);
+}
+
static int tg3_init_hw(struct tg3 *);
-static int tg3_halt(struct tg3 *);
+static int tg3_halt(struct tg3 *, int);
#ifdef CONFIG_NET_POLL_CONTROLLER
static void tg3_poll_controller(struct net_device *dev)
{
- tg3_interrupt(dev->irq, dev, NULL);
+ struct tg3 *tp = netdev_priv(dev);
+
+ tg3_interrupt(tp->pdev->irq, dev, NULL);
}
#endif
@@ -2977,7 +3044,7 @@ static void tg3_reset_task(void *_data)
restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER;
tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER;
- tg3_halt(tp);
+ tg3_halt(tp, 0);
tg3_init_hw(tp);
tg3_netif_start(tp);
@@ -3323,7 +3390,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
- tg3_halt(tp);
+ tg3_halt(tp, 1);
tg3_set_mtu(dev, tp, new_mtu);
@@ -3590,7 +3657,7 @@ err_out:
/* To stop a block, clear the enable bit and poll till it
* clears. tp->lock is held.
*/
-static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit)
+static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, int silent)
{
unsigned int i;
u32 val;
@@ -3623,7 +3690,7 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit)
break;
}
- if (i == MAX_WAIT_CNT) {
+ if (i == MAX_WAIT_CNT && !silent) {
printk(KERN_ERR PFX "tg3_stop_block timed out, "
"ofs=%lx enable_bit=%x\n",
ofs, enable_bit);
@@ -3634,7 +3701,7 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit)
}
/* tp->lock is held. */
-static int tg3_abort_hw(struct tg3 *tp)
+static int tg3_abort_hw(struct tg3 *tp, int silent)
{
int i, err;
@@ -3644,22 +3711,20 @@ static int tg3_abort_hw(struct tg3 *tp)
tw32_f(MAC_RX_MODE, tp->rx_mode);
udelay(10);
- err = tg3_stop_block(tp, RCVBDI_MODE, RCVBDI_MODE_ENABLE);
- err |= tg3_stop_block(tp, RCVLPC_MODE, RCVLPC_MODE_ENABLE);
- err |= tg3_stop_block(tp, RCVLSC_MODE, RCVLSC_MODE_ENABLE);
- err |= tg3_stop_block(tp, RCVDBDI_MODE, RCVDBDI_MODE_ENABLE);
- err |= tg3_stop_block(tp, RCVDCC_MODE, RCVDCC_MODE_ENABLE);
- err |= tg3_stop_block(tp, RCVCC_MODE, RCVCC_MODE_ENABLE);
-
- err |= tg3_stop_block(tp, SNDBDS_MODE, SNDBDS_MODE_ENABLE);
- err |= tg3_stop_block(tp, SNDBDI_MODE, SNDBDI_MODE_ENABLE);
- err |= tg3_stop_block(tp, SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
- err |= tg3_stop_block(tp, RDMAC_MODE, RDMAC_MODE_ENABLE);
- err |= tg3_stop_block(tp, SNDDATAC_MODE, SNDDATAC_MODE_ENABLE);
- err |= tg3_stop_block(tp, DMAC_MODE, DMAC_MODE_ENABLE);
- err |= tg3_stop_block(tp, SNDBDC_MODE, SNDBDC_MODE_ENABLE);
- if (err)
- goto out;
+ err = tg3_stop_block(tp, RCVBDI_MODE, RCVBDI_MODE_ENABLE, silent);
+ err |= tg3_stop_block(tp, RCVLPC_MODE, RCVLPC_MODE_ENABLE, silent);
+ err |= tg3_stop_block(tp, RCVLSC_MODE, RCVLSC_MODE_ENABLE, silent);
+ err |= tg3_stop_block(tp, RCVDBDI_MODE, RCVDBDI_MODE_ENABLE, silent);
+ err |= tg3_stop_block(tp, RCVDCC_MODE, RCVDCC_MODE_ENABLE, silent);
+ err |= tg3_stop_block(tp, RCVCC_MODE, RCVCC_MODE_ENABLE, silent);
+
+ err |= tg3_stop_block(tp, SNDBDS_MODE, SNDBDS_MODE_ENABLE, silent);
+ err |= tg3_stop_block(tp, SNDBDI_MODE, SNDBDI_MODE_ENABLE, silent);
+ err |= tg3_stop_block(tp, SNDDATAI_MODE, SNDDATAI_MODE_ENABLE, silent);
+ err |= tg3_stop_block(tp, RDMAC_MODE, RDMAC_MODE_ENABLE, silent);
+ err |= tg3_stop_block(tp, SNDDATAC_MODE, SNDDATAC_MODE_ENABLE, silent);
+ err |= tg3_stop_block(tp, DMAC_MODE, DMAC_MODE_ENABLE, silent);
+ err |= tg3_stop_block(tp, SNDBDC_MODE, SNDBDC_MODE_ENABLE, silent);
tp->mac_mode &= ~MAC_MODE_TDE_ENABLE;
tw32_f(MAC_MODE, tp->mac_mode);
@@ -3677,27 +3742,24 @@ static int tg3_abort_hw(struct tg3 *tp)
printk(KERN_ERR PFX "tg3_abort_hw timed out for %s, "
"TX_MODE_ENABLE will not clear MAC_TX_MODE=%08x\n",
tp->dev->name, tr32(MAC_TX_MODE));
- return -ENODEV;
+ err |= -ENODEV;
}
- err = tg3_stop_block(tp, HOSTCC_MODE, HOSTCC_MODE_ENABLE);
- err |= tg3_stop_block(tp, WDMAC_MODE, WDMAC_MODE_ENABLE);
- err |= tg3_stop_block(tp, MBFREE_MODE, MBFREE_MODE_ENABLE);
+ err |= tg3_stop_block(tp, HOSTCC_MODE, HOSTCC_MODE_ENABLE, silent);
+ err |= tg3_stop_block(tp, WDMAC_MODE, WDMAC_MODE_ENABLE, silent);
+ err |= tg3_stop_block(tp, MBFREE_MODE, MBFREE_MODE_ENABLE, silent);
tw32(FTQ_RESET, 0xffffffff);
tw32(FTQ_RESET, 0x00000000);
- err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE);
- err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE);
- if (err)
- goto out;
+ err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent);
+ err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent);
if (tp->hw_status)
memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
if (tp->hw_stats)
memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats));
-out:
return err;
}
@@ -3727,6 +3789,28 @@ static void tg3_nvram_unlock(struct tg3 *tp)
}
/* tp->lock is held. */
+static void tg3_enable_nvram_access(struct tg3 *tp)
+{
+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+ !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
+ u32 nvaccess = tr32(NVRAM_ACCESS);
+
+ tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
+ }
+}
+
+/* tp->lock is held. */
+static void tg3_disable_nvram_access(struct tg3 *tp)
+{
+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+ !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
+ u32 nvaccess = tr32(NVRAM_ACCESS);
+
+ tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
+ }
+}
+
+/* tp->lock is held. */
static void tg3_write_sig_pre_reset(struct tg3 *tp, int kind)
{
if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X))
@@ -3967,7 +4051,7 @@ static int tg3_chip_reset(struct tg3 *tp)
tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)
+ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
}
}
@@ -3997,7 +4081,7 @@ static void tg3_stop_fw(struct tg3 *tp)
}
/* tp->lock is held. */
-static int tg3_halt(struct tg3 *tp)
+static int tg3_halt(struct tg3 *tp, int silent)
{
int err;
@@ -4005,7 +4089,7 @@ static int tg3_halt(struct tg3 *tp)
tg3_write_sig_pre_reset(tp, RESET_KIND_SHUTDOWN);
- tg3_abort_hw(tp);
+ tg3_abort_hw(tp, silent);
err = tg3_chip_reset(tp);
tg3_write_sig_legacy(tp, RESET_KIND_SHUTDOWN);
@@ -4974,9 +5058,7 @@ static int tg3_reset_hw(struct tg3 *tp)
tg3_write_sig_pre_reset(tp, RESET_KIND_INIT);
if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) {
- err = tg3_abort_hw(tp);
- if (err)
- return err;
+ tg3_abort_hw(tp, 1);
}
err = tg3_chip_reset(tp);
@@ -5041,7 +5123,7 @@ static int tg3_reset_hw(struct tg3 *tp)
tw32(GRC_MISC_CFG, val);
/* Initialize MBUF/DESC pool. */
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
+ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
/* Do nothing. */
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE);
@@ -5238,6 +5320,8 @@ static int tg3_reset_hw(struct tg3 *tp)
RDMAC_MODE_LNGREAD_ENAB);
if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
rdmac_mode |= RDMAC_MODE_SPLIT_ENABLE;
+
+ /* If statement applies to 5705 and 5750 PCI devices only */
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) ||
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)) {
@@ -5251,6 +5335,9 @@ static int tg3_reset_hw(struct tg3 *tp)
}
}
+ if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
+ rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;
+
#if TG3_TSO_SUPPORT != 0
if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
rdmac_mode |= (1 << 27);
@@ -5332,10 +5419,28 @@ static int tg3_reset_hw(struct tg3 *tp)
tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR);
udelay(40);
- tp->grc_local_ctrl = GRC_LCLCTRL_INT_ON_ATTN | GRC_LCLCTRL_AUTO_SEEPROM;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
+ /* tp->grc_local_ctrl is partially set up during tg3_get_invariants().
+ * If TG3_FLAG_EEPROM_WRITE_PROT is set, we should read the
+ * register to preserve the GPIO settings for LOMs. The GPIOs,
+ * whether used as inputs or outputs, are set by boot code after
+ * reset.
+ */
+ if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) {
+ u32 gpio_mask;
+
+ gpio_mask = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE2 |
+ GRC_LCLCTRL_GPIO_OUTPUT0 | GRC_LCLCTRL_GPIO_OUTPUT2;
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
+ gpio_mask |= GRC_LCLCTRL_GPIO_OE3 |
+ GRC_LCLCTRL_GPIO_OUTPUT3;
+
+ tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask;
+
+ /* GPIO1 must be driven high for eeprom write protect */
tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 |
GRC_LCLCTRL_GPIO_OUTPUT1);
+ }
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
udelay(100);
@@ -5353,6 +5458,7 @@ static int tg3_reset_hw(struct tg3 *tp)
WDMAC_MODE_FIFOURUN_ENAB | WDMAC_MODE_FIFOOREAD_ENAB |
WDMAC_MODE_LNGREAD_ENAB);
+ /* If statement applies to 5705 and 5750 PCI devices only */
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
@@ -5706,6 +5812,118 @@ static void tg3_timer(unsigned long __opaque)
add_timer(&tp->timer);
}
+static int tg3_test_interrupt(struct tg3 *tp)
+{
+ struct net_device *dev = tp->dev;
+ int err, i;
+ u32 int_mbox = 0;
+
+ tg3_disable_ints(tp);
+
+ free_irq(tp->pdev->irq, dev);
+
+ err = request_irq(tp->pdev->irq, tg3_test_isr,
+ SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
+ if (err)
+ return err;
+
+ tg3_enable_ints(tp);
+
+ tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
+ HOSTCC_MODE_NOW);
+
+ for (i = 0; i < 5; i++) {
+ int_mbox = tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
+ if (int_mbox != 0)
+ break;
+ msleep(10);
+ }
+
+ tg3_disable_ints(tp);
+
+ free_irq(tp->pdev->irq, dev);
+
+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI)
+ err = request_irq(tp->pdev->irq, tg3_msi,
+ SA_SAMPLE_RANDOM, dev->name, dev);
+ else
+ err = request_irq(tp->pdev->irq, tg3_interrupt,
+ SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
+
+ if (err)
+ return err;
+
+ if (int_mbox != 0)
+ return 0;
+
+ return -EIO;
+}
+
+/* Returns 0 if MSI test succeeds or MSI test fails and INTx mode is
+ * successfully restored
+ */
+static int tg3_test_msi(struct tg3 *tp)
+{
+ struct net_device *dev = tp->dev;
+ int err;
+ u16 pci_cmd;
+
+ if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSI))
+ return 0;
+
+ /* Turn off SERR reporting in case MSI terminates with Master
+ * Abort.
+ */
+ pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
+ pci_write_config_word(tp->pdev, PCI_COMMAND,
+ pci_cmd & ~PCI_COMMAND_SERR);
+
+ err = tg3_test_interrupt(tp);
+
+ pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
+
+ if (!err)
+ return 0;
+
+ /* other failures */
+ if (err != -EIO)
+ return err;
+
+ /* MSI test failed, go back to INTx mode */
+ printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, "
+ "switching to INTx mode. Please report this failure to "
+ "the PCI maintainer and include system chipset information.\n",
+ tp->dev->name);
+
+ free_irq(tp->pdev->irq, dev);
+ pci_disable_msi(tp->pdev);
+
+ tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
+
+ err = request_irq(tp->pdev->irq, tg3_interrupt,
+ SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
+
+ if (err)
+ return err;
+
+ /* Need to reset the chip because the MSI cycle may have terminated
+ * with Master Abort.
+ */
+ spin_lock_irq(&tp->lock);
+ spin_lock(&tp->tx_lock);
+
+ tg3_halt(tp, 1);
+ err = tg3_init_hw(tp);
+
+ spin_unlock(&tp->tx_lock);
+ spin_unlock_irq(&tp->lock);
+
+ if (err)
+ free_irq(tp->pdev->irq, dev);
+
+ return err;
+}
+
static int tg3_open(struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
@@ -5727,10 +5945,29 @@ static int tg3_open(struct net_device *dev)
if (err)
return err;
- err = request_irq(dev->irq, tg3_interrupt,
- SA_SHIRQ, dev->name, dev);
+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+ (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_AX) &&
+ (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_BX)) {
+ if (pci_enable_msi(tp->pdev) == 0) {
+ u32 msi_mode;
+
+ msi_mode = tr32(MSGINT_MODE);
+ tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE);
+ tp->tg3_flags2 |= TG3_FLG2_USING_MSI;
+ }
+ }
+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI)
+ err = request_irq(tp->pdev->irq, tg3_msi,
+ SA_SAMPLE_RANDOM, dev->name, dev);
+ else
+ err = request_irq(tp->pdev->irq, tg3_interrupt,
+ SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
if (err) {
+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+ pci_disable_msi(tp->pdev);
+ tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
+ }
tg3_free_consistent(tp);
return err;
}
@@ -5740,7 +5977,7 @@ static int tg3_open(struct net_device *dev)
err = tg3_init_hw(tp);
if (err) {
- tg3_halt(tp);
+ tg3_halt(tp, 1);
tg3_free_rings(tp);
} else {
tp->timer_offset = HZ / 10;
@@ -5751,23 +5988,47 @@ static int tg3_open(struct net_device *dev)
tp->timer.expires = jiffies + tp->timer_offset;
tp->timer.data = (unsigned long) tp;
tp->timer.function = tg3_timer;
- add_timer(&tp->timer);
-
- tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
}
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock);
if (err) {
- free_irq(dev->irq, dev);
+ free_irq(tp->pdev->irq, dev);
+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+ pci_disable_msi(tp->pdev);
+ tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
+ }
tg3_free_consistent(tp);
return err;
}
+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+ err = tg3_test_msi(tp);
+ if (err) {
+ spin_lock_irq(&tp->lock);
+ spin_lock(&tp->tx_lock);
+
+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+ pci_disable_msi(tp->pdev);
+ tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
+ }
+ tg3_halt(tp, 1);
+ tg3_free_rings(tp);
+ tg3_free_consistent(tp);
+
+ spin_unlock(&tp->tx_lock);
+ spin_unlock_irq(&tp->lock);
+
+ return err;
+ }
+ }
+
spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
+ add_timer(&tp->timer);
+ tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
tg3_enable_ints(tp);
spin_unlock(&tp->tx_lock);
@@ -6025,7 +6286,7 @@ static int tg3_close(struct net_device *dev)
tg3_disable_ints(tp);
- tg3_halt(tp);
+ tg3_halt(tp, 1);
tg3_free_rings(tp);
tp->tg3_flags &=
~(TG3_FLAG_INIT_COMPLETE |
@@ -6035,7 +6296,11 @@ static int tg3_close(struct net_device *dev)
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock);
- free_irq(dev->irq, dev);
+ free_irq(tp->pdev->irq, dev);
+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+ pci_disable_msi(tp->pdev);
+ tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
+ }
memcpy(&tp->net_stats_prev, tg3_get_stats(tp->dev),
sizeof(tp->net_stats_prev));
@@ -6509,10 +6774,12 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
start = cpu_to_le32(start);
len += b_offset;
offset &= ~3;
+ if (len < 4)
+ len = 4;
}
odd_len = 0;
- if ((len & 3) && ((len > 4) || (b_offset == 0))) {
+ if (len & 3) {
/* adjustments to end on required 4 byte boundary */
odd_len = 1;
len = (len + 3) & ~3;
@@ -6739,7 +7006,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
tp->tx_pending = ering->tx_pending;
if (netif_running(dev)) {
- tg3_halt(tp);
+ tg3_halt(tp, 1);
tg3_init_hw(tp);
tg3_netif_start(tp);
}
@@ -6782,7 +7049,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE;
if (netif_running(dev)) {
- tg3_halt(tp);
+ tg3_halt(tp, 1);
tg3_init_hw(tp);
tg3_netif_start(tp);
}
@@ -7067,6 +7334,67 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp)
}
}
+static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp)
+{
+ u32 nvcfg1;
+
+ nvcfg1 = tr32(NVRAM_CFG1);
+
+ /* NVRAM protection for TPM */
+ if (nvcfg1 & (1 << 27))
+ tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
+
+ switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+ case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ:
+ case FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ break;
+ case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ break;
+ case FLASH_5752VENDOR_ST_M45PE10:
+ case FLASH_5752VENDOR_ST_M45PE20:
+ case FLASH_5752VENDOR_ST_M45PE40:
+ tp->nvram_jedecnum = JEDEC_ST;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ break;
+ }
+
+ if (tp->tg3_flags2 & TG3_FLG2_FLASH) {
+ switch (nvcfg1 & NVRAM_CFG1_5752PAGE_SIZE_MASK) {
+ case FLASH_5752PAGE_SIZE_256:
+ tp->nvram_pagesize = 256;
+ break;
+ case FLASH_5752PAGE_SIZE_512:
+ tp->nvram_pagesize = 512;
+ break;
+ case FLASH_5752PAGE_SIZE_1K:
+ tp->nvram_pagesize = 1024;
+ break;
+ case FLASH_5752PAGE_SIZE_2K:
+ tp->nvram_pagesize = 2048;
+ break;
+ case FLASH_5752PAGE_SIZE_4K:
+ tp->nvram_pagesize = 4096;
+ break;
+ case FLASH_5752PAGE_SIZE_264:
+ tp->nvram_pagesize = 264;
+ break;
+ }
+ }
+ else {
+ /* For eeprom, set pagesize to maximum eeprom size */
+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+
+ nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+ tw32(NVRAM_CFG1, nvcfg1);
+ }
+}
+
/* Chips other than 5700/5701 use the NVRAM for fetching info. */
static void __devinit tg3_nvram_init(struct tg3 *tp)
{
@@ -7093,20 +7421,16 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
tp->tg3_flags |= TG3_FLAG_NVRAM;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
- u32 nvaccess = tr32(NVRAM_ACCESS);
+ tg3_enable_nvram_access(tp);
- tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
- }
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
+ tg3_get_5752_nvram_info(tp);
+ else
+ tg3_get_nvram_info(tp);
- tg3_get_nvram_info(tp);
tg3_get_nvram_size(tp);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
- u32 nvaccess = tr32(NVRAM_ACCESS);
-
- tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
- }
+ tg3_disable_nvram_access(tp);
} else {
tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED);
@@ -7195,11 +7519,7 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
tg3_nvram_lock(tp);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
- u32 nvaccess = tr32(NVRAM_ACCESS);
-
- tw32_f(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
- }
+ tg3_enable_nvram_access(tp);
tw32(NVRAM_ADDR, offset);
ret = tg3_nvram_exec_cmd(tp, NVRAM_CMD_RD | NVRAM_CMD_GO |
@@ -7210,11 +7530,7 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
tg3_nvram_unlock(tp);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
- u32 nvaccess = tr32(NVRAM_ACCESS);
-
- tw32_f(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
- }
+ tg3_disable_nvram_access(tp);
return ret;
}
@@ -7277,7 +7593,7 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
while (len) {
int j;
- u32 phy_addr, page_off, size, nvaccess;
+ u32 phy_addr, page_off, size;
phy_addr = offset & ~pagemask;
@@ -7300,8 +7616,7 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
offset = offset + (pagesize - page_off);
- nvaccess = tr32(NVRAM_ACCESS);
- tw32_f(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
+ tg3_enable_nvram_access(tp);
/*
* Before we can erase the flash page, we need
@@ -7425,8 +7740,8 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
}
if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) {
- tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
- GRC_LCLCTRL_GPIO_OE1);
+ tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl &
+ ~GRC_LCLCTRL_GPIO_OUTPUT1);
udelay(40);
}
@@ -7438,13 +7753,10 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
tg3_nvram_lock(tp);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
- u32 nvaccess = tr32(NVRAM_ACCESS);
-
- tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
-
+ tg3_enable_nvram_access(tp);
+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+ !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM))
tw32(NVRAM_WRITE1, 0x406);
- }
grc_mode = tr32(GRC_MODE);
tw32(GRC_MODE, grc_mode | GRC_MODE_NVRAM_WR_ENABLE);
@@ -7463,17 +7775,12 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
grc_mode = tr32(GRC_MODE);
tw32(GRC_MODE, grc_mode & ~GRC_MODE_NVRAM_WR_ENABLE);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
- u32 nvaccess = tr32(NVRAM_ACCESS);
-
- tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
- }
+ tg3_disable_nvram_access(tp);
tg3_nvram_unlock(tp);
}
if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) {
- tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
- GRC_LCLCTRL_GPIO_OE1 | GRC_LCLCTRL_GPIO_OUTPUT1);
+ tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
udelay(40);
}
@@ -7537,21 +7844,27 @@ static inline struct subsys_tbl_ent *lookup_by_subsys(struct tg3 *tp)
return NULL;
}
-static int __devinit tg3_phy_probe(struct tg3 *tp)
+/* Since this function may be called in D3-hot power state during
+ * tg3_init_one(), only config cycles are allowed.
+ */
+static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
{
- u32 eeprom_phy_id, hw_phy_id_1, hw_phy_id_2;
- u32 hw_phy_id, hw_phy_id_masked;
u32 val;
- int eeprom_signature_found, eeprom_phy_serdes, err;
+
+ /* Make sure register accesses (indirect or otherwise)
+ * will function correctly.
+ */
+ pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
+ tp->misc_host_ctrl);
tp->phy_id = PHY_ID_INVALID;
- eeprom_phy_id = PHY_ID_INVALID;
- eeprom_phy_serdes = 0;
- eeprom_signature_found = 0;
+ tp->led_ctrl = LED_CTRL_MODE_PHY_1;
+
tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
if (val == NIC_SRAM_DATA_SIG_MAGIC) {
u32 nic_cfg, led_cfg;
- u32 nic_phy_id, ver, cfg2 = 0;
+ u32 nic_phy_id, ver, cfg2 = 0, eeprom_phy_id;
+ int eeprom_phy_serdes = 0;
tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
tp->nic_sram_data_cfg = nic_cfg;
@@ -7564,8 +7877,6 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
(ver > 0) && (ver < 0x100))
tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &cfg2);
- eeprom_signature_found = 1;
-
if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) ==
NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER)
eeprom_phy_serdes = 1;
@@ -7581,10 +7892,14 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
} else
eeprom_phy_id = 0;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
+ tp->phy_id = eeprom_phy_id;
+ if (eeprom_phy_serdes)
+ tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
+
+ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
led_cfg = cfg2 & (NIC_SRAM_DATA_CFG_LED_MODE_MASK |
SHASTA_EXT_LED_MODE_MASK);
- } else
+ else
led_cfg = nic_cfg & NIC_SRAM_DATA_CFG_LED_MODE_MASK;
switch (led_cfg) {
@@ -7634,7 +7949,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)
+ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
}
if (nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL)
@@ -7648,6 +7963,13 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
if (cfg2 & (1 << 18))
tp->tg3_flags2 |= TG3_FLG2_SERDES_PREEMPHASIS;
}
+}
+
+static int __devinit tg3_phy_probe(struct tg3 *tp)
+{
+ u32 hw_phy_id_1, hw_phy_id_2;
+ u32 hw_phy_id, hw_phy_id_masked;
+ int err;
/* Reading the PHY ID register can conflict with ASF
* firwmare access to the PHY hardware.
@@ -7676,10 +7998,10 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
if (hw_phy_id_masked == PHY_ID_BCM8002)
tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
} else {
- if (eeprom_signature_found) {
- tp->phy_id = eeprom_phy_id;
- if (eeprom_phy_serdes)
- tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
+ if (tp->phy_id != PHY_ID_INVALID) {
+ /* Do nothing, phy ID already set up in
+ * tg3_get_eeprom_hw_cfg().
+ */
} else {
struct subsys_tbl_ent *p;
@@ -7750,9 +8072,6 @@ skip_phy_reset:
err = tg3_init_5401phy_dsp(tp);
}
- if (!eeprom_signature_found)
- tp->led_ctrl = LED_CTRL_MODE_PHY_1;
-
if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
tp->link_config.advertising =
(ADVERTISED_1000baseT_Half |
@@ -7917,6 +8236,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->pci_chip_rev_id = (misc_ctrl_reg >>
MISC_HOST_CTRL_CHIPREV_SHIFT);
+ /* Wrong chip ID in 5752 A0. This code can be removed later
+ * as A0 is not in production.
+ */
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW)
+ tp->pci_chip_rev_id = CHIPREV_ID_5752_A0;
+
/* Initialize misc host control in PCI block. */
tp->misc_host_ctrl |= (misc_ctrl_reg &
MISC_HOST_CTRL_CHIPREV);
@@ -7931,11 +8256,15 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->pci_hdr_type = (cacheline_sz_reg >> 16) & 0xff;
tp->pci_bist = (cacheline_sz_reg >> 24) & 0xff;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
+ tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
+
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) ||
- (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750))
+ (tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
tp->tg3_flags2 |= TG3_FLG2_5705_PLUS;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)
+ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
tp->tg3_flags2 |= TG3_FLG2_HW_TSO;
if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0)
@@ -8013,6 +8342,31 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg);
}
+ /* Get eeprom hw config before calling tg3_set_power_state().
+ * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be
+ * determined before calling tg3_set_power_state() so that
+ * we know whether or not to switch out of Vaux power.
+ * When the flag is set, it means that GPIO1 is used for eeprom
+ * write protect and also implies that it is a LOM where GPIOs
+ * are not used to switch power.
+ */
+ tg3_get_eeprom_hw_cfg(tp);
+
+ /* Set up tp->grc_local_ctrl before calling tg3_set_power_state().
+ * GPIO1 driven high will bring 5700's external PHY out of reset.
+ * It is also used as eeprom write protect on LOMs.
+ */
+ tp->grc_local_ctrl = GRC_LCLCTRL_INT_ON_ATTN | GRC_LCLCTRL_AUTO_SEEPROM;
+ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) ||
+ (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT))
+ tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 |
+ GRC_LCLCTRL_GPIO_OUTPUT1);
+ /* Unused GPIO3 must be driven as output on 5752 because there
+ * are no pull-up resistors on unused GPIO pins.
+ */
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
+ tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
+
/* Force the chip into D0. */
err = tg3_set_power_state(tp, 0);
if (err) {
@@ -8065,8 +8419,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)
tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)
+ if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
/* Only 5701 and later support tagged irq status mode.
@@ -8628,6 +8981,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
case PHY_ID_BCM5704: return "5704";
case PHY_ID_BCM5705: return "5705";
case PHY_ID_BCM5750: return "5750";
+ case PHY_ID_BCM5752: return "5752";
case PHY_ID_BCM8002: return "8002/serdes";
case 0: return "serdes";
default: return "unknown";
@@ -8878,7 +9232,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
pci_save_state(tp->pdev);
tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
- tg3_halt(tp);
+ tg3_halt(tp, 1);
}
err = tg3_test_dma(tp);
@@ -9001,7 +9355,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
- tg3_halt(tp);
+ tg3_halt(tp, 1);
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock);
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index d48887d9032..8de6f21037b 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -125,6 +125,9 @@
#define CHIPREV_ID_5750_A0 0x4000
#define CHIPREV_ID_5750_A1 0x4001
#define CHIPREV_ID_5750_A3 0x4003
+#define CHIPREV_ID_5752_A0_HW 0x5000
+#define CHIPREV_ID_5752_A0 0x6000
+#define CHIPREV_ID_5752_A1 0x6001
#define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12)
#define ASIC_REV_5700 0x07
#define ASIC_REV_5701 0x00
@@ -132,6 +135,7 @@
#define ASIC_REV_5704 0x02
#define ASIC_REV_5705 0x03
#define ASIC_REV_5750 0x04
+#define ASIC_REV_5752 0x06
#define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8)
#define CHIPREV_5700_AX 0x70
#define CHIPREV_5700_BX 0x71
@@ -1307,6 +1311,9 @@
#define GRC_LCLCTRL_CLEARINT 0x00000002
#define GRC_LCLCTRL_SETINT 0x00000004
#define GRC_LCLCTRL_INT_ON_ATTN 0x00000008
+#define GRC_LCLCTRL_GPIO_INPUT3 0x00000020
+#define GRC_LCLCTRL_GPIO_OE3 0x00000040
+#define GRC_LCLCTRL_GPIO_OUTPUT3 0x00000080
#define GRC_LCLCTRL_GPIO_INPUT0 0x00000100
#define GRC_LCLCTRL_GPIO_INPUT1 0x00000200
#define GRC_LCLCTRL_GPIO_INPUT2 0x00000400
@@ -1392,6 +1399,20 @@
#define FLASH_VENDOR_SAIFUN 0x01000003
#define FLASH_VENDOR_SST_SMALL 0x00000001
#define FLASH_VENDOR_SST_LARGE 0x02000001
+#define NVRAM_CFG1_5752VENDOR_MASK 0x03c00003
+#define FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ 0x00000000
+#define FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ 0x02000000
+#define FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED 0x02000003
+#define FLASH_5752VENDOR_ST_M45PE10 0x02400000
+#define FLASH_5752VENDOR_ST_M45PE20 0x02400002
+#define FLASH_5752VENDOR_ST_M45PE40 0x02400001
+#define NVRAM_CFG1_5752PAGE_SIZE_MASK 0x70000000
+#define FLASH_5752PAGE_SIZE_256 0x00000000
+#define FLASH_5752PAGE_SIZE_512 0x10000000
+#define FLASH_5752PAGE_SIZE_1K 0x20000000
+#define FLASH_5752PAGE_SIZE_2K 0x30000000
+#define FLASH_5752PAGE_SIZE_4K 0x40000000
+#define FLASH_5752PAGE_SIZE_264 0x50000000
#define NVRAM_CFG2 0x00007018
#define NVRAM_CFG3 0x0000701c
#define NVRAM_SWARB 0x00007020
@@ -2100,6 +2121,9 @@ struct tg3 {
#define TG3_FLG2_HW_TSO 0x00010000
#define TG3_FLG2_SERDES_PREEMPHASIS 0x00020000
#define TG3_FLG2_5705_PLUS 0x00040000
+#define TG3_FLG2_5750_PLUS 0x00080000
+#define TG3_FLG2_PROTECTED_NVRAM 0x00100000
+#define TG3_FLG2_USING_MSI 0x00200000
u32 split_mode_max_reqs;
#define SPLIT_MODE_5704_MAX_REQ 3
@@ -2145,6 +2169,7 @@ struct tg3 {
#define PHY_ID_BCM5704 0x60008190
#define PHY_ID_BCM5705 0x600081a0
#define PHY_ID_BCM5750 0x60008180
+#define PHY_ID_BCM5752 0x60008100
#define PHY_ID_BCM8002 0x60010140
#define PHY_ID_INVALID 0xffffffff
#define PHY_ID_REV_MASK 0x0000000f
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 35791934a60..66b94668ddd 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -26,7 +26,7 @@ config WAN
# There is no way to detect a comtrol sv11 - force it modular for now.
config HOSTESS_SV11
tristate "Comtrol Hostess SV-11 support"
- depends on WAN && ISA && m
+ depends on WAN && ISA && m && ISA_DMA_API
help
Driver for Comtrol Hostess SV-11 network card which
operates on low speed synchronous serial links at up to
@@ -38,7 +38,7 @@ config HOSTESS_SV11
# The COSA/SRP driver has not been tested as non-modular yet.
config COSA
tristate "COSA/SRP sync serial boards support"
- depends on WAN && ISA && m
+ depends on WAN && ISA && m && ISA_DMA_API
---help---
Driver for COSA and SRP synchronous serial boards.
@@ -127,7 +127,7 @@ config LANMEDIA
# There is no way to detect a Sealevel board. Force it modular
config SEALEVEL_4021
tristate "Sealevel Systems 4021 support"
- depends on WAN && ISA && m
+ depends on WAN && ISA && m && ISA_DMA_API
help
This is a driver for the Sealevel Systems ACB 56 serial I/O adapter.
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index 5b48cd8568f..02d57c0b424 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -436,9 +436,7 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
}
if (err) {
- if (chan->local_addr)
- kfree(chan->local_addr);
-
+ kfree(chan->local_addr);
kfree(chan);
return err;
}
@@ -458,9 +456,7 @@ static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev)
struct cycx_x25_channel *chan = dev->priv;
if (chan->svc) {
- if (chan->local_addr)
- kfree(chan->local_addr);
-
+ kfree(chan->local_addr);
if (chan->state == WAN_CONNECTED)
del_timer(&chan->timer);
}
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index d67be2587d4..3e7753b1071 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -3427,7 +3427,7 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int first_time = 1;
ucchar cpc_rev_id;
- int err = 0, eeprom_outdated = 0;
+ int err, eeprom_outdated = 0;
ucshort device_id;
pc300_t *card;
@@ -3439,15 +3439,21 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
#endif
}
+ if ((err = pci_enable_device(pdev)) < 0)
+ return err;
+
card = (pc300_t *) kmalloc(sizeof(pc300_t), GFP_KERNEL);
if (card == NULL) {
printk("PC300 found at RAM 0x%08lx, "
"but could not allocate card structure.\n",
pci_resource_start(pdev, 3));
- return -ENOMEM;
+ err = -ENOMEM;
+ goto err_disable_dev;
}
memset(card, 0, sizeof(pc300_t));
+ err = -ENODEV;
+
/* read PCI configuration area */
device_id = ent->device;
card->hw.irq = pdev->irq;
@@ -3507,7 +3513,6 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
printk("PC300 found at RAM 0x%08x, "
"but could not allocate PLX mem region.\n",
card->hw.ramphys);
- err = -ENODEV;
goto err_release_io;
}
if (!request_mem_region(card->hw.ramphys, card->hw.alloc_ramsize,
@@ -3515,7 +3520,6 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
printk("PC300 found at RAM 0x%08x, "
"but could not allocate RAM mem region.\n",
card->hw.ramphys);
- err = -ENODEV;
goto err_release_plx;
}
if (!request_mem_region(card->hw.scaphys, card->hw.scasize,
@@ -3523,13 +3527,9 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
printk("PC300 found at RAM 0x%08x, "
"but could not allocate SCA mem region.\n",
card->hw.ramphys);
- err = -ENODEV;
goto err_release_ram;
}
- if ((err = pci_enable_device(pdev)) != 0)
- goto err_release_sca;
-
card->hw.plxbase = ioremap(card->hw.plxphys, card->hw.plxsize);
card->hw.rambase = ioremap(card->hw.ramphys, card->hw.alloc_ramsize);
card->hw.scabase = ioremap(card->hw.scaphys, card->hw.scasize);
@@ -3619,7 +3619,6 @@ err_io_unmap:
iounmap(card->hw.falcbase);
release_mem_region(card->hw.falcphys, card->hw.falcsize);
}
-err_release_sca:
release_mem_region(card->hw.scaphys, card->hw.scasize);
err_release_ram:
release_mem_region(card->hw.ramphys, card->hw.alloc_ramsize);
@@ -3628,7 +3627,9 @@ err_release_plx:
err_release_io:
release_region(card->hw.iophys, card->hw.iosize);
kfree(card);
- return -ENODEV;
+err_disable_dev:
+ pci_disable_device(pdev);
+ return err;
}
static void __devexit cpc_remove_one(struct pci_dev *pdev)
@@ -3662,6 +3663,7 @@ static void __devexit cpc_remove_one(struct pci_dev *pdev)
if (card->hw.irq)
free_irq(card->hw.irq, card);
kfree(card);
+ pci_disable_device(pdev);
}
}
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
index 29f84ad0873..8454bf6caaa 100644
--- a/drivers/net/wan/pc300_tty.c
+++ b/drivers/net/wan/pc300_tty.c
@@ -400,10 +400,8 @@ static void cpc_tty_close(struct tty_struct *tty, struct file *flip)
cpc_tty->buf_rx.last = NULL;
}
- if (cpc_tty->buf_tx) {
- kfree(cpc_tty->buf_tx);
- cpc_tty->buf_tx = NULL;
- }
+ kfree(cpc_tty->buf_tx);
+ cpc_tty->buf_tx = NULL;
CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name);
@@ -666,7 +664,7 @@ static void cpc_tty_rx_work(void * data)
unsigned long port;
int i, j;
st_cpc_tty_area *cpc_tty;
- volatile st_cpc_rx_buf * buf;
+ volatile st_cpc_rx_buf *buf;
char flags=0,flg_rx=1;
struct tty_ldisc *ld;
@@ -680,9 +678,9 @@ static void cpc_tty_rx_work(void * data)
cpc_tty = &cpc_tty_area[port];
if ((buf=cpc_tty->buf_rx.first) != 0) {
- if(cpc_tty->tty) {
+ if (cpc_tty->tty) {
ld = tty_ldisc_ref(cpc_tty->tty);
- if(ld) {
+ if (ld) {
if (ld->receive_buf) {
CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name);
ld->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size);
@@ -691,7 +689,7 @@ static void cpc_tty_rx_work(void * data)
}
}
cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next;
- kfree((unsigned char *)buf);
+ kfree(buf);
buf = cpc_tty->buf_rx.first;
flg_rx = 1;
}
@@ -733,7 +731,7 @@ static void cpc_tty_rx_disc_frame(pc300ch_t *pc300chan)
void cpc_tty_receive(pc300dev_t *pc300dev)
{
- st_cpc_tty_area *cpc_tty;
+ st_cpc_tty_area *cpc_tty;
pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan;
pc300_t *card = (pc300_t *)pc300chan->card;
int ch = pc300chan->channel;
@@ -742,7 +740,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
int rx_len, rx_aux;
volatile unsigned char status;
unsigned short first_bd = pc300chan->rx_first_bd;
- st_cpc_rx_buf *new=NULL;
+ st_cpc_rx_buf *new = NULL;
unsigned char dsr_rx;
if (pc300dev->cpc_tty == NULL) {
@@ -762,7 +760,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
if (status & DST_EOM) {
break;
}
- ptdescr=(pcsca_bd_t __iomem *)(card->hw.rambase+cpc_readl(&ptdescr->next));
+ ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase+cpc_readl(&ptdescr->next));
}
if (!rx_len) {
@@ -771,10 +769,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch),
RX_BD_ADDR(ch, pc300chan->rx_last_bd));
}
- if (new) {
- kfree(new);
- new = NULL;
- }
+ kfree(new);
return;
}
@@ -787,7 +782,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
continue;
}
- new = (st_cpc_rx_buf *) kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC);
+ new = (st_cpc_rx_buf *)kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC);
if (new == 0) {
cpc_tty_rx_disc_frame(pc300chan);
continue;
diff --git a/drivers/net/wan/sdla_chdlc.c b/drivers/net/wan/sdla_chdlc.c
index afbe0024e3e..496d29237e9 100644
--- a/drivers/net/wan/sdla_chdlc.c
+++ b/drivers/net/wan/sdla_chdlc.c
@@ -3664,15 +3664,10 @@ static void wanpipe_tty_close(struct tty_struct *tty, struct file * filp)
chdlc_disable_comm_shutdown(card);
unlock_adapter_irq(&card->wandev.lock,&smp_flags);
- if (card->tty_buf){
- kfree(card->tty_buf);
- card->tty_buf=NULL;
- }
-
- if (card->tty_rx){
- kfree(card->tty_rx);
- card->tty_rx=NULL;
- }
+ kfree(card->tty_buf);
+ card->tty_buf = NULL;
+ kfree(card->tty_rx);
+ card->tty_rx = NULL;
}
return;
}
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 8c5cfcb5582..1c540d82555 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -107,13 +107,9 @@ static struct x25_asy *x25_asy_alloc(void)
static void x25_asy_free(struct x25_asy *sl)
{
/* Free all X.25 frame buffers. */
- if (sl->rbuff) {
- kfree(sl->rbuff);
- }
+ kfree(sl->rbuff);
sl->rbuff = NULL;
- if (sl->xbuff) {
- kfree(sl->xbuff);
- }
+ kfree(sl->xbuff);
sl->xbuff = NULL;
if (!test_and_clear_bit(SLF_INUSE, &sl->flags)) {
@@ -134,10 +130,8 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
{
printk("%s: unable to grow X.25 buffers, MTU change cancelled.\n",
dev->name);
- if (xbuff != NULL)
- kfree(xbuff);
- if (rbuff != NULL)
- kfree(rbuff);
+ kfree(xbuff);
+ kfree(rbuff);
return -ENOMEM;
}
@@ -169,10 +163,8 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
spin_unlock_bh(&sl->lock);
- if (xbuff != NULL)
- kfree(xbuff);
- if (rbuff != NULL)
- kfree(rbuff);
+ kfree(xbuff);
+ kfree(rbuff);
return 0;
}
diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c
index 9abedeaa567..a72006c08f2 100644
--- a/drivers/oprofile/oprofile_files.c
+++ b/drivers/oprofile/oprofile_files.c
@@ -18,13 +18,13 @@ unsigned long fs_buffer_size = 131072;
unsigned long fs_cpu_buffer_size = 8192;
unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
-static ssize_t depth_read(struct file * file, char * buf, size_t count, loff_t * offset)
+static ssize_t depth_read(struct file * file, char __user * buf, size_t count, loff_t * offset)
{
return oprofilefs_ulong_to_user(backtrace_depth, buf, count, offset);
}
-static ssize_t depth_write(struct file * file, char const * buf, size_t count, loff_t * offset)
+static ssize_t depth_write(struct file * file, char const __user * buf, size_t count, loff_t * offset)
{
unsigned long val;
int retval;
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
index 731010e0e6f..16a2e6ae37f 100644
--- a/drivers/parport/Kconfig
+++ b/drivers/parport/Kconfig
@@ -34,7 +34,7 @@ config PARPORT
config PARPORT_PC
tristate "PC-style hardware"
- depends on PARPORT && (!SPARC64 || PCI) && (!SPARC32 || BROKEN)
+ depends on PARPORT && (!SPARC64 || PCI) && !SPARC32
---help---
You should say Y here if you have a PC-style parallel port. All
IBM PC compatible computers and some Alphas have PC-style
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index c5774e7855d..e7f3bcb7900 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -67,6 +67,10 @@
#define PARPORT_PC_MAX_PORTS PARPORT_MAX
+#ifdef CONFIG_ISA_DMA_API
+#define HAS_DMA
+#endif
+
/* ECR modes */
#define ECR_SPP 00
#define ECR_PS2 01
@@ -610,6 +614,7 @@ dump_parport_state ("leave fifo_write_block_pio", port);
return length - left;
}
+#ifdef HAS_DMA
static size_t parport_pc_fifo_write_block_dma (struct parport *port,
const void *buf, size_t length)
{
@@ -732,6 +737,17 @@ dump_parport_state ("enter fifo_write_block_dma", port);
dump_parport_state ("leave fifo_write_block_dma", port);
return length - left;
}
+#endif
+
+static inline size_t parport_pc_fifo_write_block(struct parport *port,
+ const void *buf, size_t length)
+{
+#ifdef HAS_DMA
+ if (port->dma != PARPORT_DMA_NONE)
+ return parport_pc_fifo_write_block_dma (port, buf, length);
+#endif
+ return parport_pc_fifo_write_block_pio (port, buf, length);
+}
/* Parallel Port FIFO mode (ECP chipsets) */
static size_t parport_pc_compat_write_block_pio (struct parport *port,
@@ -758,10 +774,7 @@ static size_t parport_pc_compat_write_block_pio (struct parport *port,
port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;
/* Write the data to the FIFO. */
- if (port->dma != PARPORT_DMA_NONE)
- written = parport_pc_fifo_write_block_dma (port, buf, length);
- else
- written = parport_pc_fifo_write_block_pio (port, buf, length);
+ written = parport_pc_fifo_write_block(port, buf, length);
/* Finish up. */
/* For some hardware we don't want to touch the mode until
@@ -856,10 +869,7 @@ static size_t parport_pc_ecp_write_block_pio (struct parport *port,
port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;
/* Write the data to the FIFO. */
- if (port->dma != PARPORT_DMA_NONE)
- written = parport_pc_fifo_write_block_dma (port, buf, length);
- else
- written = parport_pc_fifo_write_block_pio (port, buf, length);
+ written = parport_pc_fifo_write_block(port, buf, length);
/* Finish up. */
/* For some hardware we don't want to touch the mode until
@@ -2285,6 +2295,7 @@ struct parport *parport_pc_probe_port (unsigned long int base,
}
#ifdef CONFIG_PARPORT_PC_FIFO
+#ifdef HAS_DMA
if (p->dma != PARPORT_DMA_NONE) {
if (request_dma (p->dma, p->name)) {
printk (KERN_WARNING "%s: dma %d in use, "
@@ -2306,7 +2317,8 @@ struct parport *parport_pc_probe_port (unsigned long int base,
}
}
}
-#endif /* CONFIG_PARPORT_PC_FIFO */
+#endif
+#endif
}
/* Done probing. Now put the port into a sensible start-up state. */
@@ -2367,11 +2379,13 @@ void parport_pc_unregister_port (struct parport *p)
if (p->modes & PARPORT_MODE_ECP)
release_region(p->base_hi, 3);
#ifdef CONFIG_PARPORT_PC_FIFO
+#ifdef HAS_DMA
if (priv->dma_buf)
pci_free_consistent(priv->dev, PAGE_SIZE,
priv->dma_buf,
priv->dma_handle);
-#endif /* CONFIG_PARPORT_PC_FIFO */
+#endif
+#endif
kfree (p->private_data);
parport_put_port(p);
kfree (ops); /* hope no-one cached it */
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
index d471b3ea5d1..021d0f76bc4 100644
--- a/drivers/pci/hotplug.c
+++ b/drivers/pci/hotplug.c
@@ -120,6 +120,10 @@ static int pci_visit_bridge (struct pci_visit * fn,
/**
* pci_visit_dev - scans the pci buses.
+ * @fn: callback functions that are called while visiting
+ * @wrapped_dev: the device to scan
+ * @wrapped_parent: the bus where @wrapped_dev is connected to
+ *
* Every bus and every function is presented to a custom
* function that can act upon it.
*/
diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h
index 5bc039da647..c22e0284d7b 100644
--- a/drivers/pci/hotplug/ibmphp.h
+++ b/drivers/pci/hotplug/ibmphp.h
@@ -196,7 +196,7 @@ struct ebda_hpc_bus {
/********************************************************************
-* THREE TYPE OF HOT PLUG CONTROLER *
+* THREE TYPE OF HOT PLUG CONTROLLER *
********************************************************************/
struct isa_ctlr_access {
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c
index 6894b548c8c..1a3eb8d3d4c 100644
--- a/drivers/pci/hotplug/ibmphp_hpc.c
+++ b/drivers/pci/hotplug/ibmphp_hpc.c
@@ -64,7 +64,7 @@ static int to_debug = FALSE;
#define WPG_I2C_OR 0x2000 // I2C OR operation
//----------------------------------------------------------------------------
-// Command set for I2C Master Operation Setup Regisetr
+// Command set for I2C Master Operation Setup Register
//----------------------------------------------------------------------------
#define WPG_READATADDR_MASK 0x00010000 // read,bytes,I2C shifted,index
#define WPG_WRITEATADDR_MASK 0x40010000 // write,bytes,I2C shifted,index
@@ -835,7 +835,7 @@ static void poll_hpc (void)
if (ibmphp_shutdown)
break;
- /* try to get the lock to do some kind of harware access */
+ /* try to get the lock to do some kind of hardware access */
down (&semOperations);
switch (poll_state) {
@@ -906,7 +906,7 @@ static void poll_hpc (void)
poll_state = POLL_LATCH_REGISTER;
break;
}
- /* give up the harware semaphore */
+ /* give up the hardware semaphore */
up (&semOperations);
/* sleep for a short time just for good measure */
msleep(100);
diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c
index 2335fac65fb..8122fe734aa 100644
--- a/drivers/pci/hotplug/ibmphp_pci.c
+++ b/drivers/pci/hotplug/ibmphp_pci.c
@@ -1308,10 +1308,10 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
/* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
} else {
/* This is Memory */
- start_address &= PCI_BASE_ADDRESS_MEM_MASK;
if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
/* pfmem */
debug ("start address of pfmem is %x\n", start_address);
+ start_address &= PCI_BASE_ADDRESS_MEM_MASK;
if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
err ("cannot find corresponding PFMEM resource to remove\n");
@@ -1325,6 +1325,8 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
} else {
/* regular memory */
debug ("start address of mem is %x\n", start_address);
+ start_address &= PCI_BASE_ADDRESS_MEM_MASK;
+
if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
err ("cannot find corresponding MEM resource to remove\n");
return -EIO;
@@ -1422,9 +1424,9 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
/* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
} else {
/* This is Memory */
- start_address &= PCI_BASE_ADDRESS_MEM_MASK;
if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
/* pfmem */
+ start_address &= PCI_BASE_ADDRESS_MEM_MASK;
if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
err ("cannot find corresponding PFMEM resource to remove\n");
return -EINVAL;
@@ -1436,6 +1438,7 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
}
} else {
/* regular memory */
+ start_address &= PCI_BASE_ADDRESS_MEM_MASK;
if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
err ("cannot find corresponding MEM resource to remove\n");
return -EINVAL;
diff --git a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h
index 57ace325168..88d44f7fef2 100644
--- a/drivers/pci/hotplug/pci_hotplug.h
+++ b/drivers/pci/hotplug/pci_hotplug.h
@@ -150,7 +150,7 @@ struct hotplug_slot_info {
* @name: the name of the slot being registered. This string must
* be unique amoung slots registered on this system.
* @ops: pointer to the &struct hotplug_slot_ops to be used for this slot
- * @info: pointer to the &struct hotplug_slot_info for the inital values for
+ * @info: pointer to the &struct hotplug_slot_info for the initial values for
* this slot.
* @release: called during pci_hp_deregister to free memory allocated in a
* hotplug_slot structure.
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 72baf749e65..ed1fd8d6178 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -90,6 +90,22 @@ static struct hotplug_slot_ops pciehp_hotplug_slot_ops = {
.get_cur_bus_speed = get_cur_bus_speed,
};
+/**
+ * release_slot - free up the memory used by a slot
+ * @hotplug_slot: slot to free
+ */
+static void release_slot(struct hotplug_slot *hotplug_slot)
+{
+ struct slot *slot = hotplug_slot->private;
+
+ dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+ kfree(slot->hotplug_slot->info);
+ kfree(slot->hotplug_slot->name);
+ kfree(slot->hotplug_slot);
+ kfree(slot);
+}
+
static int init_slots(struct controller *ctrl)
{
struct slot *new_slot;
@@ -139,7 +155,8 @@ static int init_slots(struct controller *ctrl)
/* register this slot with the hotplug pci core */
new_slot->hotplug_slot->private = new_slot;
- make_slot_name (new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
+ new_slot->hotplug_slot->release = &release_slot;
+ make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
new_slot->hotplug_slot->ops = &pciehp_hotplug_slot_ops;
new_slot->hpc_ops->get_power_status(new_slot, &(new_slot->hotplug_slot->info->power_status));
@@ -188,10 +205,6 @@ static int cleanup_slots (struct controller * ctrl)
while (old_slot) {
next_slot = old_slot->next;
pci_hp_deregister (old_slot->hotplug_slot);
- kfree(old_slot->hotplug_slot->info);
- kfree(old_slot->hotplug_slot->name);
- kfree(old_slot->hotplug_slot);
- kfree(old_slot);
old_slot = next_slot;
}
diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c
index 6605d6bda52..3194d51c6ec 100644
--- a/drivers/pci/hotplug/pcihp_skeleton.c
+++ b/drivers/pci/hotplug/pcihp_skeleton.c
@@ -297,7 +297,7 @@ static int __init init_slots(void)
hotplug_slot->ops = &skel_hotplug_slot_ops;
/*
- * Initilize the slot info structure with some known
+ * Initialize the slot info structure with some known
* good values.
*/
info->power_status = get_power_status(slot);
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 22ecd3b058b..30206ac43c4 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -522,7 +522,7 @@ void pci_scan_msi_device(struct pci_dev *dev)
* msi_capability_init - configure device's MSI capability structure
* @dev: pointer to the pci_dev data structure of MSI device function
*
- * Setup the MSI capability structure of device funtion with a single
+ * Setup the MSI capability structure of device function with a single
* MSI vector, regardless of device function is capable of handling
* multiple messages. A return of zero indicates the successful setup
* of an entry zero with the new MSI vector or non-zero for otherwise.
@@ -599,7 +599,7 @@ static int msi_capability_init(struct pci_dev *dev)
* msix_capability_init - configure device's MSI-X capability
* @dev: pointer to the pci_dev data structure of MSI-X device function
*
- * Setup the MSI-X capability structure of device funtion with a
+ * Setup the MSI-X capability structure of device function with a
* single MSI-X vector. A return of zero indicates the successful setup of
* requested MSI-X entries with allocated vectors or non-zero for otherwise.
**/
@@ -1074,7 +1074,7 @@ void pci_disable_msix(struct pci_dev* dev)
* msi_remove_pci_irq_vectors - reclaim MSI(X) vectors to unused state
* @dev: pointer to the pci_dev data structure of MSI(X) device function
*
- * Being called during hotplug remove, from which the device funciton
+ * Being called during hotplug remove, from which the device function
* is hot-removed. All previous assigned MSI/MSI-X vectors, if
* allocated for this device function, are reclaimed to unused state,
* which may be used later on.
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 968eb32f292..bc01d34e263 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -19,7 +19,7 @@
static u32 ctrlset_buf[3] = {0, 0, 0};
static u32 global_ctrlsets = 0;
-u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
+static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
static acpi_status
acpi_query_osc (
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 37b7961efc4..fe98553c978 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -318,6 +318,14 @@ static int pci_device_resume(struct device * dev)
return 0;
}
+static void pci_device_shutdown(struct device *dev)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct pci_driver *drv = pci_dev->driver;
+
+ if (drv && drv->shutdown)
+ drv->shutdown(pci_dev);
+}
#define kobj_to_pci_driver(obj) container_of(obj, struct device_driver, kobj)
#define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr)
@@ -373,7 +381,7 @@ pci_populate_driver_dir(struct pci_driver *drv)
*
* Adds the driver structure to the list of registered drivers.
* Returns a negative value on error, otherwise 0.
- * If no error occured, the driver remains registered even if
+ * If no error occurred, the driver remains registered even if
* no device was claimed during registration.
*/
int pci_register_driver(struct pci_driver *drv)
@@ -385,6 +393,7 @@ int pci_register_driver(struct pci_driver *drv)
drv->driver.bus = &pci_bus_type;
drv->driver.probe = pci_device_probe;
drv->driver.remove = pci_device_remove;
+ drv->driver.shutdown = pci_device_shutdown,
drv->driver.owner = drv->owner;
drv->driver.kobj.ktype = &pci_driver_kobj_type;
pci_init_dynids(&drv->dynids);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index d57ae71d32b..8568b207f18 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -91,6 +91,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
unsigned int size = 64;
loff_t init_off = off;
+ u8 *data = (u8*) buf;
/* Several chips lock up trying to read undefined config space */
if (capable(CAP_SYS_ADMIN)) {
@@ -108,30 +109,47 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
size = count;
}
- while (off & 3) {
- unsigned char val;
+ if ((off & 1) && size) {
+ u8 val;
pci_read_config_byte(dev, off, &val);
- buf[off - init_off] = val;
+ data[off - init_off] = val;
off++;
- if (--size == 0)
- break;
+ size--;
+ }
+
+ if ((off & 3) && size > 2) {
+ u16 val;
+ pci_read_config_word(dev, off, &val);
+ data[off - init_off] = val & 0xff;
+ data[off - init_off + 1] = (val >> 8) & 0xff;
+ off += 2;
+ size -= 2;
}
while (size > 3) {
- unsigned int val;
+ u32 val;
pci_read_config_dword(dev, off, &val);
- buf[off - init_off] = val & 0xff;
- buf[off - init_off + 1] = (val >> 8) & 0xff;
- buf[off - init_off + 2] = (val >> 16) & 0xff;
- buf[off - init_off + 3] = (val >> 24) & 0xff;
+ data[off - init_off] = val & 0xff;
+ data[off - init_off + 1] = (val >> 8) & 0xff;
+ data[off - init_off + 2] = (val >> 16) & 0xff;
+ data[off - init_off + 3] = (val >> 24) & 0xff;
off += 4;
size -= 4;
}
- while (size > 0) {
- unsigned char val;
+ if (size >= 2) {
+ u16 val;
+ pci_read_config_word(dev, off, &val);
+ data[off - init_off] = val & 0xff;
+ data[off - init_off + 1] = (val >> 8) & 0xff;
+ off += 2;
+ size -= 2;
+ }
+
+ if (size > 0) {
+ u8 val;
pci_read_config_byte(dev, off, &val);
- buf[off - init_off] = val;
+ data[off - init_off] = val;
off++;
--size;
}
@@ -145,6 +163,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
unsigned int size = count;
loff_t init_off = off;
+ u8 *data = (u8*) buf;
if (off > dev->cfg_size)
return 0;
@@ -152,26 +171,41 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
size = dev->cfg_size - off;
count = size;
}
-
- while (off & 3) {
- pci_write_config_byte(dev, off, buf[off - init_off]);
+
+ if ((off & 1) && size) {
+ pci_write_config_byte(dev, off, data[off - init_off]);
off++;
- if (--size == 0)
- break;
+ size--;
}
+
+ if ((off & 3) && size > 2) {
+ u16 val = data[off - init_off];
+ val |= (u16) data[off - init_off + 1] << 8;
+ pci_write_config_word(dev, off, val);
+ off += 2;
+ size -= 2;
+ }
while (size > 3) {
- unsigned int val = buf[off - init_off];
- val |= (unsigned int) buf[off - init_off + 1] << 8;
- val |= (unsigned int) buf[off - init_off + 2] << 16;
- val |= (unsigned int) buf[off - init_off + 3] << 24;
+ u32 val = data[off - init_off];
+ val |= (u32) data[off - init_off + 1] << 8;
+ val |= (u32) data[off - init_off + 2] << 16;
+ val |= (u32) data[off - init_off + 3] << 24;
pci_write_config_dword(dev, off, val);
off += 4;
size -= 4;
}
+
+ if (size >= 2) {
+ u16 val = data[off - init_off];
+ val |= (u16) data[off - init_off + 1] << 8;
+ pci_write_config_word(dev, off, val);
+ off += 2;
+ size -= 2;
+ }
- while (size > 0) {
- pci_write_config_byte(dev, off, buf[off - init_off]);
+ if (size) {
+ pci_write_config_byte(dev, off, data[off - init_off]);
off++;
--size;
}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index bfbff833526..f04b9ffe415 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/dma.h> /* isa_dma_bridge_buggy */
+#include "pci.h"
/**
@@ -398,10 +399,10 @@ pci_enable_device(struct pci_dev *dev)
{
int err;
- dev->is_enabled = 1;
if ((err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1)))
return err;
pci_fixup_device(pci_fixup_enable, dev);
+ dev->is_enabled = 1;
return 0;
}
@@ -427,16 +428,15 @@ pci_disable_device(struct pci_dev *dev)
{
u16 pci_command;
- dev->is_enabled = 0;
- dev->is_busmaster = 0;
-
pci_read_config_word(dev, PCI_COMMAND, &pci_command);
if (pci_command & PCI_COMMAND_MASTER) {
pci_command &= ~PCI_COMMAND_MASTER;
pci_write_config_word(dev, PCI_COMMAND, pci_command);
}
+ dev->is_busmaster = 0;
pcibios_disable_device(dev);
+ dev->is_enabled = 0;
}
/**
@@ -749,17 +749,6 @@ pci_set_dma_mask(struct pci_dev *dev, u64 mask)
}
int
-pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
- if (!pci_dac_dma_supported(dev, mask))
- return -EIO;
-
- dev->dma_mask = mask;
-
- return 0;
-}
-
-int
pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
{
if (!pci_dma_supported(dev, mask))
@@ -821,7 +810,6 @@ EXPORT_SYMBOL(pci_set_master);
EXPORT_SYMBOL(pci_set_mwi);
EXPORT_SYMBOL(pci_clear_mwi);
EXPORT_SYMBOL(pci_set_dma_mask);
-EXPORT_SYMBOL(pci_dac_set_dma_mask);
EXPORT_SYMBOL(pci_set_consistent_dma_mask);
EXPORT_SYMBOL(pci_assign_resource);
EXPORT_SYMBOL(pci_find_parent_resource);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6f0edadd132..b7ae87823c6 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -9,6 +9,7 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/cpumask.h>
+#include "pci.h"
#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */
#define CARDBUS_RESERVE_BUSNR 3
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 84cc4f620d8..e68bbfb1e7c 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -15,6 +15,7 @@
#include <asm/uaccess.h>
#include <asm/byteorder.h>
+#include "pci.h"
static int proc_initialized; /* = 0 */
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 15a39805168..026aa04669a 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -18,6 +18,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include "pci.h"
/* Deal with broken BIOS'es that neglect to enable passive release,
which can cause problems in combination with the 82441FX/PPro MTRRs */
@@ -328,6 +329,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, quirk_ich4_lpc_acpi );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, quirk_ich4_lpc_acpi );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, quirk_ich4_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, quirk_ich4_lpc_acpi );
/*
* VIA ACPI: One IO region pointed to by longword at
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 3e64ff64b38..838575e3fac 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -14,7 +14,7 @@
/**
* pci_enable_rom - enable ROM decoding for a PCI device
- * @dev: PCI device to enable
+ * @pdev: PCI device to enable
*
* Enable ROM decoding on @dev. This involves simply turning on the last
* bit of the PCI ROM BAR. Note that some cards may share address decoders
@@ -32,7 +32,7 @@ static void pci_enable_rom(struct pci_dev *pdev)
/**
* pci_disable_rom - disable ROM decoding for a PCI device
- * @dev: PCI device to disable
+ * @pdev: PCI device to disable
*
* Disable ROM decoding on a PCI device by turning off the last bit in the
* ROM BAR.
@@ -47,7 +47,7 @@ static void pci_disable_rom(struct pci_dev *pdev)
/**
* pci_map_rom - map a PCI ROM to kernel space
- * @dev: pointer to pci device struct
+ * @pdev: pointer to pci device struct
* @size: pointer to receive size of pci window over ROM
* @return: kernel virtual pointer to image of ROM
*
@@ -132,7 +132,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
/**
* pci_map_rom_copy - map a PCI ROM to kernel space, create a copy
- * @dev: pointer to pci device struct
+ * @pdev: pointer to pci device struct
* @size: pointer to receive size of pci window over ROM
* @return: kernel virtual pointer to image of ROM
*
@@ -166,7 +166,7 @@ void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size)
/**
* pci_unmap_rom - unmap the ROM from kernel space
- * @dev: pointer to pci device struct
+ * @pdev: pointer to pci device struct
* @rom: virtual address of the previous mapping
*
* Remove a mapping of a previously mapped ROM
@@ -187,7 +187,7 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
/**
* pci_remove_rom - disable the ROM and remove its sysfs attribute
- * @dev: pointer to pci device struct
+ * @pdev: pointer to pci device struct
*
* Remove the rom file in sysfs and disable ROM decoding.
*/
@@ -206,7 +206,7 @@ void pci_remove_rom(struct pci_dev *pdev)
/**
* pci_cleanup_rom - internal routine for freeing the ROM copy created
* by pci_map_rom_copy called from remove.c
- * @dev: pointer to pci device struct
+ * @pdev: pointer to pci device struct
*
* Free the copied ROM if we allocated one.
*/
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index 3f4364341d8..20642f0e7bf 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -744,7 +744,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
for (i = 0; i < MAX_SOCKETS; i++) {
socket[i].io_base = pci_resource_start(dev, 0);
- socket[i].socket.features |= SS_CAP_PCCARD;
+ socket[i].socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD;
socket[i].socket.map_size = 0x1000;
socket[i].socket.irq_mask = mask;
socket[i].socket.pci_irq = dev->irq;
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index 52c073a9d7e..a8a1d104524 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -442,6 +442,25 @@ out:
}
+/* changes the irq of func1 to match that of func0 */
+static int ti12xx_align_irqs(struct yenta_socket *socket, int *old_irq)
+{
+ struct pci_dev *func0;
+
+ /* find func0 device */
+ func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07);
+ if (!func0)
+ return 0;
+
+ if (old_irq)
+ *old_irq = socket->cb_irq;
+ socket->cb_irq = socket->dev->irq = func0->irq;
+
+ pci_dev_put(func0);
+
+ return 1;
+}
+
/*
* ties INTA and INTB together. also changes the devices irq to that of
* the function 0 device. call from func1 only.
@@ -449,26 +468,22 @@ out:
*/
static int ti12xx_tie_interrupts(struct yenta_socket *socket, int *old_irq)
{
- struct pci_dev *func0;
u32 sysctl;
+ int ret;
sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
if (sysctl & TI122X_SCR_INTRTIE)
return 0;
- /* find func0 device */
- func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07);
- if (!func0)
+ /* align */
+ ret = ti12xx_align_irqs(socket, old_irq);
+ if (!ret)
return 0;
- /* change the interrupt to match func0, tie 'em up */
- *old_irq = socket->cb_irq;
- socket->cb_irq = socket->dev->irq = func0->irq;
+ /* tie */
sysctl |= TI122X_SCR_INTRTIE;
config_writel(socket, TI113X_SYSTEM_CONTROL, sysctl);
- pci_dev_put(func0);
-
return 1;
}
@@ -489,7 +504,7 @@ static void ti12xx_untie_interrupts(struct yenta_socket *socket, int old_irq)
*/
static void ti12xx_irqroute_func1(struct yenta_socket *socket)
{
- u32 mfunc, mfunc_old, devctl;
+ u32 mfunc, mfunc_old, devctl, sysctl;
int pci_irq_status;
mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
@@ -497,6 +512,11 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",
pci_name(socket->dev), mfunc, devctl);
+ /* if IRQs are configured as tied, align irq of func1 with func0 */
+ sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
+ if (sysctl & TI122X_SCR_INTRTIE)
+ ti12xx_align_irqs(socket, NULL);
+
/* make sure PCI interrupts are enabled before probing */
ti_init(socket);
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 639e0425348..65ecef73853 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -253,7 +253,7 @@ void pnp_init_resource_table(struct pnp_resource_table *table)
/**
* pnp_clean_resources - clears resources that were not manually set
- * @res - the resources to clean
+ * @res: the resources to clean
*
*/
static void pnp_clean_resource_table(struct pnp_resource_table * res)
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index c0ddb1eb8c4..dd61e09029b 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -94,8 +94,8 @@ static void
pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma)
{
int i = 0;
- while (!(res->dma_resource[i].flags & IORESOURCE_UNSET) &&
- i < PNP_MAX_DMA)
+ while (i < PNP_MAX_DMA &&
+ !(res->dma_resource[i].flags & IORESOURCE_UNSET))
i++;
if (i < PNP_MAX_DMA) {
res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index 618ac15a9e9..79bce7b7574 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -72,7 +72,9 @@ static void
pnpbios_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma)
{
int i = 0;
- while (!(res->dma_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_DMA) i++;
+ while (i < PNP_MAX_DMA &&
+ !(res->dma_resource[i].flags & IORESOURCE_UNSET))
+ i++;
if (i < PNP_MAX_DMA) {
res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag
if (dma == -1) {
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index b755bac6ccb..02cfe244e06 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -7,7 +7,7 @@
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
*
- * $Revision: 1.158 $
+ * $Revision: 1.161 $
*/
#include <linux/config.h>
@@ -1131,13 +1131,17 @@ __dasd_process_blk_queue(struct dasd_device * device)
request_queue_t *queue;
struct request *req;
struct dasd_ccw_req *cqr;
- int nr_queued;
+ int nr_queued, feature_ro;
queue = device->request_queue;
/* No queue ? Then there is nothing to do. */
if (queue == NULL)
return;
+ feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY);
+ if (feature_ro < 0) /* no devmap */
+ return;
+
/*
* We requeue request from the block device queue to the ccw
* queue only in two states. In state DASD_STATE_READY the
@@ -1157,8 +1161,8 @@ __dasd_process_blk_queue(struct dasd_device * device)
elv_next_request(queue) &&
nr_queued < DASD_CHANQ_MAX_SIZE) {
req = elv_next_request(queue);
- if (test_bit(DASD_FLAG_RO, &device->flags) &&
- rq_data_dir(req) == WRITE) {
+
+ if (feature_ro && rq_data_dir(req) == WRITE) {
DBF_DEV_EVENT(DBF_ERR, device,
"Rejecting write request %p",
req);
@@ -1631,6 +1635,7 @@ dasd_setup_queue(struct dasd_device * device)
blk_queue_max_hw_segments(device->request_queue, -1L);
blk_queue_max_segment_size(device->request_queue, -1L);
blk_queue_segment_boundary(device->request_queue, -1L);
+ blk_queue_ordered(device->request_queue, 1);
}
/*
@@ -1803,13 +1808,17 @@ dasd_generic_set_online (struct ccw_device *cdev,
{
struct dasd_device *device;
- int rc;
+ int feature_diag, rc;
+
+ feature_diag = dasd_get_feature(cdev, DASD_FEATURE_USEDIAG);
+ if (feature_diag < 0)
+ return feature_diag;
device = dasd_create_device(cdev);
if (IS_ERR(device))
return PTR_ERR(device);
- if (test_bit(DASD_FLAG_USE_DIAG, &device->flags)) {
+ if (feature_diag) {
if (!dasd_diag_discipline_pointer) {
printk (KERN_WARNING
"dasd_generic couldn't online device %s "
diff --git a/drivers/s390/block/dasd_cmb.c b/drivers/s390/block/dasd_cmb.c
index ed1ab474c0c..4f365bff275 100644
--- a/drivers/s390/block/dasd_cmb.c
+++ b/drivers/s390/block/dasd_cmb.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/s390/block/dasd_cmb.c ($Revision: 1.6 $)
+ * linux/drivers/s390/block/dasd_cmb.c ($Revision: 1.9 $)
*
* Linux on zSeries Channel Measurement Facility support
* (dasd device driver interface)
@@ -23,7 +23,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
-#include <linux/ioctl32.h>
#include <linux/module.h>
#include <asm/ccwdev.h>
#include <asm/cmb.h>
@@ -84,27 +83,13 @@ dasd_ioctl_readall_cmb(struct block_device *bdev, int no, long args)
static inline int
ioctl_reg(unsigned int no, dasd_ioctl_fn_t handler)
{
- int ret;
- ret = dasd_ioctl_no_register(THIS_MODULE, no, handler);
-#ifdef CONFIG_COMPAT
- if (ret)
- return ret;
-
- ret = register_ioctl32_conversion(no, NULL);
- if (ret)
- dasd_ioctl_no_unregister(THIS_MODULE, no, handler);
-#endif
- return ret;
+ return dasd_ioctl_no_register(THIS_MODULE, no, handler);
}
static inline void
ioctl_unreg(unsigned int no, dasd_ioctl_fn_t handler)
{
dasd_ioctl_no_unregister(THIS_MODULE, no, handler);
-#ifdef CONFIG_COMPAT
- unregister_ioctl32_conversion(no);
-#endif
-
}
static void
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index ad1841a96c8..1aedc48e5f8 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -11,7 +11,7 @@
* functions may not be called from interrupt context. In particular
* dasd_get_device is a no-no from interrupt context.
*
- * $Revision: 1.37 $
+ * $Revision: 1.40 $
*/
#include <linux/config.h>
@@ -513,14 +513,6 @@ dasd_create_device(struct ccw_device *cdev)
if (!devmap->device) {
devmap->device = device;
device->devindex = devmap->devindex;
- if (devmap->features & DASD_FEATURE_READONLY)
- set_bit(DASD_FLAG_RO, &device->flags);
- else
- clear_bit(DASD_FLAG_RO, &device->flags);
- if (devmap->features & DASD_FEATURE_USEDIAG)
- set_bit(DASD_FLAG_USE_DIAG, &device->flags);
- else
- clear_bit(DASD_FLAG_USE_DIAG, &device->flags);
get_device(&cdev->dev);
device->cdev = cdev;
rc = 0;
@@ -651,14 +643,8 @@ dasd_ro_store(struct device *dev, const char *buf, size_t count)
devmap->features |= DASD_FEATURE_READONLY;
else
devmap->features &= ~DASD_FEATURE_READONLY;
- if (devmap->device) {
- if (devmap->device->gdp)
- set_disk_ro(devmap->device->gdp, ro_flag);
- if (ro_flag)
- set_bit(DASD_FLAG_RO, &devmap->device->flags);
- else
- clear_bit(DASD_FLAG_RO, &devmap->device->flags);
- }
+ if (devmap->device && devmap->device->gdp)
+ set_disk_ro(devmap->device->gdp, ro_flag);
spin_unlock(&dasd_devmap_lock);
return count;
}
@@ -739,6 +725,45 @@ static struct attribute_group dasd_attr_group = {
.attrs = dasd_attrs,
};
+/*
+ * Return value of the specified feature.
+ */
+int
+dasd_get_feature(struct ccw_device *cdev, int feature)
+{
+ struct dasd_devmap *devmap;
+
+ devmap = dasd_find_busid(cdev->dev.bus_id);
+ if (IS_ERR(devmap))
+ return (int) PTR_ERR(devmap);
+
+ return ((devmap->features & feature) != 0);
+}
+
+/*
+ * Set / reset given feature.
+ * Flag indicates wether to set (!=0) or the reset (=0) the feature.
+ */
+int
+dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
+{
+ struct dasd_devmap *devmap;
+
+ devmap = dasd_find_busid(cdev->dev.bus_id);
+ if (IS_ERR(devmap))
+ return (int) PTR_ERR(devmap);
+
+ spin_lock(&dasd_devmap_lock);
+ if (flag)
+ devmap->features |= feature;
+ else
+ devmap->features &= ~feature;
+
+ spin_unlock(&dasd_devmap_lock);
+ return 0;
+}
+
+
int
dasd_add_sysfs_files(struct ccw_device *cdev)
{
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 838aedf78a5..811060e10c0 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -7,7 +7,7 @@
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
*
- * $Revision: 1.69 $
+ * $Revision: 1.71 $
*/
#include <linux/config.h>
@@ -1101,7 +1101,8 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req)
if (dasd_eckd_cdl_special(blk_per_trk, recid)){
rcmd |= 0x8;
count = dasd_eckd_cdl_reclen(recid);
- if (count < blksize)
+ if (count < blksize &&
+ rq_data_dir(req) == READ)
memset(dst + count, 0xe5,
blksize - count);
}
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index 1d52db406b2..96c49349701 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -9,7 +9,7 @@
*
* gendisk related functions for the dasd driver.
*
- * $Revision: 1.48 $
+ * $Revision: 1.50 $
*/
#include <linux/config.h>
@@ -31,12 +31,16 @@ int
dasd_gendisk_alloc(struct dasd_device *device)
{
struct gendisk *gdp;
- int len;
+ int len, feature_ro;
/* Make sure the minor for this device exists. */
if (device->devindex >= DASD_PER_MAJOR)
return -EBUSY;
+ feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY);
+ if (feature_ro < 0)
+ return feature_ro;
+
gdp = alloc_disk(1 << DASD_PARTN_BITS);
if (!gdp)
return -ENOMEM;
@@ -71,7 +75,7 @@ dasd_gendisk_alloc(struct dasd_device *device)
sprintf(gdp->devfs_name, "dasd/%s", device->cdev->dev.bus_id);
- if (test_bit(DASD_FLAG_RO, &device->flags))
+ if (feature_ro)
set_disk_ro(gdp, 1);
gdp->private_data = device;
gdp->queue = device->request_queue;
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 4586e0ecc52..a9f38b23598 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -6,7 +6,7 @@
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
*
- * $Revision: 1.63 $
+ * $Revision: 1.64 $
*/
#ifndef DASD_INT_H
@@ -329,8 +329,6 @@ struct dasd_device {
#define DASD_STOPPED_DC_EIO 16 /* disconnected, return -EIO */
/* per device flags */
-#define DASD_FLAG_RO 0 /* device is read-only */
-#define DASD_FLAG_USE_DIAG 1 /* use diag disciplnie */
#define DASD_FLAG_DSC_ERROR 2 /* return -EIO when disconnected */
#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */
@@ -501,6 +499,9 @@ void dasd_devmap_exit(void);
struct dasd_device *dasd_create_device(struct ccw_device *);
void dasd_delete_device(struct dasd_device *);
+int dasd_get_feature(struct ccw_device *, int);
+int dasd_set_feature(struct ccw_device *, int, int);
+
int dasd_add_sysfs_files(struct ccw_device *);
void dasd_remove_sysfs_files(struct ccw_device *);
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index f1892baa3b1..980c555aa53 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -7,6 +7,8 @@
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
*
+ * $Revision: 1.45 $
+ *
* i/o controls for the dasd driver.
*/
#include <linux/config.h>
@@ -294,6 +296,7 @@ dasd_ioctl_format(struct block_device *bdev, int no, long args)
{
struct dasd_device *device;
struct format_data_t fdata;
+ int feature_ro;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -304,7 +307,11 @@ dasd_ioctl_format(struct block_device *bdev, int no, long args)
if (device == NULL)
return -ENODEV;
- if (test_bit(DASD_FLAG_RO, &device->flags))
+
+ feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY);
+ if (feature_ro < 0)
+ return feature_ro;
+ if (feature_ro)
return -EROFS;
if (copy_from_user(&fdata, (void __user *) args,
sizeof (struct format_data_t)))
@@ -377,7 +384,7 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args)
struct dasd_device *device;
struct dasd_information2_t *dasd_info;
unsigned long flags;
- int rc;
+ int rc, feature_ro;
struct ccw_device *cdev;
device = bdev->bd_disk->private_data;
@@ -387,6 +394,10 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args)
if (!device->discipline->fill_info)
return -EINVAL;
+ feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY);
+ if (feature_ro < 0)
+ return feature_ro;
+
dasd_info = kmalloc(sizeof(struct dasd_information2_t), GFP_KERNEL);
if (dasd_info == NULL)
return -ENOMEM;
@@ -415,9 +426,8 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args)
if ((device->state < DASD_STATE_READY) ||
(dasd_check_blocksize(device->bp_block)))
dasd_info->format = DASD_FORMAT_NONE;
-
- dasd_info->features |= test_bit(DASD_FLAG_RO, &device->flags) ?
- DASD_FEATURE_READONLY : DASD_FEATURE_DEFAULT;
+
+ dasd_info->features |= feature_ro;
if (device->discipline)
memcpy(dasd_info->type, device->discipline->name, 4);
@@ -460,7 +470,7 @@ static int
dasd_ioctl_set_ro(struct block_device *bdev, int no, long args)
{
struct dasd_device *device;
- int intval;
+ int intval, rc;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -472,12 +482,11 @@ dasd_ioctl_set_ro(struct block_device *bdev, int no, long args)
device = bdev->bd_disk->private_data;
if (device == NULL)
return -ENODEV;
+
set_disk_ro(bdev->bd_disk, intval);
- if (intval)
- set_bit(DASD_FLAG_RO, &device->flags);
- else
- clear_bit(DASD_FLAG_RO, &device->flags);
- return 0;
+ rc = dasd_set_feature(device->cdev, DASD_FEATURE_READONLY, intval);
+
+ return rc;
}
/*
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 353d41118c6..d7f19745911 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -9,7 +9,7 @@
*
* /proc interface for the dasd driver.
*
- * $Revision: 1.30 $
+ * $Revision: 1.31 $
*/
#include <linux/config.h>
@@ -54,6 +54,7 @@ dasd_devices_show(struct seq_file *m, void *v)
{
struct dasd_device *device;
char *substr;
+ int feature;
device = dasd_device_from_devindex((unsigned long) v - 1);
if (IS_ERR(device))
@@ -77,7 +78,10 @@ dasd_devices_show(struct seq_file *m, void *v)
else
seq_printf(m, " is ????????");
/* Print devices features. */
- substr = test_bit(DASD_FLAG_RO, &device->flags) ? "(ro)" : " ";
+ feature = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY);
+ if (feature < 0)
+ return 0;
+ substr = feature ? "(ro)" : " ";
seq_printf(m, "%4s: ", substr);
/* Print device status information. */
switch ((device != NULL) ? device->state : -1) {
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c
index 3720e77b465..83e6a060668 100644
--- a/drivers/s390/cio/airq.c
+++ b/drivers/s390/cio/airq.c
@@ -45,7 +45,7 @@ s390_register_adapter_interrupt (adapter_int_handler_t handler)
else
ret = (cmpxchg(&adapter_handler, NULL, handler) ? -EBUSY : 0);
if (!ret)
- synchronize_kernel();
+ synchronize_sched(); /* Allow interrupts to complete. */
sprintf (dbf_txt, "ret:%d", ret);
CIO_TRACE_EVENT (4, dbf_txt);
@@ -65,7 +65,7 @@ s390_unregister_adapter_interrupt (adapter_int_handler_t handler)
ret = -EINVAL;
else {
adapter_handler = NULL;
- synchronize_kernel();
+ synchronize_sched(); /* Allow interrupts to complete. */
ret = 0;
}
sprintf (dbf_txt, "ret:%d", ret);
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 99ce5a56798..1d9b3f18d8d 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -1,7 +1,7 @@
/*
* drivers/s390/cio/cio.c
* S/390 common I/O routines -- low level i/o calls
- * $Revision: 1.131 $
+ * $Revision: 1.133 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
@@ -228,7 +228,7 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */
int
cio_start (struct subchannel *sch, struct ccw1 *cpa, __u8 lpm)
{
- return cio_start_key(sch, cpa, lpm, default_storage_key);
+ return cio_start_key(sch, cpa, lpm, PAGE_DEFAULT_KEY);
}
/*
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 11e260e0b9c..02d01a0de16 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -1,7 +1,7 @@
/*
* drivers/s390/cio/device_ops.c
*
- * $Revision: 1.55 $
+ * $Revision: 1.56 $
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
@@ -128,7 +128,7 @@ ccw_device_start(struct ccw_device *cdev, struct ccw1 *cpa,
unsigned long intparm, __u8 lpm, unsigned long flags)
{
return ccw_device_start_key(cdev, cpa, intparm, lpm,
- default_storage_key, flags);
+ PAGE_DEFAULT_KEY, flags);
}
int
@@ -137,7 +137,7 @@ ccw_device_start_timeout(struct ccw_device *cdev, struct ccw1 *cpa,
int expires)
{
return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm,
- default_storage_key, flags,
+ PAGE_DEFAULT_KEY, flags,
expires);
}
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 9ad14db2414..b6daadac4e8 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -1,7 +1,9 @@
#ifndef _CIO_QDIO_H
#define _CIO_QDIO_H
-#define VERSION_CIO_QDIO_H "$Revision: 1.26 $"
+#include <asm/page.h>
+
+#define VERSION_CIO_QDIO_H "$Revision: 1.32 $"
#ifdef CONFIG_QDIO_DEBUG
#define QDIO_VERBOSE_LEVEL 9
@@ -42,7 +44,7 @@
#define QDIO_Q_LAPS 5
-#define QDIO_STORAGE_KEY 0
+#define QDIO_STORAGE_KEY PAGE_DEFAULT_KEY
#define L2_CACHELINE_SIZE 256
#define INDICATORS_PER_CACHELINE (L2_CACHELINE_SIZE/sizeof(__u32))
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c
index a98c00c0255..9ec29bb41b2 100644
--- a/drivers/s390/crypto/z90main.c
+++ b/drivers/s390/crypto/z90main.c
@@ -385,8 +385,8 @@ static int z90crypt_release(struct inode *, struct file *);
static ssize_t z90crypt_read(struct file *, char __user *, size_t, loff_t *);
static ssize_t z90crypt_write(struct file *, const char __user *,
size_t, loff_t *);
-static int z90crypt_ioctl(struct inode *, struct file *,
- unsigned int, unsigned long);
+static long z90crypt_unlocked_ioctl(struct file *, unsigned int, unsigned long);
+static long z90crypt_compat_ioctl(struct file *, unsigned int, unsigned long);
static void z90crypt_reader_task(unsigned long);
static void z90crypt_schedule_reader_task(unsigned long);
@@ -433,12 +433,15 @@ static atomic_t total_open;
static atomic_t z90crypt_step;
static struct file_operations z90crypt_fops = {
- .owner = THIS_MODULE,
- .read = z90crypt_read,
- .write = z90crypt_write,
- .ioctl = z90crypt_ioctl,
- .open = z90crypt_open,
- .release = z90crypt_release
+ .owner = THIS_MODULE,
+ .read = z90crypt_read,
+ .write = z90crypt_write,
+ .unlocked_ioctl = z90crypt_unlocked_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = z90crypt_compat_ioctl,
+#endif
+ .open = z90crypt_open,
+ .release = z90crypt_release
};
#ifndef Z90CRYPT_USE_HOTPLUG
@@ -474,14 +477,13 @@ struct ica_rsa_modexpo_32 { // For 32-bit callers
compat_uptr_t n_modulus;
};
-static int
-trans_modexpo32(unsigned int fd, unsigned int cmd, unsigned long arg,
- struct file *file)
+static long
+trans_modexpo32(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct ica_rsa_modexpo_32 __user *mex32u = compat_ptr(arg);
struct ica_rsa_modexpo_32 mex32k;
struct ica_rsa_modexpo __user *mex64;
- int ret = 0;
+ long ret = 0;
unsigned int i;
if (!access_ok(VERIFY_WRITE, mex32u, sizeof(struct ica_rsa_modexpo_32)))
@@ -498,7 +500,7 @@ trans_modexpo32(unsigned int fd, unsigned int cmd, unsigned long arg,
__put_user(compat_ptr(mex32k.b_key), &mex64->b_key) ||
__put_user(compat_ptr(mex32k.n_modulus), &mex64->n_modulus))
return -EFAULT;
- ret = sys_ioctl(fd, cmd, (unsigned long)mex64);
+ ret = z90crypt_unlocked_ioctl(filp, cmd, (unsigned long)mex64);
if (!ret)
if (__get_user(i, &mex64->outputdatalength) ||
__put_user(i, &mex32u->outputdatalength))
@@ -518,14 +520,13 @@ struct ica_rsa_modexpo_crt_32 { // For 32-bit callers
compat_uptr_t u_mult_inv;
};
-static int
-trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg,
- struct file *file)
+static long
+trans_modexpo_crt32(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct ica_rsa_modexpo_crt_32 __user *crt32u = compat_ptr(arg);
struct ica_rsa_modexpo_crt_32 crt32k;
struct ica_rsa_modexpo_crt __user *crt64;
- int ret = 0;
+ long ret = 0;
unsigned int i;
if (!access_ok(VERIFY_WRITE, crt32u,
@@ -546,9 +547,8 @@ trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg,
__put_user(compat_ptr(crt32k.np_prime), &crt64->np_prime) ||
__put_user(compat_ptr(crt32k.nq_prime), &crt64->nq_prime) ||
__put_user(compat_ptr(crt32k.u_mult_inv), &crt64->u_mult_inv))
- ret = -EFAULT;
- if (!ret)
- ret = sys_ioctl(fd, cmd, (unsigned long)crt64);
+ return -EFAULT;
+ ret = z90crypt_unlocked_ioctl(filp, cmd, (unsigned long)crt64);
if (!ret)
if (__get_user(i, &crt64->outputdatalength) ||
__put_user(i, &crt32u->outputdatalength))
@@ -556,66 +556,34 @@ trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg,
return ret;
}
-static int compatible_ioctls[] = {
- ICAZ90STATUS, Z90QUIESCE, Z90STAT_TOTALCOUNT, Z90STAT_PCICACOUNT,
- Z90STAT_PCICCCOUNT, Z90STAT_PCIXCCCOUNT, Z90STAT_PCIXCCMCL2COUNT,
- Z90STAT_PCIXCCMCL3COUNT, Z90STAT_CEX2CCOUNT, Z90STAT_REQUESTQ_COUNT,
- Z90STAT_PENDINGQ_COUNT, Z90STAT_TOTALOPEN_COUNT, Z90STAT_DOMAIN_INDEX,
- Z90STAT_STATUS_MASK, Z90STAT_QDEPTH_MASK, Z90STAT_PERDEV_REQCNT,
-};
-
-static void z90_unregister_ioctl32s(void)
-{
- int i;
-
- unregister_ioctl32_conversion(ICARSAMODEXPO);
- unregister_ioctl32_conversion(ICARSACRT);
-
- for(i = 0; i < ARRAY_SIZE(compatible_ioctls); i++)
- unregister_ioctl32_conversion(compatible_ioctls[i]);
-}
-
-static int z90_register_ioctl32s(void)
-{
- int result, i;
-
- result = register_ioctl32_conversion(ICARSAMODEXPO, trans_modexpo32);
- if (result == -EBUSY) {
- unregister_ioctl32_conversion(ICARSAMODEXPO);
- result = register_ioctl32_conversion(ICARSAMODEXPO,
- trans_modexpo32);
- }
- if (result)
- return result;
- result = register_ioctl32_conversion(ICARSACRT, trans_modexpo_crt32);
- if (result == -EBUSY) {
- unregister_ioctl32_conversion(ICARSACRT);
- result = register_ioctl32_conversion(ICARSACRT,
- trans_modexpo_crt32);
- }
- if (result)
- return result;
-
- for(i = 0; i < ARRAY_SIZE(compatible_ioctls); i++) {
- result = register_ioctl32_conversion(compatible_ioctls[i], 0);
- if (result == -EBUSY) {
- unregister_ioctl32_conversion(compatible_ioctls[i]);
- result = register_ioctl32_conversion(
- compatible_ioctls[i], 0);
- }
- if (result)
- return result;
- }
- return 0;
-}
-#else // !CONFIG_COMPAT
-static inline void z90_unregister_ioctl32s(void)
-{
-}
-
-static inline int z90_register_ioctl32s(void)
+static long
+z90crypt_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
- return 0;
+ switch (cmd) {
+ case ICAZ90STATUS:
+ case Z90QUIESCE:
+ case Z90STAT_TOTALCOUNT:
+ case Z90STAT_PCICACOUNT:
+ case Z90STAT_PCICCCOUNT:
+ case Z90STAT_PCIXCCCOUNT:
+ case Z90STAT_PCIXCCMCL2COUNT:
+ case Z90STAT_PCIXCCMCL3COUNT:
+ case Z90STAT_CEX2CCOUNT:
+ case Z90STAT_REQUESTQ_COUNT:
+ case Z90STAT_PENDINGQ_COUNT:
+ case Z90STAT_TOTALOPEN_COUNT:
+ case Z90STAT_DOMAIN_INDEX:
+ case Z90STAT_STATUS_MASK:
+ case Z90STAT_QDEPTH_MASK:
+ case Z90STAT_PERDEV_REQCNT:
+ return z90crypt_unlocked_ioctl(filp, cmd, arg);
+ case ICARSAMODEXPO:
+ return trans_modexpo32(filp, cmd, arg);
+ case ICARSACRT:
+ return trans_modexpo_crt32(filp, cmd, arg);
+ default:
+ return -ENOIOCTLCMD;
+ }
}
#endif
@@ -730,14 +698,9 @@ z90crypt_init_module(void)
reader_timer.expires = jiffies + (READERTIME * HZ / 1000);
add_timer(&reader_timer);
- if ((result = z90_register_ioctl32s()))
- goto init_module_cleanup;
-
return 0; // success
init_module_cleanup:
- z90_unregister_ioctl32s();
-
#ifndef Z90CRYPT_USE_HOTPLUG
if ((nresult = misc_deregister(&z90crypt_misc_device)))
PRINTK("misc_deregister failed with %d.\n", nresult);
@@ -763,8 +726,6 @@ z90crypt_cleanup_module(void)
PDEBUG("PID %d\n", PID());
- z90_unregister_ioctl32s();
-
remove_proc_entry("driver/z90crypt", 0);
#ifndef Z90CRYPT_USE_HOTPLUG
@@ -800,7 +761,7 @@ z90crypt_cleanup_module(void)
* z90crypt_release
* z90crypt_read
* z90crypt_write
- * z90crypt_ioctl
+ * z90crypt_unlocked_ioctl
* z90crypt_status
* z90crypt_status_write
* disable_card
@@ -1804,9 +1765,8 @@ z90crypt_rsa(struct priv_data *private_data_p, pid_t pid,
* This function is a little long, but it's really just one large switch
* statement.
*/
-static int
-z90crypt_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static long
+z90crypt_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct priv_data *private_data_p = filp->private_data;
unsigned char *status;
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index a3d28585956..1e3f7f3c662 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -32,7 +32,7 @@ struct smsg_callback {
struct list_head list;
char *prefix;
int len;
- void (*callback)(char *str);
+ void (*callback)(char *from, char *str);
};
MODULE_AUTHOR
@@ -55,8 +55,9 @@ smsg_message_pending(iucv_MessagePending *eib, void *pgm_data)
{
struct smsg_callback *cb;
unsigned char *msg;
+ unsigned char sender[9];
unsigned short len;
- int rc;
+ int rc, i;
len = eib->ln1msg2.ipbfln1f;
msg = kmalloc(len + 1, GFP_ATOMIC|GFP_DMA);
@@ -69,10 +70,18 @@ smsg_message_pending(iucv_MessagePending *eib, void *pgm_data)
if (rc == 0) {
msg[len] = 0;
EBCASC(msg, len);
+ memcpy(sender, msg, 8);
+ sender[8] = 0;
+ /* Remove trailing whitespace from the sender name. */
+ for (i = 7; i >= 0; i--) {
+ if (sender[i] != ' ' && sender[i] != '\t')
+ break;
+ sender[i] = 0;
+ }
spin_lock(&smsg_list_lock);
list_for_each_entry(cb, &smsg_list, list)
if (strncmp(msg + 8, cb->prefix, cb->len) == 0) {
- cb->callback(msg + 8);
+ cb->callback(sender, msg + 8);
break;
}
spin_unlock(&smsg_list_lock);
@@ -91,7 +100,7 @@ static struct device_driver smsg_driver = {
};
int
-smsg_register_callback(char *prefix, void (*callback)(char *str))
+smsg_register_callback(char *prefix, void (*callback)(char *from, char *str))
{
struct smsg_callback *cb;
@@ -108,7 +117,7 @@ smsg_register_callback(char *prefix, void (*callback)(char *str))
}
void
-smsg_unregister_callback(char *prefix, void (*callback)(char *str))
+smsg_unregister_callback(char *prefix, void (*callback)(char *from, char *str))
{
struct smsg_callback *cb, *tmp;
diff --git a/drivers/s390/net/smsgiucv.h b/drivers/s390/net/smsgiucv.h
index 04cd8715296..67f5d4f8378 100644
--- a/drivers/s390/net/smsgiucv.h
+++ b/drivers/s390/net/smsgiucv.h
@@ -5,6 +5,6 @@
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
*/
-int smsg_register_callback(char *, void (*)(char *));
-void smsg_unregister_callback(char *, void (*)(char *));
+int smsg_register_callback(char *, void (*)(char *, char *));
+void smsg_unregister_callback(char *, void (*)(char *, char *));
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index bf3273eb1c8..9b988baf0b5 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -28,10 +28,46 @@
static int rtc_busy = 0;
+/* This is the structure layout used by drivers/char/rtc.c, we
+ * support that driver's ioctls so that things are less messy in
+ * userspace.
+ */
+struct rtc_time_generic {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+};
+#define RTC_AIE_ON _IO('p', 0x01) /* Alarm int. enable on */
+#define RTC_AIE_OFF _IO('p', 0x02) /* ... off */
+#define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */
+#define RTC_UIE_OFF _IO('p', 0x04) /* ... off */
+#define RTC_PIE_ON _IO('p', 0x05) /* Periodic int. enable on */
+#define RTC_PIE_OFF _IO('p', 0x06) /* ... off */
+#define RTC_WIE_ON _IO('p', 0x0f) /* Watchdog int. enable on */
+#define RTC_WIE_OFF _IO('p', 0x10) /* ... off */
+#define RTC_RD_TIME _IOR('p', 0x09, struct rtc_time_generic) /* Read RTC time */
+#define RTC_SET_TIME _IOW('p', 0x0a, struct rtc_time_generic) /* Set RTC time */
+#define RTC_ALM_SET _IOW('p', 0x07, struct rtc_time) /* Set alarm time */
+#define RTC_ALM_READ _IOR('p', 0x08, struct rtc_time) /* Read alarm time */
+#define RTC_IRQP_READ _IOR('p', 0x0b, unsigned long) /* Read IRQ rate */
+#define RTC_IRQP_SET _IOW('p', 0x0c, unsigned long) /* Set IRQ rate */
+#define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */
+#define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */
+#define RTC_WKALM_SET _IOW('p', 0x0f, struct rtc_wkalrm)/* Set wakeup alarm*/
+#define RTC_WKALM_RD _IOR('p', 0x10, struct rtc_wkalrm)/* Get wakeup alarm*/
+#define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */
+#define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */
+
/* Retrieve the current date and time from the real time clock. */
static void get_rtc_time(struct rtc_time *t)
{
- void * __iomem regs = mstk48t02_regs;
+ void __iomem *regs = mstk48t02_regs;
u8 tmp;
spin_lock_irq(&mostek_lock);
@@ -58,7 +94,7 @@ static void get_rtc_time(struct rtc_time *t)
/* Set the current date and time inthe real time clock. */
void set_rtc_time(struct rtc_time *t)
{
- void * __iomem regs = mstk48t02_regs;
+ void __iomem *regs = mstk48t02_regs;
u8 tmp;
spin_lock_irq(&mostek_lock);
@@ -82,29 +118,87 @@ void set_rtc_time(struct rtc_time *t)
spin_unlock_irq(&mostek_lock);
}
+static int put_rtc_time_generic(void __user *argp, struct rtc_time *tm)
+{
+ struct rtc_time_generic __user *utm = argp;
+
+ if (__put_user(tm->sec, &utm->tm_sec) ||
+ __put_user(tm->min, &utm->tm_min) ||
+ __put_user(tm->hour, &utm->tm_hour) ||
+ __put_user(tm->dom, &utm->tm_mday) ||
+ __put_user(tm->month, &utm->tm_mon) ||
+ __put_user(tm->year, &utm->tm_year) ||
+ __put_user(tm->dow, &utm->tm_wday) ||
+ __put_user(0, &utm->tm_yday) ||
+ __put_user(0, &utm->tm_isdst))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int get_rtc_time_generic(struct rtc_time *tm, void __user *argp)
+{
+ struct rtc_time_generic __user *utm = argp;
+
+ if (__get_user(tm->sec, &utm->tm_sec) ||
+ __get_user(tm->min, &utm->tm_min) ||
+ __get_user(tm->hour, &utm->tm_hour) ||
+ __get_user(tm->dom, &utm->tm_mday) ||
+ __get_user(tm->month, &utm->tm_mon) ||
+ __get_user(tm->year, &utm->tm_year) ||
+ __get_user(tm->dow, &utm->tm_wday))
+ return -EFAULT;
+
+ return 0;
+}
+
static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
struct rtc_time rtc_tm;
void __user *argp = (void __user *)arg;
- switch (cmd)
- {
+ switch (cmd) {
+ /* No interrupt support, return an error
+ * compatible with drivers/char/rtc.c
+ */
+ case RTC_AIE_OFF:
+ case RTC_AIE_ON:
+ case RTC_PIE_OFF:
+ case RTC_PIE_ON:
+ case RTC_UIE_OFF:
+ case RTC_UIE_ON:
+ case RTC_IRQP_READ:
+ case RTC_IRQP_SET:
+ case RTC_EPOCH_SET:
+ case RTC_EPOCH_READ:
+ return -EINVAL;
+
case RTCGET:
+ case RTC_RD_TIME:
memset(&rtc_tm, 0, sizeof(struct rtc_time));
get_rtc_time(&rtc_tm);
- if (copy_to_user(argp, &rtc_tm, sizeof(struct rtc_time)))
+ if (cmd == RTCGET) {
+ if (copy_to_user(argp, &rtc_tm,
+ sizeof(struct rtc_time)))
+ return -EFAULT;
+ } else if (put_rtc_time_generic(argp, &rtc_tm))
return -EFAULT;
return 0;
case RTCSET:
+ case RTC_SET_TIME:
if (!capable(CAP_SYS_TIME))
return -EPERM;
- if (copy_from_user(&rtc_tm, argp, sizeof(struct rtc_time)))
+ if (cmd == RTCSET) {
+ if (copy_from_user(&rtc_tm, argp,
+ sizeof(struct rtc_time)))
+ return -EFAULT;
+ } else if (get_rtc_time_generic(&rtc_tm, argp))
return -EFAULT;
set_rtc_time(&rtc_tm);
@@ -156,7 +250,7 @@ static int __init rtc_sun_init(void)
/* It is possible we are being driven by some other RTC chip
* and thus another RTC driver is handling things.
*/
- if (mstk48t02_regs == 0)
+ if (!mstk48t02_regs)
return -ENODEV;
error = misc_register(&rtc_dev);
@@ -164,6 +258,7 @@ static int __init rtc_sun_init(void)
printk(KERN_ERR "rtc: unable to get misc minor for Mostek\n");
return error;
}
+ printk("rtc_sun_init: Registered Mostek RTC driver.\n");
return 0;
}
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index ba88be399a5..88e34095ca4 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -278,7 +278,7 @@ config SCSI_3W_9XXX
config SCSI_7000FASST
tristate "7000FASST SCSI support"
- depends on ISA && SCSI
+ depends on ISA && SCSI && ISA_DMA_API
help
This driver supports the Western Digital 7000 SCSI host adapter
family. Some information is in the source:
@@ -313,7 +313,7 @@ config SCSI_AHA152X
config SCSI_AHA1542
tristate "Adaptec AHA1542 support"
- depends on ISA && SCSI
+ depends on ISA && SCSI && ISA_DMA_API
---help---
This is support for a SCSI host adapter. It is explained in section
3.4 of the SCSI-HOWTO, available from
@@ -533,7 +533,7 @@ config SCSI_SATA_VITESSE
config SCSI_BUSLOGIC
tristate "BusLogic SCSI support"
- depends on (PCI || ISA || MCA) && SCSI && (BROKEN || !SPARC64)
+ depends on (PCI || ISA || MCA) && SCSI && ISA_DMA_API
---help---
This is support for BusLogic MultiMaster and FlashPoint SCSI Host
Adapters. Consult the SCSI-HOWTO, available from
@@ -589,7 +589,7 @@ config SCSI_DTC3280
config SCSI_EATA
tristate "EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support"
- depends on (ISA || EISA || PCI) && SCSI && (BROKEN || !SPARC64)
+ depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API
---help---
This driver supports all EATA/DMA-compliant SCSI host adapters. DPT
ISA and all EISA I/O addresses are probed looking for the "EATA"
@@ -683,7 +683,7 @@ config SCSI_FD_MCS
config SCSI_GDTH
tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller support"
- depends on (ISA || EISA || PCI) && SCSI && (BROKEN || !SPARC64)
+ depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API
---help---
Formerly called GDT SCSI Disk Array Controller Support.
@@ -1412,7 +1412,7 @@ config SCSI_T128
config SCSI_U14_34F
tristate "UltraStor 14F/34F support"
- depends on ISA && SCSI
+ depends on ISA && SCSI && ISA_DMA_API
---help---
This is support for the UltraStor 14F and 34F SCSI-2 host adapters.
The source at <file:drivers/scsi/u14-34f.c> contains some
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
index 74293f62a62..064781a2cb1 100644
--- a/drivers/scsi/NCR53C9x.c
+++ b/drivers/scsi/NCR53C9x.c
@@ -1824,7 +1824,10 @@ static int esp_do_data(struct NCR_ESP *esp, struct ESP_regs *eregs)
/* loop */
while (hmuch) {
int j, fifo_stuck = 0, newphase;
- unsigned long flags, timeout;
+ unsigned long timeout;
+#if 0
+ unsigned long flags;
+#endif
#if 0
if ( i % 10 )
ESPDATA(("\r"));
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 7e9e6b3186a..5fd8f3ee980 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -450,7 +450,7 @@ static int aac_cfg_open(struct inode *inode, struct file *file)
}
}
- return 0;
+ return err;
}
/**
diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c
index d8ab73b6803..f6900538be9 100644
--- a/drivers/scsi/esp.c
+++ b/drivers/scsi/esp.c
@@ -49,6 +49,8 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
+#define DRV_VERSION "1.101"
+
#define DEBUG_ESP
/* #define DEBUG_ESP_HME */
/* #define DEBUG_ESP_DATA */
@@ -1145,7 +1147,7 @@ static int __init esp_detect(struct scsi_host_template *tpnt)
static struct sbus_dev esp_dev;
int esps_in_use = 0;
- espchain = 0;
+ espchain = NULL;
if (sun4_esp_physaddr) {
memset (&esp_dev, 0, sizeof(esp_dev));
@@ -2511,7 +2513,7 @@ static inline void esp_reconnect(struct esp *esp, struct scsi_cmnd *sp)
ESPLOG(("esp%d: Weird, being reselected but disconnected "
"command queue is empty.\n", esp->esp_id));
esp->snip = 0;
- esp->current_SC = 0;
+ esp->current_SC = NULL;
sp->SCp.phase = not_issued;
append_SC(&esp->issue_SC, sp);
}
@@ -4146,7 +4148,7 @@ static int esp_work_bus(struct esp *esp)
}
static espfunc_t isvc_vector[] = {
- 0,
+ NULL,
esp_do_phase_determine,
esp_do_resetbus,
esp_finish_reset,
@@ -4398,5 +4400,8 @@ static struct scsi_host_template driver_template = {
#include "scsi_module.c"
+MODULE_DESCRIPTION("EnhancedScsiProcessor Sun SCSI driver");
+MODULE_AUTHOR("David S. Miller (davem@redhat.com)");
MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c
index e70dedb0d0a..7976947c032 100644
--- a/drivers/scsi/pas16.c
+++ b/drivers/scsi/pas16.c
@@ -137,7 +137,7 @@ static unsigned short pas16_addr = 0;
static int pas16_irq = 0;
-int scsi_irq_translate[] =
+static const int scsi_irq_translate[] =
{ 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 0, 10, 11 };
/* The default_irqs array contains values used to set the irq into the
@@ -145,7 +145,7 @@ int scsi_irq_translate[] =
* irq jumpers on the board). The first value in the array will be
* assigned to logical board 0, the next to board 1, etc.
*/
-int default_irqs[] __initdata =
+static int default_irqs[] __initdata =
{ PAS16_DEFAULT_BOARD_1_IRQ,
PAS16_DEFAULT_BOARD_2_IRQ,
PAS16_DEFAULT_BOARD_3_IRQ,
@@ -177,7 +177,7 @@ static struct base {
#define NO_BASES (sizeof (bases) / sizeof (struct base))
-unsigned short pas16_offset[ 8 ] =
+static const unsigned short pas16_offset[ 8 ] =
{
0x1c00, /* OUTPUT_DATA_REG */
0x1c01, /* INITIATOR_COMMAND_REG */
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c
index 7bb0a2e5674..c01b7191fcf 100644
--- a/drivers/scsi/pluto.c
+++ b/drivers/scsi/pluto.c
@@ -45,7 +45,7 @@ static struct ctrl_inquiry {
Scsi_Cmnd cmd;
char inquiry[256];
fc_channel *fc;
-} *fcs __initdata = { 0 };
+} *fcs __initdata;
static int fcscount __initdata = 0;
static atomic_t fcss __initdata = ATOMIC_INIT(0);
DECLARE_MUTEX_LOCKED(fc_sem);
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 0d730f646bc..5578ae9a9e4 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -542,7 +542,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
* that the device is no longer present */
cmd->result = DID_NO_CONNECT << 16;
atomic_inc(&cmd->device->iorequest_cnt);
- scsi_done(cmd);
+ __scsi_done(cmd);
/* return 0 (because the command has been processed) */
goto out;
}
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 10355857466..cb789c35262 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -582,7 +582,7 @@ static int scsi_request_sense(struct scsi_cmnd *scmd)
memcpy(scmd->cmnd, generic_sense, sizeof(generic_sense));
- scsi_result = kmalloc(252, GFP_ATOMIC | (scmd->device->host->hostt->unchecked_isa_dma) ? __GFP_DMA : 0);
+ scsi_result = kmalloc(252, GFP_ATOMIC | ((scmd->device->host->hostt->unchecked_isa_dma) ? __GFP_DMA : 0));
if (unlikely(!scsi_result)) {
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 287d197a7c1..cca772624ae 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -801,7 +801,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
if (!sreq)
goto out_free_sdev;
result = kmalloc(256, GFP_ATOMIC |
- (shost->unchecked_isa_dma) ? __GFP_DMA : 0);
+ ((shost->unchecked_isa_dma) ? __GFP_DMA : 0));
if (!result)
goto out_free_sreq;
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 303d7656f71..28966d05435 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/workqueue.h>
+#include <linux/blkdev.h>
#include <asm/semaphore.h>
#include <scsi/scsi.h>
#include "scsi_priv.h"
@@ -41,6 +42,11 @@
#define SPI_MAX_ECHO_BUFFER_SIZE 4096
+#define DV_LOOPS 3
+#define DV_TIMEOUT (10*HZ)
+#define DV_RETRIES 3 /* should only need at most
+ * two cc/ua clears */
+
/* Private data accessors (keep these out of the header file) */
#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending)
#define spi_dv_sem(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_sem)
@@ -100,6 +106,29 @@ static int sprint_frac(char *dest, int value, int denom)
return result;
}
+/* Modification of scsi_wait_req that will clear UNIT ATTENTION conditions
+ * resulting from (likely) bus and device resets */
+static void spi_wait_req(struct scsi_request *sreq, const void *cmd,
+ void *buffer, unsigned bufflen)
+{
+ int i;
+
+ for(i = 0; i < DV_RETRIES; i++) {
+ sreq->sr_request->flags |= REQ_FAILFAST;
+
+ scsi_wait_req(sreq, cmd, buffer, bufflen,
+ DV_TIMEOUT, /* retries */ 1);
+ if (sreq->sr_result & DRIVER_SENSE) {
+ struct scsi_sense_hdr sshdr;
+
+ if (scsi_request_normalize_sense(sreq, &sshdr)
+ && sshdr.sense_key == UNIT_ATTENTION)
+ continue;
+ }
+ break;
+ }
+}
+
static struct {
enum spi_signal_type value;
char *name;
@@ -378,11 +407,6 @@ static CLASS_DEVICE_ATTR(signalling, S_IRUGO | S_IWUSR,
if(i->f->set_##x) \
i->f->set_##x(sdev->sdev_target, y)
-#define DV_LOOPS 3
-#define DV_TIMEOUT (10*HZ)
-#define DV_RETRIES 3 /* should only need at most
- * two cc/ua clears */
-
enum spi_compare_returns {
SPI_COMPARE_SUCCESS,
SPI_COMPARE_FAILURE,
@@ -446,8 +470,7 @@ spi_dv_device_echo_buffer(struct scsi_request *sreq, u8 *buffer,
for (r = 0; r < retries; r++) {
sreq->sr_cmd_len = 0; /* wait_req to fill in */
sreq->sr_data_direction = DMA_TO_DEVICE;
- scsi_wait_req(sreq, spi_write_buffer, buffer, len,
- DV_TIMEOUT, DV_RETRIES);
+ spi_wait_req(sreq, spi_write_buffer, buffer, len);
if(sreq->sr_result || !scsi_device_online(sdev)) {
struct scsi_sense_hdr sshdr;
@@ -471,8 +494,7 @@ spi_dv_device_echo_buffer(struct scsi_request *sreq, u8 *buffer,
memset(ptr, 0, len);
sreq->sr_cmd_len = 0; /* wait_req to fill in */
sreq->sr_data_direction = DMA_FROM_DEVICE;
- scsi_wait_req(sreq, spi_read_buffer, ptr, len,
- DV_TIMEOUT, DV_RETRIES);
+ spi_wait_req(sreq, spi_read_buffer, ptr, len);
scsi_device_set_state(sdev, SDEV_QUIESCE);
if (memcmp(buffer, ptr, len) != 0)
@@ -500,8 +522,7 @@ spi_dv_device_compare_inquiry(struct scsi_request *sreq, u8 *buffer,
memset(ptr, 0, len);
- scsi_wait_req(sreq, spi_inquiry, ptr, len,
- DV_TIMEOUT, DV_RETRIES);
+ spi_wait_req(sreq, spi_inquiry, ptr, len);
if(sreq->sr_result || !scsi_device_online(sdev)) {
scsi_device_set_state(sdev, SDEV_QUIESCE);
@@ -593,8 +614,7 @@ spi_dv_device_get_echo_buffer(struct scsi_request *sreq, u8 *buffer)
* (reservation conflict, device not ready, etc) just
* skip the write tests */
for (l = 0; ; l++) {
- scsi_wait_req(sreq, spi_test_unit_ready, NULL, 0,
- DV_TIMEOUT, DV_RETRIES);
+ spi_wait_req(sreq, spi_test_unit_ready, NULL, 0);
if(sreq->sr_result) {
if(l >= 3)
@@ -608,8 +628,7 @@ spi_dv_device_get_echo_buffer(struct scsi_request *sreq, u8 *buffer)
sreq->sr_cmd_len = 0;
sreq->sr_data_direction = DMA_FROM_DEVICE;
- scsi_wait_req(sreq, spi_read_buffer_descriptor, buffer, 4,
- DV_TIMEOUT, DV_RETRIES);
+ spi_wait_req(sreq, spi_read_buffer_descriptor, buffer, 4);
if (sreq->sr_result)
/* Device has no echo buffer */
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 5ff83d214f1..5b07c6ec3ec 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -2038,8 +2038,9 @@ static void sym2_set_period(struct scsi_target *starget, int period)
struct sym_hcb *np = sym_get_hcb(shost);
struct sym_tcb *tp = &np->target[starget->id];
- /* have to have DT for these transfers */
- if (period <= np->minsync)
+ /* have to have DT for these transfers, but DT will also
+ * set width, so check that this is allowed */
+ if (period <= np->minsync && spi_width(starget))
tp->tgoal.dt = 1;
tp->tgoal.period = period;
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index f8504b0adeb..33fbda79f35 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -110,7 +110,7 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *r
port->icount.rx++;
rxs = *CSR_RXSTAT | RXSTAT_DUMMY_READ;
- if (rxs & RXSTAT_ANYERR) {
+ if (unlikely(rxs & RXSTAT_ANYERR)) {
if (rxs & RXSTAT_PARITY)
port->icount.parity++;
else if (rxs & RXSTAT_FRAME)
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 218b69372c0..0d9358608fd 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -51,7 +51,7 @@
* share_irqs - whether we pass SA_SHIRQ to request_irq(). This option
* is unsafe when used on edge-triggered interrupts.
*/
-unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
+static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
/*
* Debugging.
diff --git a/drivers/serial/8250_hp300.c b/drivers/serial/8250_hp300.c
index b8d51eb56bf..4315afe9c08 100644
--- a/drivers/serial/8250_hp300.c
+++ b/drivers/serial/8250_hp300.c
@@ -9,15 +9,15 @@
#include <linux/init.h>
#include <linux/string.h>
#include <linux/kernel.h>
-#include <linux/tty.h>
#include <linux/serial.h>
-#include <linux/serialP.h>
#include <linux/serial_core.h>
#include <linux/delay.h>
#include <linux/dio.h>
#include <linux/console.h>
#include <asm/io.h>
+#include "8250.h"
+
#if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI)
#warning CONFIG_8250 defined but neither CONFIG_HPDCA nor CONFIG_HPAPCI defined, are you sure?
#endif
@@ -163,7 +163,7 @@ int __init hp300_setup_serial_console(void)
static int __devinit hpdca_init_one(struct dio_dev *d,
const struct dio_device_id *ent)
{
- struct serial_struct serial_req;
+ struct uart_port port;
int line;
#ifdef CONFIG_SERIAL_8250_CONSOLE
@@ -172,21 +172,22 @@ static int __devinit hpdca_init_one(struct dio_dev *d,
return 0;
}
#endif
- memset(&serial_req, 0, sizeof(struct serial_struct));
+ memset(&port, 0, sizeof(struct uart_port));
/* Memory mapped I/O */
- serial_req.io_type = SERIAL_IO_MEM;
- serial_req.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF;
- serial_req.irq = d->ipl;
- serial_req.baud_base = HPDCA_BAUD_BASE;
- serial_req.iomap_base = (d->resource.start + UART_OFFSET);
- serial_req.iomem_base = (char *)(serial_req.iomap_base + DIO_VIRADDRBASE);
- serial_req.iomem_reg_shift = 1;
- line = register_serial(&serial_req);
+ port.iotype = UPIO_MEM;
+ port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF;
+ port.irq = d->ipl;
+ port.uartclk = HPDCA_BAUD_BASE * 16;
+ port.mapbase = (d->resource.start + UART_OFFSET);
+ port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE);
+ port.regshift = 1;
+ port.dev = &d->dev;
+ line = serial8250_register_port(&port);
if (line < 0) {
printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d"
- " irq %d failed\n", d->scode, serial_req.irq);
+ " irq %d failed\n", d->scode, port.irq);
return -ENOMEM;
}
@@ -209,7 +210,7 @@ static int __init hp300_8250_init(void)
#ifdef CONFIG_HPAPCI
int line;
unsigned long base;
- struct serial_struct serial_req;
+ struct uart_port uport;
struct hp300_port *port;
int i;
#endif
@@ -251,25 +252,25 @@ static int __init hp300_8250_init(void)
if (!port)
return -ENOMEM;
- memset(&serial_req, 0, sizeof(struct serial_struct));
+ memset(&uport, 0, sizeof(struct uart_port));
base = (FRODO_BASE + FRODO_APCI_OFFSET(i));
/* Memory mapped I/O */
- serial_req.io_type = SERIAL_IO_MEM;
- serial_req.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF;
+ uport.iotype = UPIO_MEM;
+ uport.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF;
/* XXX - no interrupt support yet */
- serial_req.irq = 0;
- serial_req.baud_base = HPAPCI_BAUD_BASE;
- serial_req.iomap_base = base;
- serial_req.iomem_base = (char *)(serial_req.iomap_base + DIO_VIRADDRBASE);
- serial_req.iomem_reg_shift = 2;
+ uport.irq = 0;
+ uport.uartclk = HPAPCI_BAUD_BASE * 16;
+ uport.mapbase = base;
+ uport.membase = (char *)(base + DIO_VIRADDRBASE);
+ uport.regshift = 2;
- line = register_serial(&serial_req);
+ line = serial8250_register_port(&uport);
if (line < 0) {
printk(KERN_NOTICE "8250_hp300: register_serial() APCI %d"
- " irq %d failed\n", i, serial_req.irq);
+ " irq %d failed\n", i, uport.irq);
kfree(port);
continue;
}
@@ -299,7 +300,7 @@ static void __devexit hpdca_remove_one(struct dio_dev *d)
/* Disable board-interrupts */
out_8(d->resource.start + DIO_VIRADDRBASE + DCA_IC, 0);
}
- unregister_serial(line);
+ serial8250_unregister_port(line);
}
#endif
@@ -309,7 +310,7 @@ static void __exit hp300_8250_exit(void)
struct hp300_port *port, *to_free;
for (port = hp300_ports; port; ) {
- unregister_serial(port->line);
+ serial8250_unregister_port(port->line);
to_free = port;
port = port->next;
kfree(to_free);
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index f8d90d0ecfe..de54bdc5398 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -1009,6 +1009,8 @@ get_pci_irq(struct pci_dev *dev, struct pci_board *board, int idx)
* n = number of serial ports
* baud = baud rate
*
+ * This table is sorted by (in order): baud, bt, bn, n.
+ *
* Please note: in theory if n = 1, _bt infix should make no difference.
* ie, pbn_b0_1_115200 is the same as pbn_b0_bt_1_115200
*/
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 484f6fb900b..f2a5e2933c4 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -172,7 +172,7 @@ pl010_rx_chars(struct uart_port *port)
* out of the main execution path
*/
rsr = UART_GET_RSR(port) | UART_DUMMY_RSR_RX;
- if (rsr & UART01x_RSR_ANY) {
+ if (unlikely(rsr & UART01x_RSR_ANY)) {
if (rsr & UART01x_RSR_BE) {
rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE);
port->icount.brk++;
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index ff658a830f3..d5cbef3fe8b 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -137,7 +137,7 @@ pl011_rx_chars(struct uart_amba_port *uap)
* out of the main execution path
*/
rsr = readw(uap->port.membase + UART01x_RSR) | UART_DUMMY_RSR_RX;
- if (rsr & UART01x_RSR_ANY) {
+ if (unlikely(rsr & UART01x_RSR_ANY)) {
if (rsr & UART01x_RSR_BE) {
rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE);
uap->port.icount.brk++;
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index 16592fae47f..6242f3090a9 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -116,54 +116,43 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *re
* Note that the error handling code is
* out of the main execution path
*/
- if (ch & UART_ANY_ERR)
- goto handle_error;
+ if (unlikely(ch & UART_ANY_ERR)) {
+ if (ch & UARTDR_PARERR)
+ port->icount.parity++;
+ else if (ch & UARTDR_FRMERR)
+ port->icount.frame++;
+ if (ch & UARTDR_OVERR)
+ port->icount.overrun++;
- if (uart_handle_sysrq_char(port, ch, regs))
- goto ignore_char;
+ ch &= port->read_status_mask;
- error_return:
- tty_insert_flip_char(tty, ch, flg);
- ignore_char:
- status = clps_readl(SYSFLG(port));
- }
- out:
- tty_flip_buffer_push(tty);
- return IRQ_HANDLED;
+ if (ch & UARTDR_PARERR)
+ flg = TTY_PARITY;
+ else if (ch & UARTDR_FRMERR)
+ flg = TTY_FRAME;
- handle_error:
- if (ch & UARTDR_PARERR)
- port->icount.parity++;
- else if (ch & UARTDR_FRMERR)
- port->icount.frame++;
- if (ch & UARTDR_OVERR)
- port->icount.overrun++;
-
- if (ch & port->ignore_status_mask) {
- if (++ignored > 100)
- goto out;
- goto ignore_char;
- }
- ch &= port->read_status_mask;
+#ifdef SUPPORT_SYSRQ
+ port->sysrq = 0;
+#endif
+ }
- if (ch & UARTDR_PARERR)
- flg = TTY_PARITY;
- else if (ch & UARTDR_FRMERR)
- flg = TTY_FRAME;
+ if (uart_handle_sysrq_char(port, ch, regs))
+ goto ignore_char;
- if (ch & UARTDR_OVERR) {
/*
* CHECK: does overrun affect the current character?
* ASSUMPTION: it does not.
*/
- tty_insert_flip_char(tty, ch, flg);
- ch = 0;
- flg = TTY_OVERRUN;
+ if ((ch & port->ignore_status_mask & ~RXSTAT_OVERRUN) == 0)
+ tty_insert_flip_char(tty, ch, flg);
+ if ((ch & ~port->ignore_status_mask & RXSTAT_OVERRUN) == 0)
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+
+ ignore_char:
+ status = clps_readl(SYSFLG(port));
}
-#ifdef SUPPORT_SYSRQ
- port->sysrq = 0;
-#endif
- goto error_return;
+ tty_flip_buffer_push(tty);
+ return IRQ_HANDLED;
}
static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index c682c6308cd..01a8726a3f9 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -321,18 +321,39 @@ static void imx_break_ctl(struct uart_port *port, int break_state)
#define TXTL 2 /* reset default */
#define RXTL 1 /* reset default */
+static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
+{
+ unsigned int val;
+ unsigned int ufcr_rfdiv;
+
+ /* set receiver / transmitter trigger level.
+ * RFDIV is set such way to satisfy requested uartclk value
+ */
+ val = TXTL<<10 | RXTL;
+ ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk;
+
+ if(!ufcr_rfdiv)
+ ufcr_rfdiv = 1;
+
+ if(ufcr_rfdiv >= 7)
+ ufcr_rfdiv = 6;
+ else
+ ufcr_rfdiv = 6 - ufcr_rfdiv;
+
+ val |= UFCR_RFDIV & (ufcr_rfdiv << 7);
+
+ UFCR((u32)sport->port.membase) = val;
+
+ return 0;
+}
+
static int imx_startup(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
int retval;
- unsigned int val;
unsigned long flags;
- /* set receiver / transmitter trigger level. We assume
- * that RFDIV has been set by the arch setup or by the bootloader.
- */
- val = (UFCR((u32)sport->port.membase) & UFCR_RFDIV) | TXTL<<10 | RXTL;
- UFCR((u32)sport->port.membase) = val;
+ imx_setup_ufcr(sport, 0);
/* disable the DREN bit (Data Ready interrupt enable) before
* requesting IRQs
@@ -737,9 +758,12 @@ static void __init
imx_console_get_options(struct imx_port *sport, int *baud,
int *parity, int *bits)
{
+
if ( UCR1((u32)sport->port.membase) | UCR1_UARTEN ) {
/* ok, the port was enabled */
unsigned int ucr2, ubir,ubmr, uartclk;
+ unsigned int baud_raw;
+ unsigned int ucfr_rfdiv;
ucr2 = UCR2((u32)sport->port.membase);
@@ -758,9 +782,35 @@ imx_console_get_options(struct imx_port *sport, int *baud,
ubir = UBIR((u32)sport->port.membase) & 0xffff;
ubmr = UBMR((u32)sport->port.membase) & 0xffff;
- uartclk = sport->port.uartclk;
- *baud = ((uartclk/16) * (ubir + 1)) / (ubmr + 1);
+
+ ucfr_rfdiv = (UFCR((u32)sport->port.membase) & UFCR_RFDIV) >> 7;
+ if (ucfr_rfdiv == 6)
+ ucfr_rfdiv = 7;
+ else
+ ucfr_rfdiv = 6 - ucfr_rfdiv;
+
+ uartclk = imx_get_perclk1();
+ uartclk /= ucfr_rfdiv;
+
+ { /*
+ * The next code provides exact computation of
+ * baud_raw = round(((uartclk/16) * (ubir + 1)) / (ubmr + 1))
+ * without need of float support or long long division,
+ * which would be required to prevent 32bit arithmetic overflow
+ */
+ unsigned int mul = ubir + 1;
+ unsigned int div = 16 * (ubmr + 1);
+ unsigned int rem = uartclk % div;
+
+ baud_raw = (uartclk / div) * mul;
+ baud_raw += (rem * mul + div / 2) / div;
+ *baud = (baud_raw + 50) / 100 * 100;
+ }
+
+ if(*baud != baud_raw)
+ printk(KERN_INFO "Serial: Console IMX rounded baud rate from %d to %d\n",
+ baud_raw, *baud);
}
}
@@ -787,6 +837,8 @@ imx_console_setup(struct console *co, char *options)
else
imx_console_get_options(sport, &baud, &parity, &bits);
+ imx_setup_ufcr(sport, 0);
+
return uart_set_options(&sport->port, co, baud, parity, bits, flow);
}
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index d054f126570..ba4e13a22a5 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -838,7 +838,7 @@ static int inline port_init(struct ioc4_port *port)
port->ip_tx_prod = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK;
writel(port->ip_tx_prod, &port->ip_serial_regs->stpir);
port->ip_rx_cons = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
- writel(port->ip_rx_cons, &port->ip_serial_regs->srcir);
+ writel(port->ip_rx_cons | IOC4_SRCIR_ARM, &port->ip_serial_regs->srcir);
/* Disable interrupts for this 16550 */
uart = port->ip_uart_regs;
@@ -1272,8 +1272,9 @@ static inline int set_rx_timeout(struct ioc4_port *port, int timeout)
* and set the rx threshold to that amount. There are 4 chars
* per ring entry, so we'll divide the number of chars that will
* arrive in timeout by 4.
+ * So .... timeout * baud / 10 / HZ / 4, with HZ = 100.
*/
- threshold = timeout * port->ip_baud / 10 / HZ / 4;
+ threshold = timeout * port->ip_baud / 4000;
if (threshold == 0)
threshold = 1; /* otherwise we'll intr all the time! */
@@ -1285,8 +1286,10 @@ static inline int set_rx_timeout(struct ioc4_port *port, int timeout)
writel(port->ip_sscr, &port->ip_serial_regs->sscr);
- /* Now set the rx timeout to the given value */
- timeout = timeout * IOC4_SRTR_HZ / HZ;
+ /* Now set the rx timeout to the given value
+ * again timeout * IOC4_SRTR_HZ / HZ
+ */
+ timeout = timeout * IOC4_SRTR_HZ / 100;
if (timeout > IOC4_SRTR_CNT)
timeout = IOC4_SRTR_CNT;
@@ -1380,7 +1383,7 @@ config_port(struct ioc4_port *port,
if (port->ip_tx_lowat == 0)
port->ip_tx_lowat = 1;
- set_rx_timeout(port, port->ip_rx_timeout);
+ set_rx_timeout(port, 2);
return 0;
}
@@ -1685,8 +1688,8 @@ ioc4_change_speed(struct uart_port *the_port,
{
struct ioc4_port *port = get_ioc4_port(the_port);
int baud, bits;
- unsigned cflag, cval;
- int new_parity = 0, new_parity_enable = 0, new_stop = 1, new_data = 8;
+ unsigned cflag;
+ int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8;
struct uart_info *info = the_port->info;
cflag = new_termios->c_cflag;
@@ -1694,48 +1697,35 @@ ioc4_change_speed(struct uart_port *the_port,
switch (cflag & CSIZE) {
case CS5:
new_data = 5;
- cval = 0x00;
bits = 7;
break;
case CS6:
new_data = 6;
- cval = 0x01;
bits = 8;
break;
case CS7:
new_data = 7;
- cval = 0x02;
bits = 9;
break;
case CS8:
new_data = 8;
- cval = 0x03;
bits = 10;
break;
default:
/* cuz we always need a default ... */
new_data = 5;
- cval = 0x00;
bits = 7;
break;
}
if (cflag & CSTOPB) {
- cval |= 0x04;
bits++;
new_stop = 1;
}
if (cflag & PARENB) {
- cval |= UART_LCR_PARITY;
bits++;
new_parity_enable = 1;
- }
- if (cflag & PARODD) {
- cval |= UART_LCR_EPAR;
- new_parity = 1;
- }
- if (cflag & IGNPAR) {
- cval &= ~UART_LCR_PARITY;
- new_parity_enable = 0;
+ if (cflag & PARODD)
+ new_parity = 1;
}
baud = uart_get_baud_rate(the_port, new_termios, old_termios,
MIN_BAUD_SUPPORTED, MAX_BAUD_SUPPORTED);
@@ -1765,10 +1755,15 @@ ioc4_change_speed(struct uart_port *the_port,
the_port->ignore_status_mask &= ~N_DATA_READY;
}
- if (cflag & CRTSCTS)
+ if (cflag & CRTSCTS) {
info->flags |= ASYNC_CTS_FLOW;
- else
+ port->ip_sscr |= IOC4_SSCR_HFC_EN;
+ }
+ else {
info->flags &= ~ASYNC_CTS_FLOW;
+ port->ip_sscr &= ~IOC4_SSCR_HFC_EN;
+ }
+ writel(port->ip_sscr, &port->ip_serial_regs->sscr);
/* Set the configuration and proper notification call */
DPRINT_CONFIG(("%s : port 0x%p cflag 0%o "
@@ -1825,12 +1820,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
/* set the speed of the serial port */
ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0);
- /* enable hardware flow control - after ioc4_change_speed because
- * ASYNC_CTS_FLOW is set there */
- if (info->flags & ASYNC_CTS_FLOW) {
- port->ip_sscr |= IOC4_SSCR_HFC_EN;
- writel(port->ip_sscr, &port->ip_serial_regs->sscr);
- }
info->flags |= UIF_INITIALIZED;
return 0;
}
@@ -1847,7 +1836,6 @@ static void ioc4_cb_output_lowat(struct ioc4_port *port)
}
}
-
/**
* handle_intr - service any interrupts for the given port - 2nd level
* called via sd_intr
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h
index e0717611c94..777829fa330 100644
--- a/drivers/serial/jsm/jsm.h
+++ b/drivers/serial/jsm/jsm.h
@@ -393,7 +393,6 @@ int jsm_tty_init(struct jsm_board *);
int jsm_uart_port_init(struct jsm_board *);
int jsm_remove_uart_port(struct jsm_board *);
void jsm_input(struct jsm_channel *ch);
-void jsm_carrier(struct jsm_channel *ch);
void jsm_check_queue_flow_control(struct jsm_channel *ch);
#endif
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index 9b79c1ff6c7..3a11a69feb4 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -688,7 +688,7 @@ static void neo_flush_uart_read(struct jsm_channel *ch)
/*
* No locks are assumed to be held when calling this function.
*/
-void neo_clear_break(struct jsm_channel *ch, int force)
+static void neo_clear_break(struct jsm_channel *ch, int force)
{
unsigned long lock_flags;
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 24fe76c2883..98de2258fd0 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -31,6 +31,8 @@
#include "jsm.h"
+static void jsm_carrier(struct jsm_channel *ch);
+
static inline int jsm_get_mstat(struct jsm_channel *ch)
{
unsigned char mstat;
@@ -755,7 +757,7 @@ void jsm_input(struct jsm_channel *ch)
jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n");
}
-void jsm_carrier(struct jsm_channel *ch)
+static void jsm_carrier(struct jsm_channel *ch)
{
struct jsm_board *bd;
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index d0dfc3cf924..a8314aee2ab 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -329,8 +329,8 @@ mpsc_sdma_stop(struct mpsc_port_info *pi)
mpsc_sdma_cmd(pi, SDMA_SDCM_AR | SDMA_SDCM_AT);
/* Clear the SDMA current and first TX and RX pointers */
- mpsc_sdma_set_tx_ring(pi, 0);
- mpsc_sdma_set_rx_ring(pi, 0);
+ mpsc_sdma_set_tx_ring(pi, NULL);
+ mpsc_sdma_set_rx_ring(pi, NULL);
/* Disable interrupts */
mpsc_sdma_intr_mask(pi, 0xf);
@@ -1540,8 +1540,8 @@ mpsc_shared_unmap_regs(void)
MPSC_SDMA_INTR_REG_BLOCK_SIZE);
}
- mpsc_shared_regs.mpsc_routing_base = 0;
- mpsc_shared_regs.sdma_intr_base = 0;
+ mpsc_shared_regs.mpsc_routing_base = NULL;
+ mpsc_shared_regs.sdma_intr_base = NULL;
mpsc_shared_regs.mpsc_routing_base_p = 0;
mpsc_shared_regs.sdma_intr_base_p = 0;
@@ -1678,9 +1678,9 @@ mpsc_drv_unmap_regs(struct mpsc_port_info *pi)
release_mem_region(pi->brg_base_p, MPSC_BRG_REG_BLOCK_SIZE);
}
- pi->mpsc_base = 0;
- pi->sdma_base = 0;
- pi->brg_base = 0;
+ pi->mpsc_base = NULL;
+ pi->sdma_base = NULL;
+ pi->brg_base = NULL;
pi->mpsc_base_p = 0;
pi->sdma_base_p = 0;
diff --git a/drivers/serial/mpsc.h b/drivers/serial/mpsc.h
index 1f7294b7095..678dbcf06c8 100644
--- a/drivers/serial/mpsc.h
+++ b/drivers/serial/mpsc.h
@@ -83,8 +83,8 @@ struct mpsc_shared_regs {
phys_addr_t mpsc_routing_base_p;
phys_addr_t sdma_intr_base_p;
- void *mpsc_routing_base;
- void *sdma_intr_base;
+ void __iomem *mpsc_routing_base;
+ void __iomem *sdma_intr_base;
u32 MPSC_MRR_m;
u32 MPSC_RCRR_m;
@@ -120,9 +120,9 @@ struct mpsc_port_info {
phys_addr_t brg_base_p;
/* Virtual addresses of various blocks of registers (from platform) */
- void *mpsc_base;
- void *sdma_base;
- void *brg_base;
+ void __iomem *mpsc_base;
+ void __iomem *sdma_base;
+ void __iomem *brg_base;
/* Descriptor ring and buffer allocations */
void *dma_region;
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index bd6782aeb83..435750d40a4 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -364,7 +364,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id, struct pt_regs *regs)
flag = TTY_NORMAL;
port->icount.rx++;
- if (uerstat & S3C2410_UERSTAT_ANY) {
+ if (unlikely(uerstat & S3C2410_UERSTAT_ANY)) {
dbg("rxerr: port ch=0x%02x, rxs=0x%08x\n",
ch, uerstat);
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 086065210d1..157218bc6c6 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -214,56 +214,39 @@ sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs)
* note that the error handling code is
* out of the main execution path
*/
- if (status & UTSR1_TO_SM(UTSR1_PRE | UTSR1_FRE | UTSR1_ROR))
- goto handle_error;
+ if (status & UTSR1_TO_SM(UTSR1_PRE | UTSR1_FRE | UTSR1_ROR)) {
+ if (status & UTSR1_TO_SM(UTSR1_PRE))
+ sport->port.icount.parity++;
+ else if (status & UTSR1_TO_SM(UTSR1_FRE))
+ sport->port.icount.frame++;
+ if (status & UTSR1_TO_SM(UTSR1_ROR))
+ sport->port.icount.overrun++;
+
+ status &= sport->port.read_status_mask;
+
+ if (status & UTSR1_TO_SM(UTSR1_PRE))
+ flg = TTY_PARITY;
+ else if (status & UTSR1_TO_SM(UTSR1_FRE))
+ flg = TTY_FRAME;
+
+#ifdef SUPPORT_SYSRQ
+ sport->port.sysrq = 0;
+#endif
+ }
if (uart_handle_sysrq_char(&sport->port, ch, regs))
goto ignore_char;
- error_return:
- tty_insert_flip_char(tty, ch, flg);
+ if ((status & port->ignore_status_mask & ~UTSR1_TO_SM(UTSR1_ROR)) == 0)
+ tty_insert_flip_char(tty, ch, flg);
+ if (status & ~port->ignore_status_mask & UTSR1_TO_SM(UTSR1_ROR))
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+
ignore_char:
status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
UTSR0_TO_SM(UART_GET_UTSR0(sport));
}
- out:
tty_flip_buffer_push(tty);
- return;
-
- handle_error:
- if (status & UTSR1_TO_SM(UTSR1_PRE))
- sport->port.icount.parity++;
- else if (status & UTSR1_TO_SM(UTSR1_FRE))
- sport->port.icount.frame++;
- if (status & UTSR1_TO_SM(UTSR1_ROR))
- sport->port.icount.overrun++;
-
- if (status & sport->port.ignore_status_mask) {
- if (++ignored > 100)
- goto out;
- goto ignore_char;
- }
-
- status &= sport->port.read_status_mask;
-
- if (status & UTSR1_TO_SM(UTSR1_PRE))
- flg = TTY_PARITY;
- else if (status & UTSR1_TO_SM(UTSR1_FRE))
- flg = TTY_FRAME;
-
- if (status & UTSR1_TO_SM(UTSR1_ROR)) {
- /*
- * overrun does *not* affect the character
- * we read from the FIFO
- */
- tty_insert_flip_char(tty, ch, flg);
- ch = 0;
- flg = TTY_OVERRUN;
- }
-#ifdef SUPPORT_SYSRQ
- sport->port.sysrq = 0;
-#endif
- goto error_return;
}
static void sa1100_tx_chars(struct sa1100_port *sport)
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 9034f9ad37c..6eeb48f6a48 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -107,6 +107,13 @@ struct serial_info {
int line[4];
};
+struct serial_cfg_mem {
+ tuple_t tuple;
+ cisparse_t parse;
+ u_char buf[256];
+};
+
+
static void serial_config(dev_link_t * link);
static int serial_event(event_t event, int priority,
event_callback_args_t * args);
@@ -357,14 +364,24 @@ static int simple_config(dev_link_t *link)
static int size_table[2] = { 8, 16 };
client_handle_t handle = link->handle;
struct serial_info *info = link->priv;
- tuple_t tuple;
- u_char buf[256];
- cisparse_t parse;
- cistpl_cftable_entry_t *cf = &parse.cftable_entry;
+ struct serial_cfg_mem *cfg_mem;
+ tuple_t *tuple;
+ u_char *buf;
+ cisparse_t *parse;
+ cistpl_cftable_entry_t *cf;
config_info_t config;
int i, j, try;
int s;
+ cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
+ if (!cfg_mem)
+ return -1;
+
+ tuple = &cfg_mem->tuple;
+ parse = &cfg_mem->parse;
+ cf = &parse->cftable_entry;
+ buf = cfg_mem->buf;
+
/* If the card is already configured, look up the port and irq */
i = pcmcia_get_configuration_info(handle, &config);
if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) {
@@ -377,21 +394,23 @@ static int simple_config(dev_link_t *link)
port = config.BasePort1 + 0x28;
info->slave = 1;
}
- if (info->slave)
+ if (info->slave) {
+ kfree(cfg_mem);
return setup_serial(handle, info, port, config.AssignedIRQ);
+ }
}
link->conf.Vcc = config.Vcc;
/* First pass: look for a config entry that looks normal. */
- tuple.TupleData = (cisdata_t *) buf;
- tuple.TupleOffset = 0;
- tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ tuple->TupleData = (cisdata_t *) buf;
+ tuple->TupleOffset = 0;
+ tuple->TupleDataMax = 255;
+ tuple->Attributes = 0;
+ tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
/* Two tries: without IO aliases, then with aliases */
for (s = 0; s < 2; s++) {
for (try = 0; try < 2; try++) {
- i = first_tuple(handle, &tuple, &parse);
+ i = first_tuple(handle, tuple, parse);
while (i != CS_NO_MORE_ITEMS) {
if (i != CS_SUCCESS)
goto next_entry;
@@ -409,14 +428,14 @@ static int simple_config(dev_link_t *link)
goto found_port;
}
next_entry:
- i = next_tuple(handle, &tuple, &parse);
+ i = next_tuple(handle, tuple, parse);
}
}
}
/* Second pass: try to find an entry that isn't picky about
its base address, then try to grab any standard serial port
address, and finally try to get any free port. */
- i = first_tuple(handle, &tuple, &parse);
+ i = first_tuple(handle, tuple, parse);
while (i != CS_NO_MORE_ITEMS) {
if ((i == CS_SUCCESS) && (cf->io.nwin > 0) &&
((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
@@ -429,7 +448,7 @@ next_entry:
goto found_port;
}
}
- i = next_tuple(handle, &tuple, &parse);
+ i = next_tuple(handle, tuple, parse);
}
found_port:
@@ -437,6 +456,7 @@ next_entry:
printk(KERN_NOTICE
"serial_cs: no usable port range found, giving up\n");
cs_error(link->handle, RequestIO, i);
+ kfree(cfg_mem);
return -1;
}
@@ -450,9 +470,10 @@ next_entry:
i = pcmcia_request_configuration(link->handle, &link->conf);
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestConfiguration, i);
+ kfree(cfg_mem);
return -1;
}
-
+ kfree(cfg_mem);
return setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
}
@@ -460,29 +481,39 @@ static int multi_config(dev_link_t * link)
{
client_handle_t handle = link->handle;
struct serial_info *info = link->priv;
- tuple_t tuple;
- u_char buf[256];
- cisparse_t parse;
- cistpl_cftable_entry_t *cf = &parse.cftable_entry;
+ struct serial_cfg_mem *cfg_mem;
+ tuple_t *tuple;
+ u_char *buf;
+ cisparse_t *parse;
+ cistpl_cftable_entry_t *cf;
config_info_t config;
- int i, base2 = 0;
+ int i, rc, base2 = 0;
+
+ cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
+ if (!cfg_mem)
+ return -1;
+ tuple = &cfg_mem->tuple;
+ parse = &cfg_mem->parse;
+ cf = &parse->cftable_entry;
+ buf = cfg_mem->buf;
i = pcmcia_get_configuration_info(handle, &config);
if (i != CS_SUCCESS) {
cs_error(handle, GetConfigurationInfo, i);
- return -1;
+ rc = -1;
+ goto free_cfg_mem;
}
link->conf.Vcc = config.Vcc;
- tuple.TupleData = (cisdata_t *) buf;
- tuple.TupleOffset = 0;
- tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ tuple->TupleData = (cisdata_t *) buf;
+ tuple->TupleOffset = 0;
+ tuple->TupleDataMax = 255;
+ tuple->Attributes = 0;
+ tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
/* First, look for a generic full-sized window */
link->io.NumPorts1 = info->multi * 8;
- i = first_tuple(handle, &tuple, &parse);
+ i = first_tuple(handle, tuple, parse);
while (i != CS_NO_MORE_ITEMS) {
/* The quad port cards have bad CIS's, so just look for a
window larger than 8 ports and assume it will be right */
@@ -497,14 +528,14 @@ static int multi_config(dev_link_t * link)
if (i == CS_SUCCESS)
break;
}
- i = next_tuple(handle, &tuple, &parse);
+ i = next_tuple(handle, tuple, parse);
}
/* If that didn't work, look for two windows */
if (i != CS_SUCCESS) {
link->io.NumPorts1 = link->io.NumPorts2 = 8;
info->multi = 2;
- i = first_tuple(handle, &tuple, &parse);
+ i = first_tuple(handle, tuple, parse);
while (i != CS_NO_MORE_ITEMS) {
if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) {
link->conf.ConfigIndex = cf->index;
@@ -517,13 +548,14 @@ static int multi_config(dev_link_t * link)
if (i == CS_SUCCESS)
break;
}
- i = next_tuple(handle, &tuple, &parse);
+ i = next_tuple(handle, tuple, parse);
}
}
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestIO, i);
- return -1;
+ rc = -1;
+ goto free_cfg_mem;
}
i = pcmcia_request_irq(link->handle, &link->irq);
@@ -541,7 +573,8 @@ static int multi_config(dev_link_t * link)
i = pcmcia_request_configuration(link->handle, &link->conf);
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestConfiguration, i);
- return -1;
+ rc = -1;
+ goto free_cfg_mem;
}
/* The Oxford Semiconductor OXCF950 cards are in fact single-port:
@@ -554,17 +587,23 @@ static int multi_config(dev_link_t * link)
setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
outb(12, base2 + 1);
}
- return 0;
+ rc = 0;
+ goto free_cfg_mem;
}
setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
/* The Nokia cards are not really multiport cards */
- if (info->manfid == MANFID_NOKIA)
- return 0;
+ if (info->manfid == MANFID_NOKIA) {
+ rc = 0;
+ goto free_cfg_mem;
+ }
for (i = 0; i < info->multi - 1; i++)
- setup_serial(handle, info, base2 + (8 * i), link->irq.AssignedIRQ);
-
- return 0;
+ setup_serial(handle, info, base2 + (8 * i),
+ link->irq.AssignedIRQ);
+ rc = 0;
+free_cfg_mem:
+ kfree(cfg_mem);
+ return rc;
}
/*======================================================================
@@ -579,39 +618,49 @@ void serial_config(dev_link_t * link)
{
client_handle_t handle = link->handle;
struct serial_info *info = link->priv;
- tuple_t tuple;
- u_short buf[128];
- cisparse_t parse;
- cistpl_cftable_entry_t *cf = &parse.cftable_entry;
+ struct serial_cfg_mem *cfg_mem;
+ tuple_t *tuple;
+ u_char *buf;
+ cisparse_t *parse;
+ cistpl_cftable_entry_t *cf;
int i, last_ret, last_fn;
DEBUG(0, "serial_config(0x%p)\n", link);
- tuple.TupleData = (cisdata_t *) buf;
- tuple.TupleOffset = 0;
- tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
+ cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
+ if (!cfg_mem)
+ goto failed;
+
+ tuple = &cfg_mem->tuple;
+ parse = &cfg_mem->parse;
+ cf = &parse->cftable_entry;
+ buf = cfg_mem->buf;
+
+ tuple->TupleData = (cisdata_t *) buf;
+ tuple->TupleOffset = 0;
+ tuple->TupleDataMax = 255;
+ tuple->Attributes = 0;
/* Get configuration register information */
- tuple.DesiredTuple = CISTPL_CONFIG;
- last_ret = first_tuple(handle, &tuple, &parse);
+ tuple->DesiredTuple = CISTPL_CONFIG;
+ last_ret = first_tuple(handle, tuple, parse);
if (last_ret != CS_SUCCESS) {
last_fn = ParseTuple;
goto cs_failed;
}
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
+ link->conf.ConfigBase = parse->config.base;
+ link->conf.Present = parse->config.rmask[0];
/* Configure card */
link->state |= DEV_CONFIG;
/* Is this a compliant multifunction card? */
- tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
- tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
- info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS);
+ tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
+ tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
+ info->multi = (first_tuple(handle, tuple, parse) == CS_SUCCESS);
/* Is this a multiport card? */
- tuple.DesiredTuple = CISTPL_MANFID;
- if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
+ tuple->DesiredTuple = CISTPL_MANFID;
+ if (first_tuple(handle, tuple, parse) == CS_SUCCESS) {
info->manfid = le16_to_cpu(buf[0]);
for (i = 0; i < MULTI_COUNT; i++)
if ((info->manfid == multi_id[i].manfid) &&
@@ -623,13 +672,13 @@ void serial_config(dev_link_t * link)
/* Another check for dual-serial cards: look for either serial or
multifunction cards that ask for appropriate IO port ranges */
- tuple.DesiredTuple = CISTPL_FUNCID;
+ tuple->DesiredTuple = CISTPL_FUNCID;
if ((info->multi == 0) &&
- ((first_tuple(handle, &tuple, &parse) != CS_SUCCESS) ||
- (parse.funcid.func == CISTPL_FUNCID_MULTI) ||
- (parse.funcid.func == CISTPL_FUNCID_SERIAL))) {
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
+ ((first_tuple(handle, tuple, parse) != CS_SUCCESS) ||
+ (parse->funcid.func == CISTPL_FUNCID_MULTI) ||
+ (parse->funcid.func == CISTPL_FUNCID_SERIAL))) {
+ tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ if (first_tuple(handle, tuple, parse) == CS_SUCCESS) {
if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
info->multi = cf->io.win[0].len >> 3;
if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
@@ -664,6 +713,7 @@ void serial_config(dev_link_t * link)
link->dev = &info->node[0];
link->state &= ~DEV_CONFIG_PENDING;
+ kfree(cfg_mem);
return;
cs_failed:
@@ -671,6 +721,7 @@ void serial_config(dev_link_t * link)
failed:
serial_remove(link);
link->state &= ~DEV_CONFIG_PENDING;
+ kfree(cfg_mem);
}
/*======================================================================
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index 4ce3a41f161..85cfa08d3ba 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -162,7 +162,7 @@ lh7a40xuart_rx_chars (struct uart_port* port)
flag = TTY_NORMAL;
++port->icount.rx;
- if (data & RxError) { /* Quick check, short-circuit */
+ if (unlikely(data & RxError)) { /* Quick check, short-circuit */
if (data & RxBreak) {
data &= ~(RxFramingError | RxParityError);
++port->icount.brk;
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index ffaab9b90fd..fee6418e84c 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -787,7 +787,7 @@ static void __init sn_sal_switch_to_interrupts(struct sn_cons_port *port)
static void sn_sal_console_write(struct console *, const char *, unsigned);
static int __init sn_sal_console_setup(struct console *, char *);
-extern struct uart_driver sal_console_uart;
+static struct uart_driver sal_console_uart;
extern struct tty_driver *uart_console_device(struct console *, int *);
static struct console sal_console = {
@@ -801,7 +801,7 @@ static struct console sal_console = {
#define SAL_CONSOLE &sal_console
-struct uart_driver sal_console_uart = {
+static struct uart_driver sal_console_uart = {
.owner = THIS_MODULE,
.driver_name = "sn_console",
.dev_name = DEVICE_NAME,
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 8caaf2e5e47..39b788d95e3 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -682,7 +682,8 @@ static void calc_ebrg(int baud, int *n_ret, int *m_ret)
/* Internal routine, port->lock is held and local interrupts are disabled. */
static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cflag,
- unsigned int iflag, int baud)
+ unsigned int iflag, unsigned int baud,
+ unsigned int quot)
{
unsigned int ebrg;
unsigned char dafo;
@@ -766,6 +767,9 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla
up->port.ignore_status_mask |= (SAB82532_ISR0_RPF |
SAB82532_ISR0_TCD);
+ uart_update_timeout(&up->port, cflag,
+ (up->port.uartclk / (16 * quot)));
+
/* Now bang the new settings into the chip. */
sunsab_cec_wait(up);
sunsab_tec_wait(up);
@@ -784,10 +788,11 @@ static void sunsab_set_termios(struct uart_port *port, struct termios *termios,
{
struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
unsigned long flags;
- int baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
+ unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
+ unsigned int quot = uart_get_divisor(port, baud);
spin_lock_irqsave(&up->port.lock, flags);
- sunsab_convert_to_sab(up, termios->c_cflag, termios->c_iflag, baud);
+ sunsab_convert_to_sab(up, termios->c_cflag, termios->c_iflag, baud, quot);
spin_unlock_irqrestore(&up->port.lock, flags);
}
@@ -880,7 +885,7 @@ static int sunsab_console_setup(struct console *con, char *options)
{
struct uart_sunsab_port *up = &sunsab_ports[con->index];
unsigned long flags;
- int baud;
+ unsigned int baud, quot;
printk("Console: ttyS%d (SAB82532)\n",
(sunsab_reg.minor - 64) + con->index);
@@ -926,7 +931,8 @@ static int sunsab_console_setup(struct console *con, char *options)
SAB82532_IMR1_XPR;
writeb(up->interrupt_mask1, &up->regs->w.imr1);
- sunsab_convert_to_sab(up, con->cflag, 0, baud);
+ quot = uart_get_divisor(&up->port, baud);
+ sunsab_convert_to_sab(up, con->cflag, 0, baud, quot);
sunsab_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
spin_unlock_irqrestore(&up->port.lock, flags);
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 23d19d39432..ddc97c905e1 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1285,6 +1285,7 @@ static struct uart_driver sunsu_reg = {
static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up, int channel)
{
+ int quot, baud;
#ifdef CONFIG_SERIO
struct serio *serio;
#endif
@@ -1293,10 +1294,14 @@ static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up, int channel)
up->port.type = PORT_UNKNOWN;
up->port.uartclk = (SU_BASE_BAUD * 16);
- if (up->su_type == SU_PORT_KBD)
+ if (up->su_type == SU_PORT_KBD) {
up->cflag = B1200 | CS8 | CLOCAL | CREAD;
- else
+ baud = 1200;
+ } else {
up->cflag = B4800 | CS8 | CLOCAL | CREAD;
+ baud = 4800;
+ }
+ quot = up->port.uartclk / (16 * baud);
sunsu_autoconfig(up);
if (up->port.type == PORT_UNKNOWN)
@@ -1337,6 +1342,8 @@ static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up, int channel)
}
#endif
+ sunsu_change_speed(&up->port, up->cflag, 0, quot);
+
sunsu_startup(&up->port);
return 0;
}
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index 5538756f13b..d5863b8b56e 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -41,9 +41,6 @@
*
***************************************************************************/
-static char ixj_c_rcsid[] = "$Id: ixj.c,v 4.7 2001/08/13 06:19:33 craigs Exp $";
-static char ixj_c_revision[] = "$Revision: 4.7 $";
-
/*
* $Log: ixj.c,v $
*
@@ -6172,8 +6169,14 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
retval = j->serial;
break;
case IXJCTL_VERSION:
- if (copy_to_user(argp, ixj_c_revision, strlen(ixj_c_revision)))
- retval = -EFAULT;
+ {
+ char arg_str[100];
+ snprintf(arg_str, sizeof(arg_str),
+ "\nDriver version %i.%i.%i", IXJ_VER_MAJOR,
+ IXJ_VER_MINOR, IXJ_BLD_VER);
+ if (copy_to_user(argp, arg_str, strlen(arg_str)))
+ retval = -EFAULT;
+ }
break;
case PHONE_RING_CADENCE:
j->ring_cadence = arg;
@@ -7168,9 +7171,6 @@ static int ixj_get_status_proc(char *buf)
int cnt;
IXJ *j;
len = 0;
- len += sprintf(buf + len, "%s", ixj_c_rcsid);
- len += sprintf(buf + len, "\n%s", ixj_h_rcsid);
- len += sprintf(buf + len, "\n%s", ixjuser_h_rcsid);
len += sprintf(buf + len, "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, IXJ_VER_MINOR, IXJ_BLD_VER);
len += sprintf(buf + len, "\nsizeof IXJ struct %Zd bytes", sizeof(IXJ));
len += sprintf(buf + len, "\nsizeof DAA struct %Zd bytes", sizeof(DAA_REGS));
@@ -7790,7 +7790,7 @@ static int __init ixj_init(void)
if ((probe = ixj_probe_pci(&cnt)) < 0) {
return probe;
}
- printk("%s\n", ixj_c_rcsid);
+ printk(KERN_INFO "ixj driver initialized.\n");
create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL);
return probe;
}
diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h
index 143818a5612..51e3f7f6597 100644
--- a/drivers/telephony/ixj.h
+++ b/drivers/telephony/ixj.h
@@ -38,8 +38,6 @@
* TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*****************************************************************************/
-static char ixj_h_rcsid[] = "$Id: ixj.h,v 4.1 2001/08/04 14:49:27 craigs Exp $";
-
#define IXJ_VERSION 3031
#include <linux/version.h>
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index e12c5be1e0a..f50aaf25c98 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -431,7 +431,7 @@ nomem:
* (2) error, where io->status is a negative errno value. The number
* of io->bytes transferred before the error is usually less
* than requested, and can be nonzero.
- * (3) cancelation, a type of error with status -ECONNRESET that
+ * (3) cancellation, a type of error with status -ECONNRESET that
* is initiated by usb_sg_cancel().
*
* When this function returns, all memory allocated through usb_sg_init() or
@@ -1282,7 +1282,7 @@ static void release_interface(struct device *dev)
* bus rwsem; usb device driver probe() methods cannot use this routine.
*
* Returns zero on success, or else the status code returned by the
- * underlying call that failed. On succesful completion, each interface
+ * underlying call that failed. On successful completion, each interface
* in the original device configuration has been destroyed, and each one
* in the new configuration has been probed by all relevant usb device
* drivers currently known to the kernel.
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 16972159a57..0faf18d511d 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -121,7 +121,7 @@ struct urb * usb_get_urb(struct urb *urb)
* describing that request to the USB subsystem. Request completion will
* be indicated later, asynchronously, by calling the completion handler.
* The three types of completion are success, error, and unlink
- * (a software-induced fault, also called "request cancelation").
+ * (a software-induced fault, also called "request cancellation").
*
* URBs may be submitted in interrupt context.
*
@@ -170,7 +170,7 @@ struct urb * usb_get_urb(struct urb *urb)
* As of Linux 2.6, all USB endpoint transfer queues support depths greater
* than one. This was previously a HCD-specific behavior, except for ISO
* transfers. Non-isochronous endpoint queues are inactive during cleanup
- * after faults (transfer errors or cancelation).
+ * after faults (transfer errors or cancellation).
*
* Reserved Bandwidth Transfers:
*
@@ -395,7 +395,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags)
*
* This routine cancels an in-progress request. URBs complete only
* once per submission, and may be canceled only once per submission.
- * Successful cancelation means the requests's completion handler will
+ * Successful cancellation means the requests's completion handler will
* be called with a status code indicating that the request has been
* canceled (rather than any other code) and will quickly be removed
* from host controller data structures.
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index c231b4bef31..25cf7e9eccf 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -611,11 +611,10 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
- "MODALIAS=usb:v%04Xp%04Xdl%04Xdh%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
+ "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
le16_to_cpu(usb_dev->descriptor.idVendor),
le16_to_cpu(usb_dev->descriptor.idProduct),
le16_to_cpu(usb_dev->descriptor.bcdDevice),
- le16_to_cpu(usb_dev->descriptor.bcdDevice),
usb_dev->descriptor.bDeviceClass,
usb_dev->descriptor.bDeviceSubClass,
usb_dev->descriptor.bDeviceProtocol,
@@ -626,11 +625,10 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
} else {
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
- "MODALIAS=usb:v%04Xp%04Xdl%04Xdh%04Xdc%02Xdsc%02Xdp%02Xic*isc*ip*",
+ "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic*isc*ip*",
le16_to_cpu(usb_dev->descriptor.idVendor),
le16_to_cpu(usb_dev->descriptor.idProduct),
le16_to_cpu(usb_dev->descriptor.bcdDevice),
- le16_to_cpu(usb_dev->descriptor.bcdDevice),
usb_dev->descriptor.bDeviceClass,
usb_dev->descriptor.bDeviceSubClass,
usb_dev->descriptor.bDeviceProtocol))
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 3993156c2e8..3f783cbdc7c 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -569,7 +569,7 @@ static const struct usb_cdc_ether_desc ether_desc = {
/* include the status endpoint if we can, even where it's optional.
* use wMaxPacketSize big enough to fit CDC_NOTIFY_SPEED_CHANGE in one
- * packet, to simplify cancelation; and a big transfer interval, to
+ * packet, to simplify cancellation; and a big transfer interval, to
* waste less bandwidth.
*
* some drivers (like Linux 2.4 cdc-ether!) "need" it to exist even
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 2cff67ccce4..1e5e6ddef78 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -275,7 +275,7 @@ static const char *CHIP;
*
* After opening, configure non-control endpoints. Then use normal
* stream read() and write() requests; and maybe ioctl() to get more
- * precise FIFO status when recovering from cancelation.
+ * precise FIFO status when recovering from cancellation.
*/
static void epio_complete (struct usb_ep *ep, struct usb_request *req)
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index 0def9f70e88..df75ab65a5e 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -705,7 +705,7 @@ void nuke(struct lh7a40x_ep *ep, int status)
done(ep, req, status);
}
- /* Disable IRQ if EP is enabled (has decriptor) */
+ /* Disable IRQ if EP is enabled (has descriptor) */
if (ep->desc)
pio_irq_disable(ep_index(ep));
}
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index f1762ed6db6..4d591c764e3 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -240,7 +240,7 @@ struct gs_dev {
struct usb_ep *dev_notify_ep; /* address of notify endpoint */
struct usb_ep *dev_in_ep; /* address of in endpoint */
struct usb_ep *dev_out_ep; /* address of out endpoint */
- struct usb_endpoint_descriptor /* desciptor of notify ep */
+ struct usb_endpoint_descriptor /* descriptor of notify ep */
*dev_notify_ep_desc;
struct usb_endpoint_descriptor /* descriptor of in endpoint */
*dev_in_ep_desc;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 84d2b93aca3..bc69bd7aceb 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -346,6 +346,22 @@ ehci_reboot (struct notifier_block *self, unsigned long code, void *null)
return 0;
}
+static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
+{
+ unsigned port;
+
+ if (!HCS_PPC (ehci->hcs_params))
+ return;
+
+ ehci_dbg (ehci, "...power%s ports...\n", is_on ? "up" : "down");
+ for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; )
+ (void) ehci_hub_control(ehci_to_hcd(ehci),
+ is_on ? SetPortFeature : ClearPortFeature,
+ USB_PORT_FEAT_POWER,
+ port--, NULL, 0);
+ msleep(20);
+}
+
/* called by khubd or root hub init threads */
@@ -362,8 +378,10 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
dbg_hcs_params (ehci, "reset");
dbg_hcc_params (ehci, "reset");
+ /* cache this readonly data; minimize chip reads */
+ ehci->hcs_params = readl (&ehci->caps->hcs_params);
+
#ifdef CONFIG_PCI
- /* EHCI 0.96 and later may have "extended capabilities" */
if (hcd->self.controller->bus == &pci_bus_type) {
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
@@ -383,9 +401,30 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
break;
}
+ /* optional debug port, normally in the first BAR */
+ temp = pci_find_capability (pdev, 0x0a);
+ if (temp) {
+ pci_read_config_dword(pdev, temp, &temp);
+ temp >>= 16;
+ if ((temp & (3 << 13)) == (1 << 13)) {
+ temp &= 0x1fff;
+ ehci->debug = hcd->regs + temp;
+ temp = readl (&ehci->debug->control);
+ ehci_info (ehci, "debug port %d%s\n",
+ HCS_DEBUG_PORT(ehci->hcs_params),
+ (temp & DBGP_ENABLED)
+ ? " IN USE"
+ : "");
+ if (!(temp & DBGP_ENABLED))
+ ehci->debug = NULL;
+ }
+ }
+
temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
} else
temp = 0;
+
+ /* EHCI 0.96 and later may have "extended capabilities" */
while (temp && count--) {
u32 cap;
@@ -414,8 +453,7 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
ehci_reset (ehci);
#endif
- /* cache this readonly data; minimize PCI reads */
- ehci->hcs_params = readl (&ehci->caps->hcs_params);
+ ehci_port_power (ehci, 0);
/* at least the Genesys GL880S needs fixup here */
temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
@@ -657,16 +695,11 @@ done2:
static void ehci_stop (struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
- u8 rh_ports, port;
ehci_dbg (ehci, "stop\n");
/* Turn off port power on all root hub ports. */
- rh_ports = HCS_N_PORTS (ehci->hcs_params);
- for (port = 1; port <= rh_ports; port++)
- (void) ehci_hub_control(hcd,
- ClearPortFeature, USB_PORT_FEAT_POWER,
- port, NULL, 0);
+ ehci_port_power (ehci, 0);
/* no more interrupts ... */
del_timer_sync (&ehci->watchdog);
@@ -748,7 +781,6 @@ static int ehci_resume (struct usb_hcd *hcd)
unsigned port;
struct usb_device *root = hcd->self.root_hub;
int retval = -EINVAL;
- int powerup = 0;
// maybe restore (PCI) FLADJ
@@ -766,8 +798,6 @@ static int ehci_resume (struct usb_hcd *hcd)
up (&hcd->self.root_hub->serialize);
break;
}
- if ((status & PORT_POWER) == 0)
- powerup = 1;
if (!root->children [port])
continue;
dbg_port (ehci, __FUNCTION__, port + 1, status);
@@ -794,16 +824,9 @@ static int ehci_resume (struct usb_hcd *hcd)
retval = ehci_start (hcd);
/* here we "know" root ports should always stay powered;
- * but some controllers may lost all power.
+ * but some controllers may lose all power.
*/
- if (powerup) {
- ehci_dbg (ehci, "...powerup ports...\n");
- for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; )
- (void) ehci_hub_control(hcd,
- SetPortFeature, USB_PORT_FEAT_POWER,
- port--, NULL, 0);
- msleep(20);
- }
+ ehci_port_power (ehci, 1);
}
return retval;
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 2373537fabe..02fefab3501 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -281,6 +281,8 @@ ehci_hub_descriptor (
temp = 0x0008; /* per-port overcurrent reporting */
if (HCS_PPC (ehci->hcs_params))
temp |= 0x0001; /* per-port power control */
+ else
+ temp |= 0x0002; /* no power switching */
#if 0
// re-enable when we support USB_PORT_FEAT_INDICATOR below.
if (HCS_INDICATOR (ehci->hcs_params))
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index e763a8399a7..4df49823175 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -47,6 +47,12 @@ struct ehci_stats {
#define EHCI_MAX_ROOT_PORTS 15 /* see HCS_N_PORTS */
struct ehci_hcd { /* one per controller */
+ /* glue to PCI and HCD framework */
+ struct ehci_caps __iomem *caps;
+ struct ehci_regs __iomem *regs;
+ struct ehci_dbg_port __iomem *debug;
+
+ __u32 hcs_params; /* cached register copy */
spinlock_t lock;
/* async schedule support */
@@ -84,11 +90,6 @@ struct ehci_hcd { /* one per controller */
unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */
- /* glue to PCI and HCD framework */
- struct ehci_caps __iomem *caps;
- struct ehci_regs __iomem *regs;
- __u32 hcs_params; /* cached register copy */
-
/* irq statistics */
#ifdef EHCI_STATS
struct ehci_stats stats;
@@ -165,7 +166,7 @@ struct ehci_caps {
/* these fields are specified as 8 and 16 bit registers,
* but some hosts can't perform 8 or 16 bit PCI accesses.
*/
- u32 hc_capbase;
+ u32 hc_capbase;
#define HC_LENGTH(p) (((p)>>00)&0x00ff) /* bits 7:0 */
#define HC_VERSION(p) (((p)>>16)&0xffff) /* bits 31:16 */
u32 hcs_params; /* HCSPARAMS - offset 0x4 */
@@ -273,7 +274,7 @@ struct ehci_dbg_port {
#define DBGP_ENABLED (1<<28)
#define DBGP_DONE (1<<16)
#define DBGP_INUSE (1<<10)
-#define DBGP_ERRCODE(x) (((x)>>7)&0x0f)
+#define DBGP_ERRCODE(x) (((x)>>7)&0x07)
# define DBGP_ERR_BAD 1
# define DBGP_ERR_SIGNAL 2
#define DBGP_ERROR (1<<6)
@@ -282,11 +283,11 @@ struct ehci_dbg_port {
#define DBGP_LEN(x) (((x)>>0)&0x0f)
u32 pids;
#define DBGP_PID_GET(x) (((x)>>16)&0xff)
-#define DBGP_PID_SET(data,tok) (((data)<<8)|(tok));
+#define DBGP_PID_SET(data,tok) (((data)<<8)|(tok))
u32 data03;
u32 data47;
u32 address;
-#define DBGP_EPADDR(dev,ep) (((dev)<<8)|(ep));
+#define DBGP_EPADDR(dev,ep) (((dev)<<8)|(ep))
} __attribute__ ((packed));
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index 376f8a034f6..d9883d774d3 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -4329,7 +4329,7 @@ static int __init etrax_usb_hc_init(void)
bus->bus_name="ETRAX 100LX";
bus->hcpriv = hc;
- /* Initalize RH to the default address.
+ /* Initialize RH to the default address.
And make sure that we have no status change indication */
hc->rh.numports = 2; /* The RH has two ports */
hc->rh.devnum = 1;
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index d309e292198..a374b769207 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -134,7 +134,7 @@ static void port_power(struct sl811 *sl811, int is_on)
/* This is a PIO-only HCD. Queueing appends URBs to the endpoint's queue,
* and may start I/O. Endpoint queues are scanned during completion irq
- * handlers (one per packet: ACK, NAK, faults, etc) and urb cancelation.
+ * handlers (one per packet: ACK, NAK, faults, etc) and urb cancellation.
*
* Using an external DMA engine to copy a packet at a time could work,
* though setup/teardown costs may be too big to make it worthwhile.
@@ -738,7 +738,7 @@ retry:
}
#endif
- /* port status seems wierd until after reset, so
+ /* port status seems weird until after reset, so
* force the reset and make khubd clean up later.
*/
sl811->port1 |= (1 << USB_PORT_FEAT_C_CONNECTION)
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
index 5791723e608..a330a4b50e1 100644
--- a/drivers/usb/image/mdc800.c
+++ b/drivers/usb/image/mdc800.c
@@ -23,7 +23,7 @@
*
*
* The driver brings the USB functions of the MDC800 to Linux.
- * To use the Camera you must support the USB Protocoll of the camera
+ * To use the Camera you must support the USB Protocol of the camera
* to the Kernel Node.
* The Driver uses a misc device Node. Create it with :
* mknod /dev/mustek c 180 32
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index cab89a970c7..7d21a4f5c42 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -335,7 +335,7 @@ static int mts_scsi_abort (Scsi_Cmnd *srb)
mts_urb_abort(desc);
- return FAILURE;
+ return FAILED;
}
static int mts_scsi_host_reset (Scsi_Cmnd *srb)
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
index 2d76be62f4e..94ce2a9ad50 100644
--- a/drivers/usb/input/aiptek.c
+++ b/drivers/usb/input/aiptek.c
@@ -386,7 +386,7 @@ static int aiptek_convert_from_2s_complement(unsigned char c)
* convention above.) I therefore have taken over REL_MISC and ABS_MISC
* (for relative and absolute reports, respectively) for communicating
* Proximity. Why two events? I thought it interesting to know if the
- * Proximity event occured while the tablet was in absolute or relative
+ * Proximity event occurred while the tablet was in absolute or relative
* mode.
*
* Other tablets use the notion of a certain minimum stylus pressure
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
index 355add5c29f..860df26323b 100644
--- a/drivers/usb/input/ati_remote.c
+++ b/drivers/usb/input/ati_remote.c
@@ -619,7 +619,7 @@ static void ati_remote_delete(struct ati_remote *ati_remote)
if (ati_remote->outbuf)
usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
- ati_remote->inbuf, ati_remote->outbuf_dma);
+ ati_remote->outbuf, ati_remote->outbuf_dma);
if (ati_remote->irq_urb)
usb_free_urb(ati_remote->irq_urb);
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
index 6b45a66d58c..ab1a2a30ce7 100644
--- a/drivers/usb/input/mtouchusb.c
+++ b/drivers/usb/input/mtouchusb.c
@@ -32,7 +32,7 @@
* Changed reset from standard USB dev reset to vendor reset
* Changed data sent to host from compensated to raw coordinates
* Eliminated vendor/product module params
- * Performed multiple successfull tests with an EXII-5010UC
+ * Performed multiple successful tests with an EXII-5010UC
*
* 1.5 02/27/2005 ddstreet@ieee.org
* Added module parameter to select raw or hw-calibrated coordinate reporting
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
index 01514b0551b..7038fb9d1ce 100644
--- a/drivers/usb/input/usbkbd.c
+++ b/drivers/usb/input/usbkbd.c
@@ -133,7 +133,8 @@ resubmit:
kbd->usbdev->devpath, i);
}
-int usb_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+static int usb_kbd_event(struct input_dev *dev, unsigned int type,
+ unsigned int code, int value)
{
struct usb_kbd *kbd = dev->private;
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
index d6051822416..036c485d1d1 100644
--- a/drivers/usb/media/ov511.c
+++ b/drivers/usb/media/ov511.c
@@ -5041,7 +5041,7 @@ ov6xx0_configure(struct usb_ov511 *ov)
{ OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */
// { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */
{ OV511_I2C_BUS, 0x2d, 0x99 },
- { OV511_I2C_BUS, 0x33, 0xa0 }, /* Color Procesing Parameter */
+ { OV511_I2C_BUS, 0x33, 0xa0 }, /* Color Processing Parameter */
{ OV511_I2C_BUS, 0x34, 0xd2 }, /* Max A/D range */
{ OV511_I2C_BUS, 0x38, 0x8b },
{ OV511_I2C_BUS, 0x39, 0x40 },
diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c
index 26aa914bc54..42ec468d52d 100644
--- a/drivers/usb/media/pwc/pwc-ctrl.c
+++ b/drivers/usb/media/pwc/pwc-ctrl.c
@@ -418,6 +418,44 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
+static void pwc_set_image_buffer_size(struct pwc_device *pdev)
+{
+ int i, factor = 0, filler = 0;
+
+ /* for PALETTE_YUV420P */
+ switch(pdev->vpalette)
+ {
+ case VIDEO_PALETTE_YUV420P:
+ factor = 6;
+ filler = 128;
+ break;
+ case VIDEO_PALETTE_RAW:
+ factor = 6; /* can be uncompressed YUV420P */
+ filler = 0;
+ break;
+ }
+
+ /* Set sizes in bytes */
+ pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
+ pdev->view.size = pdev->view.x * pdev->view.y * factor / 4;
+
+ /* Align offset, or you'll get some very weird results in
+ YUV420 mode... x must be multiple of 4 (to get the Y's in
+ place), and y even (or you'll mixup U & V). This is less of a
+ problem for YUV420P.
+ */
+ pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
+ pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
+
+ /* Fill buffers with gray or black */
+ for (i = 0; i < MAX_IMAGES; i++) {
+ if (pdev->image_ptr[i] != NULL)
+ memset(pdev->image_ptr[i], filler, pdev->view.size);
+ }
+}
+
+
+
/**
@pdev: device structure
@width: viewport width
@@ -475,44 +513,6 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame
}
-void pwc_set_image_buffer_size(struct pwc_device *pdev)
-{
- int i, factor = 0, filler = 0;
-
- /* for PALETTE_YUV420P */
- switch(pdev->vpalette)
- {
- case VIDEO_PALETTE_YUV420P:
- factor = 6;
- filler = 128;
- break;
- case VIDEO_PALETTE_RAW:
- factor = 6; /* can be uncompressed YUV420P */
- filler = 0;
- break;
- }
-
- /* Set sizes in bytes */
- pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
- pdev->view.size = pdev->view.x * pdev->view.y * factor / 4;
-
- /* Align offset, or you'll get some very weird results in
- YUV420 mode... x must be multiple of 4 (to get the Y's in
- place), and y even (or you'll mixup U & V). This is less of a
- problem for YUV420P.
- */
- pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
- pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
-
- /* Fill buffers with gray or black */
- for (i = 0; i < MAX_IMAGES; i++) {
- if (pdev->image_ptr[i] != NULL)
- memset(pdev->image_ptr[i], filler, pdev->view.size);
- }
-}
-
-
-
/* BRIGHTNESS */
int pwc_get_brightness(struct pwc_device *pdev)
@@ -949,7 +949,7 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
return SendControlMsg(SET_STATUS_CTL, LED_FORMATTER, 2);
}
-int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
+static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
{
unsigned char buf[2];
int ret;
@@ -1100,7 +1100,7 @@ static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
unsigned char buf[4];
/* set new relative angle; angles are expressed in degrees * 100,
- but cam as .5 degree resolution, hence devide by 200. Also
+ but cam as .5 degree resolution, hence divide by 200. Also
the angle must be multiplied by 64 before it's send to
the cam (??)
*/
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c
index 100a5a4f03a..cca47f480a8 100644
--- a/drivers/usb/media/pwc/pwc-if.c
+++ b/drivers/usb/media/pwc/pwc-if.c
@@ -129,7 +129,7 @@ static int default_mbufs = 2; /* Default number of mmap() buffers */
int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX;
static int power_save = 0;
static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */
- int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */
+static int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */
static struct {
int type;
char serial_number[30];
@@ -272,7 +272,7 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
return -ENXIO;
}
#endif
- /* Allocate Isochronuous pipe buffers */
+ /* Allocate Isochronous pipe buffers */
for (i = 0; i < MAX_ISO_BUFS; i++) {
if (pdev->sbuf[i].data == NULL) {
kbuf = kmalloc(ISO_BUFFER_SIZE, GFP_KERNEL);
@@ -322,7 +322,7 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
case 730:
case 740:
case 750:
- Trace(TRACE_MEMORY,"private_data(%Zd)\n",sizeof(struct pwc_dec23_private));
+ Trace(TRACE_MEMORY,"private_data(%zu)\n",sizeof(struct pwc_dec23_private));
kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); /* Timon & Kiara */
break;
case 645:
@@ -850,7 +850,7 @@ static int pwc_isoc_init(struct pwc_device *pdev)
if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
Err("Failed to find packet size for video endpoint in current alternate setting.\n");
- return -ENFILE; /* Odd error, that should be noticable */
+ return -ENFILE; /* Odd error, that should be noticeable */
}
/* Set alternate interface */
@@ -1179,7 +1179,7 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf,
DECLARE_WAITQUEUE(wait, current);
int bytes_to_read;
- Trace(TRACE_READ, "video_read(0x%p, %p, %Zd) called.\n", vdev, buf, count);
+ Trace(TRACE_READ, "video_read(0x%p, %p, %zu) called.\n", vdev, buf, count);
if (vdev == NULL)
return -EFAULT;
pdev = vdev->priv;
@@ -2128,7 +2128,7 @@ static int __init usb_pwc_init(void)
if (leds[1] >= 0)
led_off = leds[1];
- /* Big device node whoopla. Basicly, it allows you to assign a
+ /* Big device node whoopla. Basically, it allows you to assign a
device node (/dev/videoX) to a camera, based on its type
& serial number. The format is [type[.serialnumber]:]node.
diff --git a/drivers/usb/media/pwc/pwc-ioctl.h b/drivers/usb/media/pwc/pwc-ioctl.h
index 65805eaa9a1..5f9cb08bc02 100644
--- a/drivers/usb/media/pwc/pwc-ioctl.h
+++ b/drivers/usb/media/pwc/pwc-ioctl.h
@@ -75,7 +75,7 @@
#define PWC_FPS_SNAPSHOT 0x00400000
-/* structure for transfering x & y coordinates */
+/* structure for transferring x & y coordinates */
struct pwc_coord
{
int x, y; /* guess what */
diff --git a/drivers/usb/media/pwc/pwc.h b/drivers/usb/media/pwc/pwc.h
index 53b516d29cf..267869dab18 100644
--- a/drivers/usb/media/pwc/pwc.h
+++ b/drivers/usb/media/pwc/pwc.h
@@ -226,9 +226,8 @@ struct pwc_device
extern "C" {
#endif
-/* Global variables */
+/* Global variable */
extern int pwc_trace;
-extern int pwc_preferred_compression;
/** functions in pwc-if.c */
int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot);
@@ -243,8 +242,6 @@ void pwc_construct(struct pwc_device *pdev);
/** Functions in pwc-ctrl.c */
/* Request a certain video mode. Returns < 0 if not possible */
extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot);
-/* Calculate the number of bytes per image (not frame) */
-extern void pwc_set_image_buffer_size(struct pwc_device *pdev);
/* Various controls; should be obvious. Value 0..65535, or < 0 on error */
extern int pwc_get_brightness(struct pwc_device *pdev);
@@ -256,7 +253,6 @@ extern int pwc_set_gamma(struct pwc_device *pdev, int value);
extern int pwc_get_saturation(struct pwc_device *pdev);
extern int pwc_set_saturation(struct pwc_device *pdev, int value);
extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
-extern int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value);
extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);
/* Power down or up the camera; not supported by all models */
diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c
index 898401cf7dc..31d57400d5b 100644
--- a/drivers/usb/media/sn9c102_core.c
+++ b/drivers/usb/media/sn9c102_core.c
@@ -429,7 +429,7 @@ sn9c102_i2c_try_read(struct sn9c102_device* cam,
}
-int
+static int
sn9c102_i2c_try_write(struct sn9c102_device* cam,
struct sn9c102_sensor* sensor, u8 address, u8 value)
{
@@ -785,7 +785,7 @@ static int sn9c102_stop_transfer(struct sn9c102_device* cam)
}
-int sn9c102_stream_interrupt(struct sn9c102_device* cam)
+static int sn9c102_stream_interrupt(struct sn9c102_device* cam)
{
int err = 0;
diff --git a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h
index 16f7483559f..6a7adebcb4b 100644
--- a/drivers/usb/media/sn9c102_sensor.h
+++ b/drivers/usb/media/sn9c102_sensor.h
@@ -145,8 +145,6 @@ static const struct usb_device_id sn9c102_id_table[] = { \
*/
/* The "try" I2C I/O versions are used when probing the sensor */
-extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*,
- u8 address, u8 value);
extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
u8 address);
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index dd4580cb57e..7d06105763d 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -859,7 +859,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
info ("udev is NULL.");
}
- /* allocate memory for our device state and intialize it */
+ /* allocate memory for our device state and initialize it */
dev = kmalloc (sizeof(struct lego_usb_tower), GFP_KERNEL);
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index 57b82d53a94..2fd12264fd5 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -983,7 +983,7 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
msgcount++;
if (msgcount < 500)
printk(KERN_ERR
- "sisusbvga[%d]: Wrote %Zd of "
+ "sisusbvga[%d]: Wrote %zd of "
"%d bytes, error %d\n",
sisusb->minor, *bytes_written,
length, ret);
@@ -3105,6 +3105,7 @@ static void sisusb_disconnect(struct usb_interface *intf)
static struct usb_device_id sisusb_table [] = {
{ USB_DEVICE(0x0711, 0x0900) },
{ USB_DEVICE(0x182d, 0x021c) },
+ { USB_DEVICE(0x182d, 0x0269) },
{ }
};
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
index a02be795d63..d976790312a 100644
--- a/drivers/usb/net/pegasus.c
+++ b/drivers/usb/net/pegasus.c
@@ -1388,11 +1388,11 @@ static int pegasus_resume (struct usb_interface *intf)
if (netif_running(pegasus->net)) {
pegasus->rx_urb->status = 0;
pegasus->rx_urb->actual_length = 0;
- read_bulk_callback(pegasus->rx_urb, 0);
+ read_bulk_callback(pegasus->rx_urb, NULL);
pegasus->intr_urb->status = 0;
pegasus->intr_urb->actual_length = 0;
- intr_callback(pegasus->intr_urb, 0);
+ intr_callback(pegasus->intr_urb, NULL);
queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check,
CARRIER_CHECK_DELAY);
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index bbaef047d53..f6bc6b3b333 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -1,6 +1,6 @@
/*
* USB Networking Links
- * Copyright (C) 2000-2003 by David Brownell <dbrownell@users.sourceforge.net>
+ * Copyright (C) 2000-2005 by David Brownell <dbrownell@users.sourceforge.net>
* Copyright (C) 2002 Pavel Machek <pavel@ucw.cz>
* Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
* Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
@@ -210,6 +210,7 @@ struct usbnet {
# define EVENT_RX_HALT 1
# define EVENT_RX_MEMORY 2
# define EVENT_STS_SPLIT 3
+# define EVENT_LINK_RESET 4
};
// device-specific info used by the driver
@@ -243,6 +244,9 @@ struct driver_info {
/* for status polling */
void (*status)(struct usbnet *, struct urb *);
+ /* link reset handling, called from defer_kevent */
+ int (*link_reset)(struct usbnet *);
+
/* fixup rx packet (strip framing) */
int (*rx_fixup)(struct usbnet *dev, struct sk_buff *skb);
@@ -304,6 +308,7 @@ static void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *);
static u32 usbnet_get_link (struct net_device *);
static u32 usbnet_get_msglevel (struct net_device *);
static void usbnet_set_msglevel (struct net_device *, u32);
+static void defer_kevent (struct usbnet *, int);
/* mostly for PDA style devices, which are always connected if present */
static int always_connected (struct usbnet *dev)
@@ -426,7 +431,7 @@ static void skb_return (struct usbnet *dev, struct sk_buff *skb)
dev->stats.rx_bytes += skb->len;
if (netif_msg_rx_status (dev))
- devdbg (dev, "< rx, len %zd, type 0x%x",
+ devdbg (dev, "< rx, len %zu, type 0x%x",
skb->len + sizeof (struct ethhdr), skb->protocol);
memset (skb->cb, 0, sizeof (struct skb_data));
status = netif_rx (skb);
@@ -501,6 +506,7 @@ static const struct driver_info an2720_info = {
#define AX_CMD_WRITE_MULTI_FILTER 0x16
#define AX_CMD_READ_NODE_ID 0x17
#define AX_CMD_READ_PHY_ID 0x19
+#define AX_CMD_READ_MEDIUM_STATUS 0x1a
#define AX_CMD_WRITE_MEDIUM_MODE 0x1b
#define AX_CMD_READ_MONITOR_MODE 0x1c
#define AX_CMD_WRITE_MONITOR_MODE 0x1d
@@ -515,11 +521,14 @@ static const struct driver_info an2720_info = {
#define AX_MONITOR_MAGIC 0x04
#define AX_MONITOR_HSFS 0x10
+/* AX88172 Medium Status Register values */
+#define AX_MEDIUM_FULL_DUPLEX 0x02
+#define AX_MEDIUM_TX_ABORT_ALLOW 0x04
+#define AX_MEDIUM_FLOW_CONTROL_EN 0x10
+
#define AX_MCAST_FILTER_SIZE 8
#define AX_MAX_MCAST 64
-#define AX_INTERRUPT_BUFSIZE 8
-
#define AX_EEPROM_LEN 0x40
#define AX_SWRESET_CLEAR 0x00
@@ -535,15 +544,33 @@ static const struct driver_info an2720_info = {
#define AX88772_IPG1_DEFAULT 0x0c
#define AX88772_IPG2_DEFAULT 0x12
+#define AX88772_MEDIUM_FULL_DUPLEX 0x0002
+#define AX88772_MEDIUM_RESERVED 0x0004
+#define AX88772_MEDIUM_RX_FC_ENABLE 0x0010
+#define AX88772_MEDIUM_TX_FC_ENABLE 0x0020
+#define AX88772_MEDIUM_PAUSE_FORMAT 0x0080
+#define AX88772_MEDIUM_RX_ENABLE 0x0100
+#define AX88772_MEDIUM_100MB 0x0200
+#define AX88772_MEDIUM_DEFAULT \
+ (AX88772_MEDIUM_FULL_DUPLEX | AX88772_MEDIUM_RX_FC_ENABLE | \
+ AX88772_MEDIUM_TX_FC_ENABLE | AX88772_MEDIUM_100MB | \
+ AX88772_MEDIUM_RESERVED | AX88772_MEDIUM_RX_ENABLE )
+
#define AX_EEPROM_MAGIC 0xdeadbeef
/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
struct ax8817x_data {
u8 multi_filter[AX_MCAST_FILTER_SIZE];
- struct urb *int_urb;
- u8 *int_buf;
};
+struct ax88172_int_data {
+ u16 res1;
+ u8 link;
+ u16 res2;
+ u8 status;
+ u16 res3;
+} __attribute__ ((packed));
+
static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
u16 size, void *data)
{
@@ -586,25 +613,23 @@ static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
usb_free_urb(urb);
}
-static void ax8817x_interrupt_complete(struct urb *urb, struct pt_regs *regs)
+static void ax8817x_status(struct usbnet *dev, struct urb *urb)
{
- struct usbnet *dev = (struct usbnet *)urb->context;
- struct ax8817x_data *data = (struct ax8817x_data *)&dev->data;
+ struct ax88172_int_data *event;
int link;
- if (urb->status < 0) {
- devdbg(dev,"ax8817x_interrupt_complete() failed with %d",
- urb->status);
- } else {
- link = data->int_buf[2] & 0x01;
- if (netif_carrier_ok(dev->net) != link) {
- if (link)
- netif_carrier_on(dev->net);
- else
- netif_carrier_off(dev->net);
- devdbg(dev, "ax8817x - Link Status is: %d", link);
- }
- usb_submit_urb(data->int_urb, GFP_ATOMIC);
+ if (urb->actual_length < 8)
+ return;
+
+ event = urb->transfer_buffer;
+ link = event->link & 0x01;
+ if (netif_carrier_ok(dev->net) != link) {
+ if (link) {
+ netif_carrier_on(dev->net);
+ defer_kevent (dev, EVENT_LINK_RESET );
+ } else
+ netif_carrier_off(dev->net);
+ devdbg(dev, "ax8817x - Link Status is: %d", link);
}
}
@@ -711,6 +736,20 @@ static void ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, i
ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
}
+static int ax88172_link_reset(struct usbnet *dev)
+{
+ u16 lpa;
+ u8 mode;
+
+ mode = AX_MEDIUM_TX_ABORT_ALLOW | AX_MEDIUM_FLOW_CONTROL_EN;
+ lpa = ax8817x_mdio_read(dev->net, dev->mii.phy_id, MII_LPA);
+ if (lpa & LPA_DUPLEX)
+ mode |= AX_MEDIUM_FULL_DUPLEX;
+ ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
+
+ return 0;
+}
+
static void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = netdev_priv(net);
@@ -824,35 +863,13 @@ static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf)
void *buf;
int i;
unsigned long gpio_bits = dev->driver_info->data;
- struct ax8817x_data *data = (struct ax8817x_data *)dev->data;
get_endpoints(dev,intf);
- if ((data->int_urb = usb_alloc_urb (0, GFP_KERNEL)) == NULL) {
- dbg ("%s: cannot allocate interrupt URB",
- dev->net->name);
- ret = -ENOMEM;
- goto out1;
- }
-
- if ((data->int_buf = kmalloc(AX_INTERRUPT_BUFSIZE, GFP_KERNEL)) == NULL) {
- dbg ("%s: cannot allocate memory for interrupt buffer",
- dev->net->name);
- ret = -ENOMEM;
- goto out1;
- }
- memset(data->int_buf, 0, AX_INTERRUPT_BUFSIZE);
-
- usb_fill_int_urb (data->int_urb, dev->udev,
- usb_rcvintpipe (dev->udev, 1),
- data->int_buf, AX_INTERRUPT_BUFSIZE,
- ax8817x_interrupt_complete, dev,
- dev->udev->speed == USB_SPEED_HIGH ? 8 : 100);
-
buf = kmalloc(ETH_ALEN, GFP_KERNEL);
if(!buf) {
ret = -ENOMEM;
- goto out2;
+ goto out1;
}
/* Toggle the GPIOs in a manufacturer/model specific way */
@@ -860,32 +877,32 @@ static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf)
if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
(gpio_bits >> (i * 8)) & 0xff, 0, 0,
buf)) < 0)
- goto out3;
+ goto out2;
msleep(5);
}
if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf)) < 0) {
dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret);
- goto out3;
+ goto out2;
}
/* Get the MAC address */
memset(buf, 0, ETH_ALEN);
if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, 6, buf)) < 0) {
dbg("read AX_CMD_READ_NODE_ID failed: %d", ret);
- goto out3;
+ goto out2;
}
memcpy(dev->net->dev_addr, buf, ETH_ALEN);
/* Get the PHY id */
if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf)) < 0) {
dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret);
- goto out3;
+ goto out2;
} else if (ret < 2) {
/* this should always return 2 bytes */
dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", ret);
ret = -EIO;
- goto out3;
+ goto out2;
}
/* Initialize MII structure */
@@ -899,36 +916,18 @@ static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf)
dev->net->set_multicast_list = ax8817x_set_multicast;
dev->net->ethtool_ops = &ax8817x_ethtool_ops;
- ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR,
- cpu_to_le16(BMCR_RESET));
+ ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
- cpu_to_le16(ADVERTISE_ALL | ADVERTISE_CSMA | 0x0400));
+ ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
mii_nway_restart(&dev->mii);
- if((ret = usb_submit_urb(data->int_urb, GFP_KERNEL)) < 0) {
- dbg("Failed to submit interrupt URB: %02x", ret);
- goto out2;
- }
-
return 0;
-out3:
- kfree(buf);
out2:
- kfree(data->int_buf);
+ kfree(buf);
out1:
- usb_free_urb(data->int_urb);
return ret;
}
-static void ax8817x_unbind(struct usbnet *dev, struct usb_interface *intf)
-{
- struct ax8817x_data *data = (struct ax8817x_data *)dev->data;
-
- usb_kill_urb(data->int_urb);
- usb_free_urb(data->int_urb);
- kfree(data->int_buf);
-}
-
static struct ethtool_ops ax88772_ethtool_ops = {
.get_drvinfo = ax8817x_get_drvinfo,
.get_link = ethtool_op_get_link,
@@ -946,64 +945,44 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
{
int ret;
void *buf;
- struct ax8817x_data *data = (struct ax8817x_data *)dev->data;
get_endpoints(dev,intf);
- if ((data->int_urb = usb_alloc_urb (0, GFP_KERNEL)) == 0) {
- dbg ("Cannot allocate interrupt URB");
- ret = -ENOMEM;
- goto out1;
- }
-
- if ((data->int_buf = kmalloc(AX_INTERRUPT_BUFSIZE, GFP_KERNEL)) == NULL) {
- dbg ("Cannot allocate memory for interrupt buffer");
- ret = -ENOMEM;
- goto out1;
- }
- memset(data->int_buf, 0, AX_INTERRUPT_BUFSIZE);
-
- usb_fill_int_urb (data->int_urb, dev->udev,
- usb_rcvintpipe (dev->udev, 1),
- data->int_buf, AX_INTERRUPT_BUFSIZE,
- ax8817x_interrupt_complete, dev,
- dev->udev->speed == USB_SPEED_HIGH ? 8 : 100);
-
buf = kmalloc(6, GFP_KERNEL);
if(!buf) {
dbg ("Cannot allocate memory for buffer");
ret = -ENOMEM;
- goto out2;
+ goto out1;
}
if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
0x00B0, 0, 0, buf)) < 0)
- goto out3;
+ goto out2;
msleep(5);
if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0x0001, 0, 0, buf)) < 0) {
dbg("Select PHY #1 failed: %d", ret);
- goto out3;
+ goto out2;
}
if ((ret =
ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPPD, 0, 0, buf)) < 0) {
dbg("Failed to power down internal PHY: %d", ret);
- goto out3;
+ goto out2;
}
msleep(150);
if ((ret =
ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_CLEAR, 0, 0, buf)) < 0) {
dbg("Failed to perform software reset: %d", ret);
- goto out3;
+ goto out2;
}
msleep(150);
if ((ret =
ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPRL | AX_SWRESET_PRL, 0, 0, buf)) < 0) {
dbg("Failed to set Internal/External PHY reset control: %d", ret);
- goto out3;
+ goto out2;
}
msleep(150);
@@ -1011,27 +990,27 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0000, 0, 0,
buf)) < 0) {
dbg("Failed to reset RX_CTL: %d", ret);
- goto out3;
+ goto out2;
}
/* Get the MAC address */
memset(buf, 0, ETH_ALEN);
if ((ret = ax8817x_read_cmd(dev, AX88772_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf)) < 0) {
dbg("Failed to read MAC address: %d", ret);
- goto out3;
+ goto out2;
}
memcpy(dev->net->dev_addr, buf, ETH_ALEN);
if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, buf)) < 0) {
dbg("Enabling software MII failed: %d", ret);
- goto out3;
+ goto out2;
}
if (((ret =
ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, 0x0010, 2, 2, buf)) < 0)
|| (*((u16 *)buf) != 0x003b)) {
dbg("Read PHY register 2 must be 0x3b00: %d", ret);
- goto out3;
+ goto out2;
}
/* Initialize MII structure */
@@ -1044,26 +1023,26 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
/* Get the PHY id */
if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf)) < 0) {
dbg("Error reading PHY ID: %02x", ret);
- goto out3;
+ goto out2;
} else if (ret < 2) {
/* this should always return 2 bytes */
dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x",
ret);
ret = -EIO;
- goto out3;
+ goto out2;
}
dev->mii.phy_id = *((u8 *)buf + 1);
if ((ret =
ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_PRL, 0, 0, buf)) < 0) {
dbg("Set external PHY reset pin level: %d", ret);
- goto out3;
+ goto out2;
}
msleep(150);
if ((ret =
ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPRL | AX_SWRESET_PRL, 0, 0, buf)) < 0) {
dbg("Set Internal/External PHY reset control: %d", ret);
- goto out3;
+ goto out2;
}
msleep(150);
@@ -1071,25 +1050,24 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
dev->net->set_multicast_list = ax8817x_set_multicast;
dev->net->ethtool_ops = &ax88772_ethtool_ops;
- ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR,
- cpu_to_le16(BMCR_RESET));
+ ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
- cpu_to_le16(ADVERTISE_ALL | ADVERTISE_CSMA));
+ ADVERTISE_ALL | ADVERTISE_CSMA);
mii_nway_restart(&dev->mii);
- if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, 0x0336, 0, 0, buf)) < 0) {
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, AX88772_MEDIUM_DEFAULT, 0, 0, buf)) < 0) {
dbg("Write medium mode register: %d", ret);
- goto out3;
+ goto out2;
}
if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0, AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,AX88772_IPG2_DEFAULT, 0, buf)) < 0) {
dbg("Write IPG,IPG1,IPG2 failed: %d", ret);
- goto out3;
+ goto out2;
}
if ((ret =
ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) {
dbg("Failed to set hardware MII: %02x", ret);
- goto out3;
+ goto out2;
}
/* Set RX_CTL to default values with 2k buffer, and enable cactus */
@@ -1097,25 +1075,16 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0088, 0, 0,
buf)) < 0) {
dbg("Reset RX_CTL failed: %d", ret);
- goto out3;
- }
-
- if((ret = usb_submit_urb(data->int_urb, GFP_KERNEL)) < 0) {
- dbg("Failed to submit interrupt URB: %02x", ret);
- goto out3;
+ goto out2;
}
kfree(buf);
return 0;
-out3:
- kfree(buf);
out2:
- kfree(data->int_buf);
+ kfree(buf);
out1:
- usb_free_urb(data->int_urb);
-
return ret;
}
@@ -1213,10 +1182,29 @@ static struct sk_buff *ax88772_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
return skb;
}
+static int ax88772_link_reset(struct usbnet *dev)
+{
+ u16 lpa;
+ u16 mode;
+
+ mode = AX88772_MEDIUM_DEFAULT;
+ lpa = ax8817x_mdio_read(dev->net, dev->mii.phy_id, MII_LPA);
+
+ if ((lpa & LPA_DUPLEX) == 0)
+ mode &= ~AX88772_MEDIUM_FULL_DUPLEX;
+ if ((lpa & LPA_100) == 0)
+ mode &= ~AX88772_MEDIUM_100MB;
+ ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
+
+ return 0;
+}
+
static const struct driver_info ax8817x_info = {
.description = "ASIX AX8817x USB 2.0 Ethernet",
.bind = ax8817x_bind,
- .unbind = ax8817x_unbind,
+ .status = ax8817x_status,
+ .link_reset = ax88172_link_reset,
+ .reset = ax88172_link_reset,
.flags = FLAG_ETHER,
.data = 0x00130103,
};
@@ -1224,7 +1212,9 @@ static const struct driver_info ax8817x_info = {
static const struct driver_info dlink_dub_e100_info = {
.description = "DLink DUB-E100 USB Ethernet",
.bind = ax8817x_bind,
- .unbind = ax8817x_unbind,
+ .status = ax8817x_status,
+ .link_reset = ax88172_link_reset,
+ .reset = ax88172_link_reset,
.flags = FLAG_ETHER,
.data = 0x009f9d9f,
};
@@ -1232,7 +1222,9 @@ static const struct driver_info dlink_dub_e100_info = {
static const struct driver_info netgear_fa120_info = {
.description = "Netgear FA-120 USB Ethernet",
.bind = ax8817x_bind,
- .unbind = ax8817x_unbind,
+ .status = ax8817x_status,
+ .link_reset = ax88172_link_reset,
+ .reset = ax88172_link_reset,
.flags = FLAG_ETHER,
.data = 0x00130103,
};
@@ -1240,7 +1232,9 @@ static const struct driver_info netgear_fa120_info = {
static const struct driver_info hawking_uf200_info = {
.description = "Hawking UF200 USB Ethernet",
.bind = ax8817x_bind,
- .unbind = ax8817x_unbind,
+ .status = ax8817x_status,
+ .link_reset = ax88172_link_reset,
+ .reset = ax88172_link_reset,
.flags = FLAG_ETHER,
.data = 0x001f1d1f,
};
@@ -1248,7 +1242,9 @@ static const struct driver_info hawking_uf200_info = {
static const struct driver_info ax88772_info = {
.description = "ASIX AX88772 USB 2.0 Ethernet",
.bind = ax88772_bind,
- .unbind = ax8817x_unbind,
+ .status = ax8817x_status,
+ .link_reset = ax88772_link_reset,
+ .reset = ax88772_link_reset,
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88772_rx_fixup,
.tx_fixup = ax88772_tx_fixup,
@@ -2661,7 +2657,7 @@ static const struct driver_info blob_info = {
* All known Zaurii lie about their standards conformance. Most lie by
* saying they support CDC Ethernet. Some lie and say they support CDC
* MDLM (as if for access to cell phone modems). Someone, please beat
- * on Sharp for a while with a cluestick.
+ * on Sharp (and other such vendors) for a while with a cluestick.
*
*-------------------------------------------------------------------------*/
@@ -2714,13 +2710,6 @@ static const struct driver_info zaurus_pxa_info = {
};
#define ZAURUS_PXA_INFO ((unsigned long)&zaurus_pxa_info)
-static const struct driver_info zaurus_pxa_mdlm_info = {
- .description = "Sharp Zaurus, PXA-255 based",
- .flags = FLAG_FRAMING_Z,
- .check_connect = always_connected,
- .tx_fixup = zaurus_tx_fixup,
-};
-
static const struct driver_info olympus_mxl_info = {
.description = "Olympus R1000",
.flags = FLAG_FRAMING_Z,
@@ -2731,6 +2720,133 @@ static const struct driver_info olympus_mxl_info = {
};
#define OLYMPUS_MXL_INFO ((unsigned long)&olympus_mxl_info)
+
+/* Some more recent products using Lineo/Belcarra code will wrongly claim
+ * CDC MDLM conformance. They aren't conformant: data endpoints live
+ * in the control interface, there's no data interface, and it's not used
+ * to talk to a cell phone radio. But at least we can detect these two
+ * pseudo-classes, rather than growing this product list with entries for
+ * each new nonconformant product (sigh).
+ */
+static const u8 safe_guid[16] = {
+ 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
+ 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
+};
+static const u8 blan_guid[16] = {
+ 0x74, 0xf0, 0x3d, 0xbd, 0x1e, 0xc1, 0x44, 0x70,
+ 0xa3, 0x67, 0x71, 0x34, 0xc9, 0xf5, 0x54, 0x37,
+};
+
+static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf)
+{
+ u8 *buf = intf->cur_altsetting->extra;
+ int len = intf->cur_altsetting->extralen;
+ struct usb_cdc_mdlm_desc *desc = NULL;
+ struct usb_cdc_mdlm_detail_desc *detail = NULL;
+
+ while (len > 3) {
+ if (buf [1] != USB_DT_CS_INTERFACE)
+ goto next_desc;
+
+ /* use bDescriptorSubType, and just verify that we get a
+ * "BLAN" (or "SAFE") descriptor.
+ */
+ switch (buf [2]) {
+ case USB_CDC_MDLM_TYPE:
+ if (desc) {
+ dev_dbg (&intf->dev, "extra MDLM\n");
+ goto bad_desc;
+ }
+ desc = (void *) buf;
+ if (desc->bLength != sizeof *desc) {
+ dev_dbg (&intf->dev, "MDLM len %u\n",
+ desc->bLength);
+ goto bad_desc;
+ }
+ /* expect bcdVersion 1.0, ignore */
+ if (memcmp(&desc->bGUID, blan_guid, 16)
+ || memcmp(&desc->bGUID, blan_guid, 16) ) {
+ /* hey, this one might _really_ be MDLM! */
+ dev_dbg (&intf->dev, "MDLM guid\n");
+ goto bad_desc;
+ }
+ break;
+ case USB_CDC_MDLM_DETAIL_TYPE:
+ if (detail) {
+ dev_dbg (&intf->dev, "extra MDLM detail\n");
+ goto bad_desc;
+ }
+ detail = (void *) buf;
+ switch (detail->bGuidDescriptorType) {
+ case 0: /* "SAFE" */
+ if (detail->bLength != (sizeof *detail + 2))
+ goto bad_detail;
+ break;
+ case 1: /* "BLAN" */
+ if (detail->bLength != (sizeof *detail + 3))
+ goto bad_detail;
+ break;
+ default:
+ goto bad_detail;
+ }
+
+ /* assuming we either noticed BLAN already, or will
+ * find it soon, there are some data bytes here:
+ * - bmNetworkCapabilities (unused)
+ * - bmDataCapabilities (bits, see below)
+ * - bPad (ignored, for PADAFTER -- BLAN-only)
+ * bits are:
+ * - 0x01 -- Zaurus framing (add CRC)
+ * - 0x02 -- PADBEFORE
+ * - 0x04 -- PADAFTER
+ * - 0x08 -- "fermat" packet mangling (for hw bugs)
+ */
+ if (detail->bDetailData[1] != 0x01) {
+ /* bmDataCapabilites == 0 would be fine too,
+ * but framing is minidriver-coupled for now.
+ */
+bad_detail:
+ dev_dbg (&intf->dev,
+ "bad MDLM detail, %d %d %d\n",
+ detail->bLength,
+ detail->bDetailData[0],
+ detail->bDetailData[2]);
+ goto bad_desc;
+ }
+ break;
+ }
+next_desc:
+ len -= buf [0]; /* bLength */
+ buf += buf [0];
+ }
+
+ if (!desc || !detail) {
+ dev_dbg (&intf->dev, "missing cdc mdlm %s%sdescriptor\n",
+ desc ? "" : "func ",
+ detail ? "" : "detail ");
+ goto bad_desc;
+ }
+
+ /* There's probably a CDC Ethernet descriptor there, but we can't
+ * rely on the Ethernet address it provides since not all vendors
+ * bother to make it unique. Likewise there's no point in tracking
+ * of the CDC event notifications.
+ */
+ return get_endpoints (dev, intf);
+
+bad_desc:
+ dev_info (&dev->udev->dev, "unsupported MDLM descriptors\n");
+ return -ENODEV;
+}
+
+static const struct driver_info bogus_mdlm_info = {
+ .description = "pseudo-MDLM (BLAN) device",
+ .flags = FLAG_FRAMING_Z,
+ .check_connect = always_connected,
+ .tx_fixup = zaurus_tx_fixup,
+ .bind = blan_mdlm_bind,
+};
+
#else
/* blacklist all those devices */
@@ -3307,6 +3423,19 @@ kevent (void *data)
}
}
+ if (test_bit (EVENT_LINK_RESET, &dev->flags)) {
+ struct driver_info *info = dev->driver_info;
+ int retval = 0;
+
+ clear_bit (EVENT_LINK_RESET, &dev->flags);
+ if(info->link_reset && (retval = info->link_reset(dev)) < 0) {
+ devinfo(dev, "link reset failed (%d) usbnet usb-%s-%s, %s",
+ retval,
+ dev->udev->bus->bus_name, dev->udev->devpath,
+ info->description);
+ }
+ }
+
if (dev->flags)
devdbg (dev, "kevent done, flags = 0x%lx",
dev->flags);
@@ -3942,6 +4071,9 @@ static const struct usb_device_id products [] = {
USB_DEVICE (0x8086, 0x07d3), // "blob" bootloader
.driver_info = (unsigned long) &blob_info,
}, {
+ USB_DEVICE (0x22b8, 0x600c), // USBNET Motorola E680
+ .driver_info = (unsigned long) &linuxdev_info,
+}, {
// Linux Ethernet/RNDIS gadget on pxa210/25x/26x
// e.g. Gumstix, current OpenZaurus, ...
USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203),
@@ -4020,30 +4152,14 @@ static const struct usb_device_id products [] = {
},
#ifdef CONFIG_USB_ZAURUS
- /* at least some (reports vary) PXA units have very different
- * lies about their standards support: they claim to be cell
- * phones giving direct radio access (which they aren't).
+ /* At least some (reports vary) PXA units have very different lies
+ * about their standards support: they claim to be cell phones with
+ * direct access to their radios. (They don't conform to CDC MDLM.)
*/
{
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- /* Sharp ROM v1.32 */
- .idProduct = 0x8006, /* SL-5600 */
- .bInterfaceClass = USB_CLASS_COMM,
- .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM,
- .bInterfaceProtocol = USB_CDC_PROTO_NONE,
- .driver_info = (unsigned long) &zaurus_pxa_mdlm_info,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- /* reported with some C860 units */
- .idProduct = 0x9031, /* C-860 */
- .bInterfaceClass = USB_CLASS_COMM,
- .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM,
- .bInterfaceProtocol = USB_CDC_PROTO_NONE,
- .driver_info = (unsigned long) &zaurus_pxa_mdlm_info,
+ USB_INTERFACE_INFO (USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
+ USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &bogus_mdlm_info,
},
#endif
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c
index c81cd0a619b..341ae5f732d 100644
--- a/drivers/usb/net/zd1201.c
+++ b/drivers/usb/net/zd1201.c
@@ -45,7 +45,7 @@ MODULE_PARM_DESC(ap, "If non-zero Access Point firmware will be loaded");
MODULE_DEVICE_TABLE(usb, zd1201_table);
-int zd1201_fw_upload(struct usb_device *dev, int apfw)
+static int zd1201_fw_upload(struct usb_device *dev, int apfw)
{
const struct firmware *fw_entry;
char* data;
@@ -111,7 +111,7 @@ exit:
return err;
}
-void zd1201_usbfree(struct urb *urb, struct pt_regs *regs)
+static void zd1201_usbfree(struct urb *urb, struct pt_regs *regs)
{
struct zd1201 *zd = urb->context;
@@ -142,7 +142,8 @@ void zd1201_usbfree(struct urb *urb, struct pt_regs *regs)
total: 4 + 2 + 2 + 2 + 2 + 4 = 16
*/
-int zd1201_docmd(struct zd1201 *zd, int cmd, int parm0, int parm1, int parm2)
+static int zd1201_docmd(struct zd1201 *zd, int cmd, int parm0,
+ int parm1, int parm2)
{
unsigned char *command;
int ret;
@@ -175,15 +176,15 @@ int zd1201_docmd(struct zd1201 *zd, int cmd, int parm0, int parm1, int parm2)
}
/* Callback after sending out a packet */
-void zd1201_usbtx(struct urb *urb, struct pt_regs *regs)
+static void zd1201_usbtx(struct urb *urb, struct pt_regs *regs)
{
struct zd1201 *zd = urb->context;
netif_wake_queue(zd->dev);
return;
}
-/* Incomming data */
-void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
+/* Incoming data */
+static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
{
struct zd1201 *zd = urb->context;
int free = 0;
@@ -613,7 +614,7 @@ static inline int zd1201_setconfig16(struct zd1201 *zd, int rid, short val)
return (zd1201_setconfig(zd, rid, &zdval, sizeof(__le16), 1));
}
-int zd1201_drvr_start(struct zd1201 *zd)
+static int zd1201_drvr_start(struct zd1201 *zd)
{
int err, i;
short max;
@@ -771,7 +772,7 @@ static int zd1201_net_stop(struct net_device *dev)
/*
RFC 1042 encapsulates Ethernet frames in 802.11 frames
by prefixing them with 0xaa, 0xaa, 0x03) followed by a SNAP OID of 0
- (0x00, 0x00, 0x00). Zd requires an additionnal padding, copy
+ (0x00, 0x00, 0x00). Zd requires an additional padding, copy
of ethernet addresses, length of the standard RFC 1042 packet
and a command byte (which is nul for tx).
@@ -1097,7 +1098,7 @@ static int zd1201_get_range(struct net_device *dev,
/* Little bit of magic here: we only get the quality if we poll
* for it, and we never get an actual request to trigger such
- * a poll. Therefore we 'asume' that the user will soon ask for
+ * a poll. Therefore we 'assume' that the user will soon ask for
* the stats after asking the bssid.
*/
static int zd1201_get_wap(struct net_device *dev,
@@ -1107,7 +1108,7 @@ static int zd1201_get_wap(struct net_device *dev,
unsigned char buffer[6];
if (!zd1201_getconfig(zd, ZD1201_RID_COMMSQUALITY, buffer, 6)) {
- /* Unfortunatly the quality and noise reported is useless.
+ /* Unfortunately the quality and noise reported is useless.
they seem to be accumulators that increase until you
read them, unless we poll on a fixed interval we can't
use them
@@ -1739,7 +1740,8 @@ static const struct iw_handler_def zd1201_iw_handlers = {
.private_args = (struct iw_priv_args *) zd1201_private_args,
};
-int zd1201_probe(struct usb_interface *interface, const struct usb_device_id *id)
+static int zd1201_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
{
struct zd1201 *zd;
struct usb_device *usb;
@@ -1851,7 +1853,7 @@ err_zd:
return err;
}
-void zd1201_disconnect(struct usb_interface *interface)
+static void zd1201_disconnect(struct usb_interface *interface)
{
struct zd1201 *zd=(struct zd1201 *)usb_get_intfdata(interface);
struct hlist_node *node, *node2;
@@ -1882,7 +1884,7 @@ void zd1201_disconnect(struct usb_interface *interface)
kfree(zd);
}
-struct usb_driver zd1201_usb = {
+static struct usb_driver zd1201_usb = {
.owner = THIS_MODULE,
.name = "zd1201",
.probe = zd1201_probe,
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index b869076d9c7..bc798edf035 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -53,6 +53,15 @@ config USB_SERIAL_GENERIC
support" be compiled as a module for this driver to be used
properly.
+config USB_SERIAL_AIRPRIME
+ tristate "USB AirPrime CDMA Wireless Driver"
+ depends on USB_SERIAL
+ help
+ Say Y here if you want to use a AirPrime CDMA Wireless PC card.
+
+ To compile this driver as a module, choose M here: the
+ module will be called airprime.
+
config USB_SERIAL_BELKIN
tristate "USB Belkin and Peracom Single Port Serial Driver"
depends on USB_SERIAL
@@ -395,6 +404,15 @@ config USB_SERIAL_PL2303
To compile this driver as a module, choose M here: the
module will be called pl2303.
+config USB_SERIAL_HP4X
+ tristate "USB HP4x Calculators support"
+ depends on USB_SERIAL
+ help
+ Say Y here if you want to use an Hewlett-Packard 4x Calculator.
+
+ To compile this driver as a module, choose M here: the
+ module will be called hp4x.
+
config USB_SERIAL_SAFE
tristate "USB Safe Serial (Encapsulated) Driver (EXPERIMENTAL)"
depends on USB_SERIAL && EXPERIMENTAL
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index 351b81855b1..d56ff6d86cc 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -11,6 +11,7 @@ usbserial-obj-$(CONFIG_USB_EZUSB) += ezusb.o
usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y)
+obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o
obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o
obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o
obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o
@@ -21,6 +22,7 @@ obj-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += io_ti.o
obj-$(CONFIG_USB_SERIAL_EMPEG) += empeg.o
obj-$(CONFIG_USB_SERIAL_FTDI_SIO) += ftdi_sio.o
obj-$(CONFIG_USB_SERIAL_GARMIN) += garmin_gps.o
+obj-$(CONFIG_USB_SERIAL_HP4X) += hp4x.o
obj-$(CONFIG_USB_SERIAL_IPAQ) += ipaq.o
obj-$(CONFIG_USB_SERIAL_IPW) += ipw.o
obj-$(CONFIG_USB_SERIAL_IR) += ir-usb.o
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
new file mode 100644
index 00000000000..a4ce0008d69
--- /dev/null
+++ b/drivers/usb/serial/airprime.c
@@ -0,0 +1,63 @@
+/*
+ * AirPrime CDMA Wireless Serial USB driver
+ *
+ * Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "usb-serial.h"
+
+static struct usb_device_id id_table [] = {
+ { USB_DEVICE(0xf3d, 0x0112) },
+ { },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver airprime_driver = {
+ .owner = THIS_MODULE,
+ .name = "airprime",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
+static struct usb_serial_device_type airprime_device = {
+ .owner = THIS_MODULE,
+ .name = "airprime",
+ .id_table = id_table,
+ .num_interrupt_in = NUM_DONT_CARE,
+ .num_bulk_in = NUM_DONT_CARE,
+ .num_bulk_out = NUM_DONT_CARE,
+ .num_ports = 1,
+};
+
+static int __init airprime_init(void)
+{
+ int retval;
+
+ retval = usb_serial_register(&airprime_device);
+ if (retval)
+ return retval;
+ retval = usb_register(&airprime_driver);
+ if (retval)
+ usb_serial_deregister(&airprime_device);
+ return retval;
+}
+
+static void __exit airprime_exit(void)
+{
+ usb_deregister(&airprime_driver);
+ usb_serial_deregister(&airprime_device);
+}
+
+module_init(airprime_init);
+module_exit(airprime_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index d165f42d560..f34a9bb6a21 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -16,6 +16,14 @@
* See http://geocities.com/i0xox0i for information on this driver and the
* earthmate usb device.
*
+ * Lonnie Mendez <dignome@gmail.com>
+ * 4-29-2005
+ * Fixed problem where setting or retreiving the serial config would fail with
+ * EPIPE. Removed CRTS toggling so the driver behaves more like other usbserial
+ * adapters. Issued new interval of 1ms instead of the default 10ms. As a
+ * result, transfer speed has been substantially increased. From avg. 850bps to
+ * avg. 3300bps. initial termios has also been modified. Cleaned up code and
+ * formatting issues so it is more readable. Replaced the C++ style comments.
*
* Lonnie Mendez <dignome@gmail.com>
* 12-15-2004
@@ -32,12 +40,6 @@
* 10-2003
* Driver first released.
*
- *
- * Long Term TODO:
- * Improve transfer speeds - both read/write are somewhat slow
- * at this point.
- * Improve debugging. Show modem line status with debug output and
- * implement filtering for certain data as a module parameter.
*/
/* Thanks to Neil Whelchel for writing the first cypress m8 implementation for linux. */
@@ -72,11 +74,12 @@
static int debug;
#endif
static int stats;
+static int interval;
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.08"
+#define DRIVER_VERSION "v1.09"
#define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>"
#define DRIVER_DESC "Cypress USB to Serial Driver"
@@ -130,7 +133,6 @@ struct cypress_private {
char prev_status, diff_status; /* used for TIOCMIWAIT */
/* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */
struct termios tmp_termios; /* stores the old termios settings */
- char calledfromopen; /* used when issuing lines on open - fixes rts drop bug */
};
/* write buffer structure */
@@ -168,10 +170,8 @@ static void cypress_buf_free(struct cypress_buf *cb);
static void cypress_buf_clear(struct cypress_buf *cb);
static unsigned int cypress_buf_data_avail(struct cypress_buf *cb);
static unsigned int cypress_buf_space_avail(struct cypress_buf *cb);
-static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf,
- unsigned int count);
-static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf,
- unsigned int count);
+static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf, unsigned int count);
+static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf, unsigned int count);
static struct usb_serial_device_type cypress_earthmate_device = {
@@ -234,14 +234,13 @@ static struct usb_serial_device_type cypress_hidcom_device = {
*****************************************************************************/
-/* This function can either set or retreive the current serial line settings */
+/* This function can either set or retrieve the current serial line settings */
static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_mask, int data_bits, int stop_bits,
int parity_enable, int parity_type, int reset, int cypress_request_type)
{
- int i, n_baud_rate = 0, retval = 0;
+ int new_baudrate = 0, retval = 0, tries = 0;
struct cypress_private *priv;
- __u8 feature_buffer[5];
- __u8 config;
+ __u8 feature_buffer[8];
unsigned long flags;
dbg("%s", __FUNCTION__);
@@ -256,7 +255,8 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m
* of 57600bps (I have no idea whether DeLorme chose to use the general purpose
* firmware or not), if you need to modify this speed setting for your own
* project please add your own chiptype and modify the code likewise. The
- * Cypress HID->COM device will work successfully up to 115200bps.
+ * Cypress HID->COM device will work successfully up to 115200bps (but the
+ * actual throughput is around 3kBps).
*/
if (baud_mask != priv->cbr_mask) {
dbg("%s - baud rate is changing", __FUNCTION__);
@@ -265,109 +265,114 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m
* but are not used with NMEA and SiRF protocols */
if ( (baud_mask == B300) || (baud_mask == B600) ) {
- err("%s - failed setting baud rate, unsupported speed (default to 4800)",
+ err("%s - failed setting baud rate, unsupported speed",
__FUNCTION__);
- n_baud_rate = 4800;
- } else if ( (n_baud_rate = mask_to_rate(baud_mask)) == -1) {
- err("%s - failed setting baud rate, unsupported speed (default to 4800)",
+ new_baudrate = priv->baud_rate;
+ } else if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
+ err("%s - failed setting baud rate, unsupported speed",
__FUNCTION__);
- n_baud_rate = 4800;
+ new_baudrate = priv->baud_rate;
}
} else if (priv->chiptype == CT_CYPHIDCOM) {
- if ( (n_baud_rate = mask_to_rate(baud_mask)) == -1) {
- err("%s - failed setting baud rate, unsupported speed (default to 4800)",
+ if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
+ err("%s - failed setting baud rate, unsupported speed",
__FUNCTION__);
- n_baud_rate = 4800;
+ new_baudrate = priv->baud_rate;
}
} else if (priv->chiptype == CT_GENERIC) {
- if ( (n_baud_rate = mask_to_rate(baud_mask)) == -1) {
- err("%s - failed setting baud rate, unsupported speed (default to 4800)",
+ if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
+ err("%s - failed setting baud rate, unsupported speed",
__FUNCTION__);
- n_baud_rate = 4800;
+ new_baudrate = priv->baud_rate;
}
} else {
- info("%s - please define your chiptype, using 4800bps default", __FUNCTION__);
- n_baud_rate = 4800;
+ info("%s - please define your chiptype", __FUNCTION__);
+ new_baudrate = priv->baud_rate;
}
} else { /* baud rate not changing, keep the old */
- n_baud_rate = priv->baud_rate;
+ new_baudrate = priv->baud_rate;
}
- dbg("%s - baud rate is being sent as %d", __FUNCTION__, n_baud_rate);
-
+ dbg("%s - baud rate is being sent as %d", __FUNCTION__, new_baudrate);
- /*
- * This algorithm accredited to Jiang Jay Zhang... thanks for all the help!
- */
- for (i = 0; i < 4; ++i) {
- feature_buffer[i] = ( n_baud_rate >> (i*8) & 0xFF );
- }
+ memset(feature_buffer, 0, 8);
+ /* fill the feature_buffer with new configuration */
+ *((u_int32_t *)feature_buffer) = new_baudrate;
- config = 0; // reset config byte
- config |= data_bits; // assign data bits in 2 bit space ( max 3 )
+ feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */
/* 1 bit gap */
- config |= (stop_bits << 3); // assign stop bits in 1 bit space
- config |= (parity_enable << 4); // assign parity flag in 1 bit space
- config |= (parity_type << 5); // assign parity type in 1 bit space
+ feature_buffer[4] |= (stop_bits << 3); /* assign stop bits in 1 bit space */
+ feature_buffer[4] |= (parity_enable << 4); /* assign parity flag in 1 bit space */
+ feature_buffer[4] |= (parity_type << 5); /* assign parity type in 1 bit space */
/* 1 bit gap */
- config |= (reset << 7); // assign reset at end of byte, 1 bit space
-
- feature_buffer[4] = config;
+ feature_buffer[4] |= (reset << 7); /* assign reset at end of byte, 1 bit space */
dbg("%s - device is being sent this feature report:", __FUNCTION__);
dbg("%s - %02X - %02X - %02X - %02X - %02X", __FUNCTION__, feature_buffer[0], feature_buffer[1],
feature_buffer[2], feature_buffer[3], feature_buffer[4]);
+ do {
retval = usb_control_msg (port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
HID_REQ_SET_REPORT, USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
- 0x0300, 0, feature_buffer, 5, 500);
+ 0x0300, 0, feature_buffer, 8, 500);
+
+ if (tries++ >= 3)
+ break;
- if (retval != 5)
+ if (retval == EPIPE)
+ usb_clear_halt(port->serial->dev, 0x00);
+ } while (retval != 8 && retval != ENODEV);
+
+ if (retval != 8)
err("%s - failed sending serial line settings - %d", __FUNCTION__, retval);
else {
spin_lock_irqsave(&priv->lock, flags);
- priv->baud_rate = n_baud_rate;
+ priv->baud_rate = new_baudrate;
priv->cbr_mask = baud_mask;
- priv->current_config = config;
- ++priv->cmd_count;
+ priv->current_config = feature_buffer[4];
spin_unlock_irqrestore(&priv->lock, flags);
}
break;
case CYPRESS_GET_CONFIG:
dbg("%s - retreiving serial line settings", __FUNCTION__);
- /* reset values in feature buffer */
- memset(feature_buffer, 0, 5);
+ /* set initial values in feature buffer */
+ memset(feature_buffer, 0, 8);
+ do {
retval = usb_control_msg (port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0),
HID_REQ_GET_REPORT, USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
- 0x0300, 0, feature_buffer, 5, 500);
+ 0x0300, 0, feature_buffer, 8, 500);
+
+ if (tries++ >= 3)
+ break;
+
+ if (retval == EPIPE)
+ usb_clear_halt(port->serial->dev, 0x00);
+ } while (retval != 5 && retval != ENODEV);
+
if (retval != 5) {
err("%s - failed to retreive serial line settings - %d", __FUNCTION__, retval);
return retval;
} else {
spin_lock_irqsave(&priv->lock, flags);
+
/* store the config in one byte, and later use bit masks to check values */
priv->current_config = feature_buffer[4];
- /* reverse the process above to get the baud_mask value */
- n_baud_rate = 0; // reset bits
- for (i = 0; i < 4; ++i) {
- n_baud_rate |= ( feature_buffer[i] << (i*8) );
- }
+ priv->baud_rate = *((u_int32_t *)feature_buffer);
- priv->baud_rate = n_baud_rate;
- if ( (priv->cbr_mask = rate_to_mask(n_baud_rate)) == 0x40)
+ if ( (priv->cbr_mask = rate_to_mask(priv->baud_rate)) == 0x40)
dbg("%s - failed setting the baud mask (not defined)", __FUNCTION__);
- ++priv->cmd_count;
spin_unlock_irqrestore(&priv->lock, flags);
}
- break;
- default:
- err("%s - unsupported serial control command issued", __FUNCTION__);
}
+ spin_lock_irqsave(&priv->lock, flags);
+ ++priv->cmd_count;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
return retval;
} /* cypress_serial_control */
-/* given a baud mask, it will return speed on success */
+/* given a baud mask, it will return integer baud on success */
static int mask_to_rate (unsigned mask)
{
int rate;
@@ -438,11 +443,12 @@ static int generic_startup (struct usb_serial *serial)
usb_reset_configuration (serial->dev);
+ interval = 1;
priv->cmd_ctrl = 0;
priv->line_control = 0;
priv->termios_initialized = 0;
- priv->calledfromopen = 0;
priv->rx_flags = 0;
+ priv->cbr_mask = B300;
usb_set_serial_port_data(serial->port[0], priv);
return (0);
@@ -513,7 +519,6 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
dbg("%s - port %d", __FUNCTION__, port->number);
/* clear halts before open */
- usb_clear_halt(serial->dev, 0x00);
usb_clear_halt(serial->dev, 0x81);
usb_clear_halt(serial->dev, 0x02);
@@ -531,7 +536,6 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
/* raise both lines and set termios */
spin_lock_irqsave(&priv->lock, flags);
priv->line_control = CONTROL_DTR | CONTROL_RTS;
- priv->calledfromopen = 1;
priv->cmd_ctrl = 1;
spin_unlock_irqrestore(&priv->lock, flags);
result = cypress_write(port, NULL, 0);
@@ -553,7 +557,7 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
port->interrupt_in_urb->transfer_buffer, port->interrupt_in_urb->transfer_buffer_length,
- cypress_read_int_callback, port, port->interrupt_in_urb->interval);
+ cypress_read_int_callback, port, interval);
result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (result){
@@ -680,12 +684,12 @@ static void cypress_send(struct usb_serial_port *port)
spin_lock_irqsave(&priv->lock, flags);
switch (port->interrupt_out_size) {
case 32:
- // this is for the CY7C64013...
+ /* this is for the CY7C64013... */
offset = 2;
port->interrupt_out_buffer[0] = priv->line_control;
break;
case 8:
- // this is for the CY7C63743...
+ /* this is for the CY7C63743... */
offset = 1;
port->interrupt_out_buffer[0] = priv->line_control;
break;
@@ -738,6 +742,7 @@ send:
port->interrupt_out_urb->transfer_buffer_length = actual_size;
port->interrupt_out_urb->dev = port->serial->dev;
+ port->interrupt_out_urb->interval = interval;
result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC);
if (result) {
dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__,
@@ -910,7 +915,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
unsigned cflag, iflag, baud_mask;
unsigned long flags;
__u8 oldlines;
- int linechange;
+ int linechange = 0;
dbg("%s - port %d", __FUNCTION__, port->number);
@@ -996,15 +1001,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
case B115200: dbg("%s - setting baud 115200bps", __FUNCTION__); break;
default: dbg("%s - unknown masked baud rate", __FUNCTION__);
}
- priv->line_control |= CONTROL_DTR;
-
- /* toggle CRTSCTS? - don't do this if being called from cypress_open */
- if (!priv->calledfromopen) {
- if (cflag & CRTSCTS)
- priv->line_control |= CONTROL_RTS;
- else
- priv->line_control &= ~CONTROL_RTS;
- }
+ priv->line_control = (CONTROL_DTR | CONTROL_RTS);
}
spin_unlock_irqrestore(&priv->lock, flags);
@@ -1014,8 +1011,6 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
cypress_serial_control(port, baud_mask, data_bits, stop_bits, parity_enable,
parity_type, 0, CYPRESS_SET_CONFIG);
- msleep(50); /* give some time between change and read (50ms) */
-
/* we perform a CYPRESS_GET_CONFIG so that the current settings are filled into the private structure
* this should confirm that all is working if it returns what we just set */
cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);
@@ -1031,7 +1026,6 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
dbg("Using custom termios settings for a baud rate of 4800bps.");
/* define custom termios settings for NMEA protocol */
-
tty->termios->c_iflag /* input modes - */
&= ~(IGNBRK /* disable ignore break */
| BRKINT /* disable break causes interrupt */
@@ -1052,23 +1046,16 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
| ISIG /* disable interrupt, quit, and suspend special characters */
| IEXTEN); /* disable non-POSIX special characters */
- } else if (priv->chiptype == CT_CYPHIDCOM) {
-
- // Software app handling it for device...
+ } /* CT_CYPHIDCOM: Application should handle this for device */
- }
linechange = (priv->line_control != oldlines);
spin_unlock_irqrestore(&priv->lock, flags);
/* if necessary, set lines */
- if (!priv->calledfromopen && linechange) {
+ if (linechange) {
priv->cmd_ctrl = 1;
cypress_write(port, NULL, 0);
}
-
- if (priv->calledfromopen)
- priv->calledfromopen = 0;
-
} /* cypress_set_termios */
@@ -1164,7 +1151,7 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
spin_lock_irqsave(&priv->lock, flags);
switch(urb->actual_length) {
case 32:
- // This is for the CY7C64013...
+ /* This is for the CY7C64013... */
priv->current_status = data[0] & 0xF8;
bytes = data[1]+2;
i=2;
@@ -1172,7 +1159,7 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
havedata = 1;
break;
case 8:
- // This is for the CY7C63743...
+ /* This is for the CY7C63743... */
priv->current_status = data[0] & 0xF8;
bytes = (data[0] & 0x07)+1;
i=1;
@@ -1245,7 +1232,7 @@ continue_read:
port->interrupt_in_urb->transfer_buffer,
port->interrupt_in_urb->transfer_buffer_length,
cypress_read_int_callback, port,
- port->interrupt_in_urb->interval);
+ interval);
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
if (result)
dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
@@ -1274,6 +1261,8 @@ static void cypress_write_int_callback(struct urb *urb, struct pt_regs *regs)
dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
priv->write_urb_in_use = 0;
return;
+ case -EPIPE: /* no break needed */
+ usb_clear_halt(port->serial->dev, 0x02);
default:
/* error in the urb, so we have to resubmit it */
dbg("%s - Overflow in write", __FUNCTION__);
@@ -1535,3 +1524,5 @@ module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
module_param(stats, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(stats, "Enable statistics or not");
+module_param(interval, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(interval, "Overrides interrupt interval");
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 4c788c767a9..52394f08a94 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -76,7 +76,7 @@
* Defererence pointers after any paranoid checks, not before.
*
* (21/Jun/2003) Erik Nygren
- * Added support for Home Electronics Tira-1 IR tranceiver using FT232BM chip.
+ * Added support for Home Electronics Tira-1 IR transceiver using FT232BM chip.
* See <http://www.home-electro.com/tira1.htm>. Only operates properly
* at 100000 and RTS-CTS, so set custom divisor mode on startup.
* Also force the Tira-1 and USB-UIRT to only use their custom baud rates.
@@ -91,7 +91,7 @@
* Minor whitespace and comment changes.
*
* (12/Jun/2003) David Norwood
- * Added support for USB-UIRT IR tranceiver using 8U232AM chip.
+ * Added support for USB-UIRT IR transceiver using 8U232AM chip.
* See <http://home.earthlink.net/~jrhees/USBUIRT/index.htm>. Only
* operates properly at 312500, so set custom divisor mode on startup.
*
@@ -272,6 +272,7 @@ static int debug;
static struct usb_device_id id_table_sio [] = {
{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
+ { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
{ } /* Terminating entry */
};
@@ -296,7 +297,6 @@ static struct usb_device_id id_table_8U232AM [] = {
{ USB_DEVICE_VER(FTDI_VID, FTDI_IRTRANS_PID, 0, 0x3ff) },
{ USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_PID, 0, 0x3ff) },
{ USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_ALT_PID, 0, 0x3ff) },
{ USB_DEVICE_VER(FTDI_VID, FTDI_RELAIS_PID, 0, 0x3ff) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
@@ -369,11 +369,14 @@ static struct usb_device_id id_table_8U232AM [] = {
{ USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) },
{ USB_DEVICE_VER(FALCOM_VID, FALCOM_TWIST_PID, 0, 0x3ff) },
{ USB_DEVICE_VER(FTDI_VID, FTDI_SUUNTO_SPORTS_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_RM_VID, FTDI_RMCANVIEW_PID, 0, 0x3ff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_RM_CANVIEW_PID, 0, 0x3ff) },
{ USB_DEVICE_VER(BANDB_VID, BANDB_USOTL4_PID, 0, 0x3ff) },
{ USB_DEVICE_VER(BANDB_VID, BANDB_USTL4_PID, 0, 0x3ff) },
{ USB_DEVICE_VER(BANDB_VID, BANDB_USO9ML2_PID, 0, 0x3ff) },
{ USB_DEVICE_VER(FTDI_VID, EVER_ECO_PRO_CDS, 0, 0x3ff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID, 0, 0x3ff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID, 0, 0x3ff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID, 0, 0x3ff) },
{ } /* Terminating entry */
};
@@ -382,7 +385,6 @@ static struct usb_device_id id_table_FT232BM [] = {
{ USB_DEVICE_VER(FTDI_VID, FTDI_IRTRANS_PID, 0x400, 0xffff) },
{ USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_PID, 0x400, 0xffff) },
{ USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_ALT_PID, 0x400, 0xffff) },
{ USB_DEVICE_VER(FTDI_VID, FTDI_RELAIS_PID, 0x400, 0xffff) },
{ USB_DEVICE_VER(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID, 0x400, 0xffff) },
{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0x400, 0xffff) },
@@ -485,11 +487,15 @@ static struct usb_device_id id_table_FT232BM [] = {
{ USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0x400, 0xffff) },
{ USB_DEVICE_VER(FALCOM_VID, FALCOM_TWIST_PID, 0x400, 0xffff) },
{ USB_DEVICE_VER(FTDI_VID, FTDI_SUUNTO_SPORTS_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_RM_VID, FTDI_RMCANVIEW_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_RM_CANVIEW_PID, 0x400, 0xffff) },
{ USB_DEVICE_VER(BANDB_VID, BANDB_USOTL4_PID, 0x400, 0xffff) },
{ USB_DEVICE_VER(BANDB_VID, BANDB_USTL4_PID, 0x400, 0xffff) },
{ USB_DEVICE_VER(BANDB_VID, BANDB_USO9ML2_PID, 0x400, 0xffff) },
{ USB_DEVICE_VER(FTDI_VID, EVER_ECO_PRO_CDS, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID, 0x400, 0xffff) },
{ } /* Terminating entry */
};
@@ -517,7 +523,6 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
- { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_ALT_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
@@ -596,6 +601,22 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, PROTEGO_R2X0) },
{ USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_3) },
{ USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_4) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E808_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E809_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80A_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80B_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80C_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80D_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80E_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80F_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E888_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E889_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88A_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88B_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88C_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88D_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) },
{ USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) },
{ USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) },
{ USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) },
@@ -609,11 +630,16 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
{ USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) },
- { USB_DEVICE(FTDI_RM_VID, FTDI_RMCANVIEW_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
{ USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
{ USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
{ USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) },
{ USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) },
+ { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) },
+ { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
+ { USB_DEVICE_VER(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID, 0x400, 0xffff) },
{ } /* Terminating entry */
};
@@ -1457,10 +1483,10 @@ static int ftdi_FT2232C_startup (struct usb_serial *serial)
inter = serial->interface->altsetting->desc.bInterfaceNumber;
if (inter) {
- priv->interface = INTERFACE_B;
+ priv->interface = PIT_SIOB;
}
else {
- priv->interface = INTERFACE_A;
+ priv->interface = PIT_SIOA;
}
priv->baud_base = 48000000 / 2; /* Would be / 16, but FT2232C supports multiple of 0.125 divisor fractions! */
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index be5d60bf90b..a52bb13a9ce 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -26,7 +26,6 @@
#define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */
#define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */
#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */
-#define FTDI_8U232AM_ALT_ALT_PID 0xf3c0 /* FTDI's second alternate PID for above */
#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */
#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */
#define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */
@@ -137,7 +136,7 @@
/*
* Home Electronics (www.home-electro.com) USB gadgets
*/
-#define FTDI_HE_TIRA1_PID 0xFA78 /* Tira-1 IR tranceiver */
+#define FTDI_HE_TIRA1_PID 0xFA78 /* Tira-1 IR transceiver */
/* USB-UIRT - An infrared receiver and transmitter using the 8U232AM chip */
/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */
@@ -157,7 +156,8 @@
*/
#define OCT_VID 0x0B39 /* OCT vendor ID */
/* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */
-/* Also rebadged as SIIG Inc. model US2308 */
+/* Also rebadged as Dick Smith Electronics (Aus) XH6451 */
+/* Also rebadged as SIIG Inc. model US2308 hardware version 1 */
#define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */
/* an infrared receiver for user access control with IR tags */
@@ -236,10 +236,10 @@
/*
* RM Michaelides CANview USB (http://www.rmcan.com)
- * CAN filedbus interface adapter, addad by port GmbH www.port.de)
+ * CAN fieldbus interface adapter, added by port GmbH www.port.de)
+ * Ian Abbott changed the macro names for consistency.
*/
-#define FTDI_RM_VID 0x0403 /* Vendor Id */
-#define FTDI_RMCANVIEW_PID 0xfd60 /* Product Id */
+#define FTDI_RM_CANVIEW_PID 0xfd60 /* Product Id */
/*
* EVER Eco Pro UPS (http://www.ever.com.pl/)
@@ -247,6 +247,26 @@
#define EVER_ECO_PRO_CDS 0xe520 /* RS-232 converter */
+/*
+ * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485,
+ * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices
+ * and I'm not entirely sure which are used by which.
+ */
+#define FTDI_4N_GALAXY_DE_0_PID 0x8372
+#define FTDI_4N_GALAXY_DE_1_PID 0xF3C0
+#define FTDI_4N_GALAXY_DE_2_PID 0xF3C1
+
+/*
+ * Mobility Electronics products.
+ */
+#define MOBILITY_VID 0x1342
+#define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */
+
+/*
+ * Active Robots product ids.
+ */
+#define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */
+
/* Commands */
#define FTDI_SIO_RESET 0 /* Reset the port */
#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
@@ -259,10 +279,6 @@
#define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */
#define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */
-/* Port interface code for FT2232C */
-#define INTERFACE_A 1
-#define INTERFACE_B 2
-
/*
* BmRequestType: 1100 0000b
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c
new file mode 100644
index 00000000000..64d55fbd206
--- /dev/null
+++ b/drivers/usb/serial/hp4x.c
@@ -0,0 +1,85 @@
+/*
+ * HP4x Calculators Serial USB driver
+ *
+ * Copyright (C) 2005 Arthur Huillet (ahuillet@users.sf.net)
+ * Copyright (C) 2001-2005 Greg Kroah-Hartman (greg@kroah.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * See Documentation/usb/usb-serial.txt for more information on using this driver
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "usb-serial.h"
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "v1.00"
+#define DRIVER_DESC "HP4x (48/49) Generic Serial driver"
+
+#define HP_VENDOR_ID 0x03f0
+#define HP49GP_PRODUCT_ID 0x0121
+
+static struct usb_device_id id_table [] = {
+ { USB_DEVICE(HP_VENDOR_ID, HP49GP_PRODUCT_ID) },
+ { } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver hp49gp_driver = {
+ .owner = THIS_MODULE,
+ .name = "HP4X",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
+static struct usb_serial_device_type hp49gp_device = {
+ .owner = THIS_MODULE,
+ .name = "HP4X",
+ .id_table = id_table,
+ .num_interrupt_in = NUM_DONT_CARE,
+ .num_bulk_in = NUM_DONT_CARE,
+ .num_bulk_out = NUM_DONT_CARE,
+ .num_ports = 1,
+};
+
+static int __init hp49gp_init(void)
+{
+ int retval;
+ retval = usb_serial_register(&hp49gp_device);
+ if (retval)
+ goto failed_usb_serial_register;
+ retval = usb_register(&hp49gp_driver);
+ if (retval)
+ goto failed_usb_register;
+ info(DRIVER_DESC " " DRIVER_VERSION);
+ return 0;
+failed_usb_register:
+ usb_serial_deregister(&hp49gp_device);
+failed_usb_serial_register:
+ return retval;
+}
+
+static void __exit hp49gp_exit(void)
+{
+ usb_deregister(&hp49gp_driver);
+ usb_serial_deregister(&hp49gp_device);
+}
+
+module_init(hp49gp_init);
+module_exit(hp49gp_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/io_usbvend.h b/drivers/usb/serial/io_usbvend.h
index 8c1fa5e722b..f1804fd5a3d 100644
--- a/drivers/usb/serial/io_usbvend.h
+++ b/drivers/usb/serial/io_usbvend.h
@@ -289,7 +289,7 @@
//
//
-// Edgeport Compatiblity Descriptor
+// Edgeport Compatibility Descriptor
//
// This descriptor is only returned by Edgeport-compatible devices
// supporting the EPiC spec. True ION devices do not return this
diff --git a/drivers/usb/serial/keyspan_usa90msg.h b/drivers/usb/serial/keyspan_usa90msg.h
index dd935b62c1a..86708ecd873 100644
--- a/drivers/usb/serial/keyspan_usa90msg.h
+++ b/drivers/usb/serial/keyspan_usa90msg.h
@@ -19,7 +19,7 @@
This file is available under a BSD-style copyright
- 2. The name of InnoSys Incorprated may not be used to endorse or promote
+ 2. The name of InnoSys Incorporated may not be used to endorse or promote
products derived from this software without specific prior written
permission.
diff --git a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c
index d76483706bc..5a9321705a7 100644
--- a/drivers/usb/storage/debug.c
+++ b/drivers/usb/storage/debug.c
@@ -47,6 +47,7 @@
#include <linux/cdrom.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
#include "debug.h"
#include "scsi.h"
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index 7eff03d9b04..f3b60288696 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -786,7 +786,7 @@ static int usbat_flash_check_media(struct us_data *us,
if (rc != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
- // Check for media existance
+ // Check for media existence
rc = usbat_flash_check_media_present(uio);
if (rc == USBAT_FLASH_MEDIA_NONE) {
info->sense_key = 0x02;
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index fa68dea6bc6..d2891f47579 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1,5 +1,5 @@
/* Driver for USB Mass Storage compliant devices
- * Ununsual Devices File
+ * Unusual Devices File
*
* $Id: unusual_devs.h,v 1.32 2002/02/25 02:41:24 mdharm Exp $
*
@@ -48,6 +48,14 @@
* USB development list <linux-usb-devel@lists.sourceforge.net>.
*/
+/* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr>
+ */
+UNUSUAL_DEV( 0x03eb, 0x2002, 0x0100, 0x0100,
+ "ATMEL",
+ "SND1 Storage",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE),
+
UNUSUAL_DEV( 0x03ee, 0x6901, 0x0000, 0x0100,
"Mitsumi",
"USB FDD",
@@ -517,14 +525,32 @@ UNUSUAL_DEV( 0x05ab, 0x5701, 0x0100, 0x0110,
0 ),
#endif
+/* Submitted by Sven Anderson <sven-linux@anderson.de>
+ * There are at least four ProductIDs used for iPods, so I added 0x1202 and
+ * 0x1204. They just need the US_FL_FIX_CAPACITY. As the bcdDevice appears
+ * to change with firmware updates, I changed the range to maximum for all
+ * iPod entries.
+ */
+UNUSUAL_DEV( 0x05ac, 0x1202, 0x0000, 0x9999,
+ "Apple",
+ "iPod",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY ),
+
/* Reported by Avi Kivity <avi@argo.co.il> */
-UNUSUAL_DEV( 0x05ac, 0x1203, 0x0001, 0x0001,
+UNUSUAL_DEV( 0x05ac, 0x1203, 0x0000, 0x9999,
"Apple",
"iPod",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ),
-UNUSUAL_DEV( 0x05ac, 0x1205, 0x0001, 0x0001,
+UNUSUAL_DEV( 0x05ac, 0x1204, 0x0000, 0x9999,
+ "Apple",
+ "iPod",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY ),
+
+UNUSUAL_DEV( 0x05ac, 0x1205, 0x0000, 0x9999,
"Apple",
"iPod",
US_SC_DEVICE, US_PR_DEVICE, NULL,
@@ -976,6 +1002,13 @@ UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x9999,
US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
0 ),
+/* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
+UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001,
+ "Minolta",
+ "Dimage Z10",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 0 ),
+
/* Reported by Kotrla Vitezslav <kotrla@ceb.cz> */
UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110,
"SWISSBIT",
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 2a1c5965de2..6be8fbec0a0 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -198,6 +198,14 @@ config FB_SA1100
If you plan to use the LCD display with your SA-1100 system, say
Y here.
+config FB_IMX
+ tristate "Motorola i.MX LCD support"
+ depends on FB && ARM && ARCH_IMX
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_SOFT_CURSOR
+
config FB_CYBER2000
tristate "CyberPro 2000/2010/5000 support"
depends on FB && PCI && (BROKEN || !SPARC64)
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 92265b741dc..bd8dc0ffe72 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -90,6 +90,7 @@ obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
obj-$(CONFIG_FB_MAXINE) += maxinefb.o
obj-$(CONFIG_FB_TX3912) += tx3912fb.o
obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
+obj-$(CONFIG_FB_IMX) += imxfb.o
# Platform or fallback drivers go here
obj-$(CONFIG_FB_VESA) += vesafb.o
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index acdba0c67fb..321dbe91dc1 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -125,28 +125,28 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
case 2:
case 4:
case 8:
- var->red.length = 8;
+ var->red.length = var->bits_per_pixel;
var->red.offset = 0;
- var->green.length = 8;
+ var->green.length = var->bits_per_pixel;
var->green.offset = 0;
- var->blue.length = 8;
+ var->blue.length = var->bits_per_pixel;
var->blue.offset = 0;
break;
case 16:
var->red.length = 5;
- var->green.length = 5;
+ var->green.length = 6;
var->blue.length = 5;
if (fb->panel->cntl & CNTL_BGR) {
- var->red.offset = 10;
+ var->red.offset = 11;
var->green.offset = 5;
var->blue.offset = 0;
} else {
var->red.offset = 0;
var->green.offset = 5;
- var->blue.offset = 10;
+ var->blue.offset = 11;
}
break;
- case 24:
+ case 32:
if (fb->panel->cntl & CNTL_LCDTFT) {
var->red.length = 8;
var->green.length = 8;
@@ -178,6 +178,12 @@ static int clcdfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
if (fb->board->check)
ret = fb->board->check(fb, var);
+
+ if (ret == 0 &&
+ var->xres_virtual * var->bits_per_pixel / 8 *
+ var->yres_virtual > fb->fb.fix.smem_len)
+ ret = -EINVAL;
+
if (ret == 0)
ret = clcdfb_set_bitfields(fb, var);
@@ -250,7 +256,7 @@ clcdfb_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
convert_bitfield(green, &fb->fb.var.green) |
convert_bitfield(red, &fb->fb.var.red);
- if (fb->fb.var.bits_per_pixel == 8 && regno < 256) {
+ if (fb->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR && regno < 256) {
int hw_reg = CLCD_PALETTE + ((regno * 2) & ~3);
u32 val, mask, newval;
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index e8eb124754b..ee25b9e8db6 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -1057,13 +1057,14 @@ static int radeonfb_blank (int blank, struct fb_info *info)
return radeon_screen_blank(rinfo, blank, 0);
}
-static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp, struct fb_info *info)
+static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct radeonfb_info *rinfo)
{
- struct radeonfb_info *rinfo = info->par;
u32 pindex;
unsigned int i;
-
+
+
if (regno > 255)
return 1;
@@ -1078,20 +1079,7 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
pindex = regno;
if (!rinfo->asleep) {
- u32 dac_cntl2, vclk_cntl = 0;
-
radeon_fifo_wait(9);
- if (rinfo->is_mobility) {
- vclk_cntl = INPLL(VCLK_ECP_CNTL);
- OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
- }
-
- /* Make sure we are on first palette */
- if (rinfo->has_CRTC2) {
- dac_cntl2 = INREG(DAC_CNTL2);
- dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL;
- OUTREG(DAC_CNTL2, dac_cntl2);
- }
if (rinfo->bpp == 16) {
pindex = regno * 8;
@@ -1101,24 +1089,27 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
if (rinfo->depth == 15 && regno > 31)
return 1;
- /* For 565, the green component is mixed one order below */
+ /* For 565, the green component is mixed one order
+ * below
+ */
if (rinfo->depth == 16) {
OUTREG(PALETTE_INDEX, pindex>>1);
- OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) |
- (green << 8) | (rinfo->palette[regno>>1].blue));
+ OUTREG(PALETTE_DATA,
+ (rinfo->palette[regno>>1].red << 16) |
+ (green << 8) |
+ (rinfo->palette[regno>>1].blue));
green = rinfo->palette[regno<<1].green;
}
}
if (rinfo->depth != 16 || regno < 32) {
OUTREG(PALETTE_INDEX, pindex);
- OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
+ OUTREG(PALETTE_DATA, (red << 16) |
+ (green << 8) | blue);
}
- if (rinfo->is_mobility)
- OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
}
if (regno < 16) {
- u32 *pal = info->pseudo_palette;
+ u32 *pal = rinfo->info->pseudo_palette;
switch (rinfo->depth) {
case 15:
pal[regno] = (regno << 10) | (regno << 5) | regno;
@@ -1138,6 +1129,84 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
return 0;
}
+static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *info)
+{
+ struct radeonfb_info *rinfo = info->par;
+ u32 dac_cntl2, vclk_cntl = 0;
+ int rc;
+
+ if (!rinfo->asleep) {
+ if (rinfo->is_mobility) {
+ vclk_cntl = INPLL(VCLK_ECP_CNTL);
+ OUTPLL(VCLK_ECP_CNTL,
+ vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
+ }
+
+ /* Make sure we are on first palette */
+ if (rinfo->has_CRTC2) {
+ dac_cntl2 = INREG(DAC_CNTL2);
+ dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL;
+ OUTREG(DAC_CNTL2, dac_cntl2);
+ }
+ }
+
+ rc = radeon_setcolreg (regno, red, green, blue, transp, rinfo);
+
+ if (!rinfo->asleep && rinfo->is_mobility)
+ OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
+
+ return rc;
+}
+
+static int radeonfb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
+{
+ struct radeonfb_info *rinfo = info->par;
+ u16 *red, *green, *blue, *transp;
+ u32 dac_cntl2, vclk_cntl = 0;
+ int i, start, rc = 0;
+
+ if (!rinfo->asleep) {
+ if (rinfo->is_mobility) {
+ vclk_cntl = INPLL(VCLK_ECP_CNTL);
+ OUTPLL(VCLK_ECP_CNTL,
+ vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
+ }
+
+ /* Make sure we are on first palette */
+ if (rinfo->has_CRTC2) {
+ dac_cntl2 = INREG(DAC_CNTL2);
+ dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL;
+ OUTREG(DAC_CNTL2, dac_cntl2);
+ }
+ }
+
+ red = cmap->red;
+ green = cmap->green;
+ blue = cmap->blue;
+ transp = cmap->transp;
+ start = cmap->start;
+
+ for (i = 0; i < cmap->len; i++) {
+ u_int hred, hgreen, hblue, htransp = 0xffff;
+
+ hred = *red++;
+ hgreen = *green++;
+ hblue = *blue++;
+ if (transp)
+ htransp = *transp++;
+ rc = radeon_setcolreg (start++, hred, hgreen, hblue, htransp,
+ rinfo);
+ if (rc)
+ break;
+ }
+
+ if (!rinfo->asleep && rinfo->is_mobility)
+ OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
+
+ return rc;
+}
static void radeon_save_state (struct radeonfb_info *rinfo,
struct radeon_regs *save)
@@ -1796,6 +1865,7 @@ static struct fb_ops radeonfb_ops = {
.fb_check_var = radeonfb_check_var,
.fb_set_par = radeonfb_set_par,
.fb_setcolreg = radeonfb_setcolreg,
+ .fb_setcmap = radeonfb_setcmap,
.fb_pan_display = radeonfb_pan_display,
.fb_blank = radeonfb_blank,
.fb_ioctl = radeonfb_ioctl,
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 59e3b4b4e7e..b209adbd508 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -906,10 +906,13 @@ static void fbcon_init(struct vc_data *vc, int init)
struct vc_data *svc = *default_mode;
struct display *t, *p = &fb_display[vc->vc_num];
int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256;
- int cap = info->flags;
+ int cap;
if (info_idx == -1 || info == NULL)
return;
+
+ cap = info->flags;
+
if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
(info->fix.type == FB_TYPE_TEXT))
logo = 0;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 7d1ae06667c..bcf59b28a14 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -337,6 +337,8 @@ static void vgacon_init(struct vc_data *c, int init)
c->vc_scan_lines = vga_scan_lines;
c->vc_font.height = vga_video_font_height;
c->vc_complement_mask = 0x7700;
+ if (vga_512_chars)
+ c->vc_hi_font_mask = 0x0800;
p = *c->vc_uni_pagedir_loc;
if (c->vc_uni_pagedir_loc == &c->vc_uni_pagedir ||
!--c->vc_uni_pagedir_loc[1])
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 8b1b7c687a9..3894b2a501d 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -90,6 +90,8 @@ struct cfb_info {
*/
u_char ramdac_ctrl;
u_char ramdac_powerdown;
+
+ u32 pseudo_palette[16];
};
static char *default_font = "Acorn8x8";
@@ -1223,9 +1225,7 @@ cyberpro_alloc_fb_info(unsigned int id, char *name)
{
struct cfb_info *cfb;
- cfb = kmalloc(sizeof(struct cfb_info) +
- sizeof(u32) * 16, GFP_KERNEL);
-
+ cfb = kmalloc(sizeof(struct cfb_info), GFP_KERNEL);
if (!cfb)
return NULL;
@@ -1281,7 +1281,7 @@ cyberpro_alloc_fb_info(unsigned int id, char *name)
cfb->fb.fbops = &cyber2000fb_ops;
cfb->fb.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
- cfb->fb.pseudo_palette = (void *)(cfb + 1);
+ cfb->fb.pseudo_palette = cfb->pseudo_palette;
fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0);
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index c51f8fb5c1d..4e5ce8f7d65 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -222,8 +222,11 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
transp = cmap->transp;
start = cmap->start;
- if (start < 0 || !info->fbops->fb_setcolreg)
+ if (start < 0 || (!info->fbops->fb_setcolreg &&
+ !info->fbops->fb_setcmap))
return -EINVAL;
+ if (info->fbops->fb_setcmap)
+ return info->fbops->fb_setcmap(cmap, info);
for (i = 0; i < cmap->len; i++) {
hred = *red++;
hgreen = *green++;
@@ -250,8 +253,33 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
transp = cmap->transp;
start = cmap->start;
- if (start < 0 || !info->fbops->fb_setcolreg)
+ if (start < 0 || (!info->fbops->fb_setcolreg &&
+ !info->fbops->fb_setcmap))
return -EINVAL;
+
+ /* If we can batch, do it */
+ if (info->fbops->fb_setcmap && cmap->len > 1) {
+ struct fb_cmap umap;
+ int size = cmap->len * sizeof(u16);
+ int rc;
+
+ memset(&umap, 0, sizeof(struct fb_cmap));
+ rc = fb_alloc_cmap(&umap, cmap->len, transp != NULL);
+ if (rc)
+ return rc;
+ if (copy_from_user(umap.red, red, size) ||
+ copy_from_user(umap.green, green, size) ||
+ copy_from_user(umap.blue, blue, size) ||
+ (transp && copy_from_user(umap.transp, transp, size))) {
+ rc = -EFAULT;
+ }
+ umap.start = start;
+ if (rc == 0)
+ rc = info->fbops->fb_setcmap(&umap, info);
+ fb_dealloc_cmap(&umap);
+ return rc;
+ }
+
for (i = 0; i < cmap->len; i++, red++, blue++, green++) {
if (get_user(hred, red) ||
get_user(hgreen, green) ||
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 25f460ca0da..7705070191d 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1257,6 +1257,8 @@ int fb_new_modelist(struct fb_info *info)
static char *video_options[FB_MAX];
static int ofonly;
+extern const char *global_mode_option;
+
/**
* fb_get_options - get kernel boot parameters
* @name: framebuffer name as it would appear in
@@ -1297,9 +1299,6 @@ int fb_get_options(char *name, char **option)
return retval;
}
-
-extern const char *global_mode_option;
-
/**
* video_setup - process command line options
* @options: string of options
@@ -1313,7 +1312,7 @@ extern const char *global_mode_option;
* Returns zero.
*
*/
-int __init video_setup(char *options)
+static int __init video_setup(char *options)
{
int i, global = 0;
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 978def01358..6cd1976548d 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -34,7 +34,6 @@
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#endif
-#include <video/edid.h>
#include "edid.h"
/*
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 2bdda4010b8..c78a2c5961d 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -354,7 +354,7 @@ static ssize_t show_pan(struct class_device *class_device, char *buf)
fb_info->var.xoffset);
}
-struct class_device_attribute class_device_attrs[] = {
+static struct class_device_attribute class_device_attrs[] = {
__ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp),
__ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank),
__ATTR(color_map, S_IRUGO|S_IWUSR, show_cmap, store_cmap),
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 9ec8781794c..a9a618f2aa6 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -999,8 +999,16 @@ static int i810_check_params(struct fb_var_screeninfo *var,
info->monspecs.dclkmin = 15000000;
if (fb_validate_mode(var, info)) {
- if (fb_get_mode(FB_MAXTIMINGS, 0, var, info))
+ if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) {
+ int default_sync = (info->monspecs.hfmin-HFMIN)
+ |(info->monspecs.hfmax-HFMAX)
+ |(info->monspecs.vfmin-VFMIN)
+ |(info->monspecs.vfmax-VFMAX);
+ printk("i810fb: invalid video mode%s\n",
+ default_sync ? "" :
+ ". Specifying vsyncN/hsyncN parameters may help");
return -EINVAL;
+ }
}
var->xres = xres;
@@ -2023,10 +2031,10 @@ MODULE_PARM_DESC(vyres, "Virtual vertical resolution in scanlines"
" (default = 480)");
module_param(hsync1, int, 0);
MODULE_PARM_DESC(hsync1, "Minimum horizontal frequency of monitor in KHz"
- " (default = 31)");
+ " (default = 29)");
module_param(hsync2, int, 0);
MODULE_PARM_DESC(hsync2, "Maximum horizontal frequency of monitor in KHz"
- " (default = 31)");
+ " (default = 30)");
module_param(vsync1, int, 0);
MODULE_PARM_DESC(vsync1, "Minimum vertical frequency of monitor in Hz"
" (default = 50)");
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index 5a72ca3c013..7b9bf45ab6f 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -1287,12 +1287,12 @@ imsttfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
case FBIMSTT_SETCMAPREG:
if (copy_from_user(reg, argp, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
return -EFAULT;
- write_reg_le32(((u_int *)par->cmap_regs), reg[0], reg[1]);
+ write_reg_le32(((u_int __iomem *)par->cmap_regs), reg[0], reg[1]);
return 0;
case FBIMSTT_GETCMAPREG:
if (copy_from_user(reg, argp, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
return -EFAULT;
- reg[1] = read_reg_le32(((u_int *)par->cmap_regs), reg[0]);
+ reg[1] = read_reg_le32(((u_int __iomem *)par->cmap_regs), reg[0]);
if (copy_to_user((void __user *)(arg + 4), &reg[1], 4))
return -EFAULT;
return 0;
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
new file mode 100644
index 00000000000..8fe1c12a17b
--- /dev/null
+++ b/drivers/video/imxfb.c
@@ -0,0 +1,695 @@
+/*
+ * linux/drivers/video/imxfb.c
+ *
+ * Freescale i.MX Frame Buffer device driver
+ *
+ * Copyright (C) 2004 Sascha Hauer, Pengutronix
+ * Based on acornfb.c Copyright (C) Russell King.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Please direct your questions and comments on this driver to the following
+ * email address:
+ *
+ * linux-arm-kernel@lists.arm.linux.org.uk
+ */
+
+//#define DEBUG 1
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/uaccess.h>
+#include <asm/arch/imxfb.h>
+
+/*
+ * Complain if VAR is out of range.
+ */
+#define DEBUG_VAR 1
+
+#include "imxfb.h"
+
+static struct imxfb_rgb def_rgb_16 = {
+ .red = { .offset = 8, .length = 4, },
+ .green = { .offset = 4, .length = 4, },
+ .blue = { .offset = 0, .length = 4, },
+ .transp = { .offset = 0, .length = 0, },
+};
+
+static struct imxfb_rgb def_rgb_8 = {
+ .red = { .offset = 0, .length = 8, },
+ .green = { .offset = 0, .length = 8, },
+ .blue = { .offset = 0, .length = 8, },
+ .transp = { .offset = 0, .length = 0, },
+};
+
+static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info);
+
+static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+#define LCDC_PALETTE(x) __REG2(IMX_LCDC_BASE+0x800, (x)<<2)
+static int
+imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int trans, struct fb_info *info)
+{
+ struct imxfb_info *fbi = info->par;
+ u_int val, ret = 1;
+
+#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
+ if (regno < fbi->palette_size) {
+ val = (CNVT_TOHW(red, 4) << 8) |
+ (CNVT_TOHW(green,4) << 4) |
+ CNVT_TOHW(blue, 4);
+
+ LCDC_PALETTE(regno) = val;
+ ret = 0;
+ }
+ return ret;
+}
+
+static int
+imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int trans, struct fb_info *info)
+{
+ struct imxfb_info *fbi = info->par;
+ unsigned int val;
+ int ret = 1;
+
+ /*
+ * If inverse mode was selected, invert all the colours
+ * rather than the register number. The register number
+ * is what you poke into the framebuffer to produce the
+ * colour you requested.
+ */
+ if (fbi->cmap_inverse) {
+ red = 0xffff - red;
+ green = 0xffff - green;
+ blue = 0xffff - blue;
+ }
+
+ /*
+ * If greyscale is true, then we convert the RGB value
+ * to greyscale no mater what visual we are using.
+ */
+ if (info->var.grayscale)
+ red = green = blue = (19595 * red + 38470 * green +
+ 7471 * blue) >> 16;
+
+ switch (info->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ /*
+ * 12 or 16-bit True Colour. We encode the RGB value
+ * according to the RGB bitfield information.
+ */
+ if (regno < 16) {
+ u32 *pal = info->pseudo_palette;
+
+ val = chan_to_field(red, &info->var.red);
+ val |= chan_to_field(green, &info->var.green);
+ val |= chan_to_field(blue, &info->var.blue);
+
+ pal[regno] = val;
+ ret = 0;
+ }
+ break;
+
+ case FB_VISUAL_STATIC_PSEUDOCOLOR:
+ case FB_VISUAL_PSEUDOCOLOR:
+ ret = imxfb_setpalettereg(regno, red, green, blue, trans, info);
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * imxfb_check_var():
+ * Round up in the following order: bits_per_pixel, xres,
+ * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
+ * bitfields, horizontal timing, vertical timing.
+ */
+static int
+imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct imxfb_info *fbi = info->par;
+ int rgbidx;
+
+ if (var->xres < MIN_XRES)
+ var->xres = MIN_XRES;
+ if (var->yres < MIN_YRES)
+ var->yres = MIN_YRES;
+ if (var->xres > fbi->max_xres)
+ var->xres = fbi->max_xres;
+ if (var->yres > fbi->max_yres)
+ var->yres = fbi->max_yres;
+ var->xres_virtual = max(var->xres_virtual, var->xres);
+ var->yres_virtual = max(var->yres_virtual, var->yres);
+
+ pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
+ switch (var->bits_per_pixel) {
+ case 16:
+ rgbidx = RGB_16;
+ break;
+ case 8:
+ rgbidx = RGB_8;
+ break;
+ default:
+ rgbidx = RGB_16;
+ }
+
+ /*
+ * Copy the RGB parameters for this display
+ * from the machine specific parameters.
+ */
+ var->red = fbi->rgb[rgbidx]->red;
+ var->green = fbi->rgb[rgbidx]->green;
+ var->blue = fbi->rgb[rgbidx]->blue;
+ var->transp = fbi->rgb[rgbidx]->transp;
+
+ pr_debug("RGBT length = %d:%d:%d:%d\n",
+ var->red.length, var->green.length, var->blue.length,
+ var->transp.length);
+
+ pr_debug("RGBT offset = %d:%d:%d:%d\n",
+ var->red.offset, var->green.offset, var->blue.offset,
+ var->transp.offset);
+
+ return 0;
+}
+
+/*
+ * imxfb_set_par():
+ * Set the user defined part of the display for the specified console
+ */
+static int imxfb_set_par(struct fb_info *info)
+{
+ struct imxfb_info *fbi = info->par;
+ struct fb_var_screeninfo *var = &info->var;
+
+ pr_debug("set_par\n");
+
+ if (var->bits_per_pixel == 16)
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ else if (!fbi->cmap_static)
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ else {
+ /*
+ * Some people have weird ideas about wanting static
+ * pseudocolor maps. I suspect their user space
+ * applications are broken.
+ */
+ info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
+ }
+
+ info->fix.line_length = var->xres_virtual *
+ var->bits_per_pixel / 8;
+ fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16;
+
+ imxfb_activate_var(var, info);
+
+ return 0;
+}
+
+static void imxfb_enable_controller(struct imxfb_info *fbi)
+{
+ pr_debug("Enabling LCD controller\n");
+
+ /* initialize LCDC */
+ LCDC_RMCR &= ~RMCR_LCDC_EN; /* just to be safe... */
+
+ LCDC_SSA = fbi->screen_dma;
+ /* physical screen start address */
+ LCDC_VPW = VPW_VPW(fbi->max_xres * fbi->max_bpp / 8 / 4);
+
+ LCDC_POS = 0x00000000; /* panning offset 0 (0 pixel offset) */
+
+ /* disable hardware cursor */
+ LCDC_CPOS &= ~(CPOS_CC0 | CPOS_CC1);
+
+ /* fixed burst length (see erratum 11) */
+ LCDC_DMACR = DMACR_BURST | DMACR_HM(8) | DMACR_TM(2);
+
+ LCDC_RMCR = RMCR_LCDC_EN;
+
+ if(fbi->backlight_power)
+ fbi->backlight_power(1);
+ if(fbi->lcd_power)
+ fbi->lcd_power(1);
+}
+
+static void imxfb_disable_controller(struct imxfb_info *fbi)
+{
+ pr_debug("Disabling LCD controller\n");
+
+ if(fbi->backlight_power)
+ fbi->backlight_power(0);
+ if(fbi->lcd_power)
+ fbi->lcd_power(0);
+
+ LCDC_RMCR = 0;
+}
+
+static int imxfb_blank(int blank, struct fb_info *info)
+{
+ struct imxfb_info *fbi = info->par;
+
+ pr_debug("imxfb_blank: blank=%d\n", blank);
+
+ switch (blank) {
+ case FB_BLANK_POWERDOWN:
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_NORMAL:
+ imxfb_disable_controller(fbi);
+ break;
+
+ case FB_BLANK_UNBLANK:
+ imxfb_enable_controller(fbi);
+ break;
+ }
+ return 0;
+}
+
+static struct fb_ops imxfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = imxfb_check_var,
+ .fb_set_par = imxfb_set_par,
+ .fb_setcolreg = imxfb_setcolreg,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_blank = imxfb_blank,
+ .fb_cursor = soft_cursor, /* FIXME: i.MX can do hardware cursor */
+};
+
+/*
+ * imxfb_activate_var():
+ * Configures LCD Controller based on entries in var parameter. Settings are
+ * only written to the controller if changes were made.
+ */
+static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct imxfb_info *fbi = info->par;
+ pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",
+ var->xres, var->hsync_len,
+ var->left_margin, var->right_margin);
+ pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n",
+ var->yres, var->vsync_len,
+ var->upper_margin, var->lower_margin);
+
+#if DEBUG_VAR
+ if (var->xres < 16 || var->xres > 1024)
+ printk(KERN_ERR "%s: invalid xres %d\n",
+ info->fix.id, var->xres);
+ if (var->hsync_len < 1 || var->hsync_len > 64)
+ printk(KERN_ERR "%s: invalid hsync_len %d\n",
+ info->fix.id, var->hsync_len);
+ if (var->left_margin > 255)
+ printk(KERN_ERR "%s: invalid left_margin %d\n",
+ info->fix.id, var->left_margin);
+ if (var->right_margin > 255)
+ printk(KERN_ERR "%s: invalid right_margin %d\n",
+ info->fix.id, var->right_margin);
+ if (var->yres < 1 || var->yres > 511)
+ printk(KERN_ERR "%s: invalid yres %d\n",
+ info->fix.id, var->yres);
+ if (var->vsync_len > 100)
+ printk(KERN_ERR "%s: invalid vsync_len %d\n",
+ info->fix.id, var->vsync_len);
+ if (var->upper_margin > 63)
+ printk(KERN_ERR "%s: invalid upper_margin %d\n",
+ info->fix.id, var->upper_margin);
+ if (var->lower_margin > 255)
+ printk(KERN_ERR "%s: invalid lower_margin %d\n",
+ info->fix.id, var->lower_margin);
+#endif
+
+ LCDC_HCR = HCR_H_WIDTH(var->hsync_len) |
+ HCR_H_WAIT_1(var->left_margin) |
+ HCR_H_WAIT_2(var->right_margin);
+
+ LCDC_VCR = VCR_V_WIDTH(var->vsync_len) |
+ VCR_V_WAIT_1(var->upper_margin) |
+ VCR_V_WAIT_2(var->lower_margin);
+
+ LCDC_SIZE = SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres);
+ LCDC_PCR = fbi->pcr;
+ LCDC_PWMR = fbi->pwmr;
+ LCDC_LSCR1 = fbi->lscr1;
+
+ return 0;
+}
+
+static void imxfb_setup_gpio(struct imxfb_info *fbi)
+{
+ int width;
+
+ LCDC_RMCR &= ~(RMCR_LCDC_EN | RMCR_SELF_REF);
+
+ if( fbi->pcr & PCR_TFT )
+ width = 16;
+ else
+ width = 1 << ((fbi->pcr >> 28) & 0x3);
+
+ switch(width) {
+ case 16:
+ imx_gpio_mode(PD30_PF_LD15);
+ imx_gpio_mode(PD29_PF_LD14);
+ imx_gpio_mode(PD28_PF_LD13);
+ imx_gpio_mode(PD27_PF_LD12);
+ imx_gpio_mode(PD26_PF_LD11);
+ imx_gpio_mode(PD25_PF_LD10);
+ imx_gpio_mode(PD24_PF_LD9);
+ imx_gpio_mode(PD23_PF_LD8);
+ case 8:
+ imx_gpio_mode(PD22_PF_LD7);
+ imx_gpio_mode(PD21_PF_LD6);
+ imx_gpio_mode(PD20_PF_LD5);
+ imx_gpio_mode(PD19_PF_LD4);
+ case 4:
+ imx_gpio_mode(PD18_PF_LD3);
+ imx_gpio_mode(PD17_PF_LD2);
+ case 2:
+ imx_gpio_mode(PD16_PF_LD1);
+ case 1:
+ imx_gpio_mode(PD15_PF_LD0);
+ }
+
+ /* initialize GPIOs */
+ imx_gpio_mode(PD6_PF_LSCLK);
+ imx_gpio_mode(PD10_PF_SPL_SPR);
+ imx_gpio_mode(PD11_PF_CONTRAST);
+ imx_gpio_mode(PD14_PF_FLM_VSYNC);
+ imx_gpio_mode(PD13_PF_LP_HSYNC);
+ imx_gpio_mode(PD7_PF_REV);
+ imx_gpio_mode(PD8_PF_CLS);
+
+#ifndef CONFIG_MACH_PIMX1
+ /* on PiMX1 used as buffers enable signal
+ */
+ imx_gpio_mode(PD9_PF_PS);
+#endif
+
+#ifndef CONFIG_MACH_MX1FS2
+ /* on mx1fs2 this pin is used to (de)activate the display, so we need
+ * it as a normal gpio
+ */
+ imx_gpio_mode(PD12_PF_ACD_OE);
+#endif
+
+}
+
+#ifdef CONFIG_PM
+/*
+ * Power management hooks. Note that we won't be called from IRQ context,
+ * unlike the blank functions above, so we may sleep.
+ */
+static int imxfb_suspend(struct device *dev, u32 state, u32 level)
+{
+ struct imxfb_info *fbi = dev_get_drvdata(dev);
+ pr_debug("%s\n",__FUNCTION__);
+
+ if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN)
+ imxfb_disable_controller(fbi);
+ return 0;
+}
+
+static int imxfb_resume(struct device *dev, u32 level)
+{
+ struct imxfb_info *fbi = dev_get_drvdata(dev);
+ pr_debug("%s\n",__FUNCTION__);
+
+ if (level == RESUME_ENABLE)
+ imxfb_enable_controller(fbi);
+ return 0;
+}
+#else
+#define imxfb_suspend NULL
+#define imxfb_resume NULL
+#endif
+
+static int __init imxfb_init_fbinfo(struct device *dev)
+{
+ struct imxfb_mach_info *inf = dev->platform_data;
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct imxfb_info *fbi = info->par;
+
+ pr_debug("%s\n",__FUNCTION__);
+
+ info->pseudo_palette = kmalloc( sizeof(u32) * 16, GFP_KERNEL);
+ if (!info->pseudo_palette)
+ return -ENOMEM;
+
+ memset(fbi, 0, sizeof(struct imxfb_info));
+ fbi->dev = dev;
+
+ strlcpy(info->fix.id, IMX_NAME, sizeof(info->fix.id));
+
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.type_aux = 0;
+ info->fix.xpanstep = 0;
+ info->fix.ypanstep = 0;
+ info->fix.ywrapstep = 0;
+ info->fix.accel = FB_ACCEL_NONE;
+
+ info->var.nonstd = 0;
+ info->var.activate = FB_ACTIVATE_NOW;
+ info->var.height = -1;
+ info->var.width = -1;
+ info->var.accel_flags = 0;
+ info->var.vmode = FB_VMODE_NONINTERLACED;
+
+ info->fbops = &imxfb_ops;
+ info->flags = FBINFO_FLAG_DEFAULT;
+ info->pseudo_palette = (fbi + 1);
+
+ fbi->rgb[RGB_16] = &def_rgb_16;
+ fbi->rgb[RGB_8] = &def_rgb_8;
+
+ fbi->max_xres = inf->xres;
+ info->var.xres = inf->xres;
+ info->var.xres_virtual = inf->xres;
+ fbi->max_yres = inf->yres;
+ info->var.yres = inf->yres;
+ info->var.yres_virtual = inf->yres;
+ fbi->max_bpp = inf->bpp;
+ info->var.bits_per_pixel = inf->bpp;
+ info->var.pixclock = inf->pixclock;
+ info->var.hsync_len = inf->hsync_len;
+ info->var.left_margin = inf->left_margin;
+ info->var.right_margin = inf->right_margin;
+ info->var.vsync_len = inf->vsync_len;
+ info->var.upper_margin = inf->upper_margin;
+ info->var.lower_margin = inf->lower_margin;
+ info->var.sync = inf->sync;
+ info->var.grayscale = inf->cmap_greyscale;
+ fbi->cmap_inverse = inf->cmap_inverse;
+ fbi->pcr = inf->pcr;
+ fbi->lscr1 = inf->lscr1;
+ fbi->pwmr = inf->pwmr;
+ fbi->lcd_power = inf->lcd_power;
+ fbi->backlight_power = inf->backlight_power;
+ info->fix.smem_len = fbi->max_xres * fbi->max_yres *
+ fbi->max_bpp / 8;
+
+ return 0;
+}
+
+/*
+ * Allocates the DRAM memory for the frame buffer. This buffer is
+ * remapped into a non-cached, non-buffered, memory region to
+ * allow pixel writes to occur without flushing the cache.
+ * Once this area is remapped, all virtual memory access to the
+ * video memory should occur at the new region.
+ */
+static int __init imxfb_map_video_memory(struct fb_info *info)
+{
+ struct imxfb_info *fbi = info->par;
+
+ fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
+ fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size,
+ &fbi->map_dma,GFP_KERNEL);
+
+ if (fbi->map_cpu) {
+ info->screen_base = fbi->map_cpu;
+ fbi->screen_cpu = fbi->map_cpu;
+ fbi->screen_dma = fbi->map_dma;
+ info->fix.smem_start = fbi->screen_dma;
+ }
+
+ return fbi->map_cpu ? 0 : -ENOMEM;
+}
+
+static int __init imxfb_probe(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct imxfb_info *fbi;
+ struct fb_info *info;
+ struct imxfb_mach_info *inf;
+ struct resource *res;
+ int ret;
+
+ printk("i.MX Framebuffer driver\n");
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if(!res)
+ return -ENODEV;
+
+ inf = dev->platform_data;
+ if(!inf) {
+ dev_err(dev,"No platform_data available\n");
+ return -ENOMEM;
+ }
+
+ info = framebuffer_alloc(sizeof(struct imxfb_info), dev);
+ if(!info)
+ return -ENOMEM;
+
+ fbi = info->par;
+
+ dev_set_drvdata(dev, info);
+
+ ret = imxfb_init_fbinfo(dev);
+ if( ret < 0 )
+ goto failed_init;
+
+ res = request_mem_region(res->start, res->end - res->start + 1, "IMXFB");
+ if (!res) {
+ ret = -EBUSY;
+ goto failed_regs;
+ }
+
+ if (!inf->fixed_screen_cpu) {
+ ret = imxfb_map_video_memory(info);
+ if (ret) {
+ dev_err(dev, "Failed to allocate video RAM: %d\n", ret);
+ ret = -ENOMEM;
+ goto failed_map;
+ }
+ } else {
+ /* Fixed framebuffer mapping enables location of the screen in eSRAM */
+ fbi->map_cpu = inf->fixed_screen_cpu;
+ fbi->map_dma = inf->fixed_screen_dma;
+ info->screen_base = fbi->map_cpu;
+ fbi->screen_cpu = fbi->map_cpu;
+ fbi->screen_dma = fbi->map_dma;
+ info->fix.smem_start = fbi->screen_dma;
+ }
+
+ /*
+ * This makes sure that our colour bitfield
+ * descriptors are correctly initialised.
+ */
+ imxfb_check_var(&info->var, info);
+
+ ret = fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0);
+ if (ret < 0)
+ goto failed_cmap;
+
+ imxfb_setup_gpio(fbi);
+
+ imxfb_set_par(info);
+ ret = register_framebuffer(info);
+ if (ret < 0) {
+ dev_err(dev, "failed to register framebuffer\n");
+ goto failed_register;
+ }
+
+ imxfb_enable_controller(fbi);
+
+ return 0;
+
+failed_register:
+ fb_dealloc_cmap(&info->cmap);
+failed_cmap:
+ if (!inf->fixed_screen_cpu)
+ dma_free_writecombine(dev,fbi->map_size,fbi->map_cpu,
+ fbi->map_dma);
+failed_map:
+ kfree(info->pseudo_palette);
+failed_regs:
+ release_mem_region(res->start, res->end - res->start);
+failed_init:
+ dev_set_drvdata(dev, NULL);
+ framebuffer_release(info);
+ return ret;
+}
+
+static int imxfb_remove(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ /* disable LCD controller */
+ LCDC_RMCR &= ~RMCR_LCDC_EN;
+
+ unregister_framebuffer(info);
+
+ fb_dealloc_cmap(&info->cmap);
+ kfree(info->pseudo_palette);
+ framebuffer_release(info);
+
+ release_mem_region(res->start, res->end - res->start + 1);
+ dev_set_drvdata(dev, NULL);
+
+ return 0;
+}
+
+void imxfb_shutdown(struct device * dev)
+{
+ /* disable LCD Controller */
+ LCDC_RMCR &= ~RMCR_LCDC_EN;
+}
+
+static struct device_driver imxfb_driver = {
+ .name = "imx-fb",
+ .bus = &platform_bus_type,
+ .probe = imxfb_probe,
+ .suspend = imxfb_suspend,
+ .resume = imxfb_resume,
+ .remove = imxfb_remove,
+ .shutdown = imxfb_shutdown,
+};
+
+int __init imxfb_init(void)
+{
+ return driver_register(&imxfb_driver);
+}
+
+static void __exit imxfb_cleanup(void)
+{
+ driver_unregister(&imxfb_driver);
+}
+
+module_init(imxfb_init);
+module_exit(imxfb_cleanup);
+
+MODULE_DESCRIPTION("Motorola i.MX framebuffer driver");
+MODULE_AUTHOR("Sascha Hauer, Pengutronix");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/imxfb.h b/drivers/video/imxfb.h
new file mode 100644
index 00000000000..128c3ee515c
--- /dev/null
+++ b/drivers/video/imxfb.h
@@ -0,0 +1,72 @@
+/*
+ * linux/drivers/video/imxfb.h
+ *
+ * Freescale i.MX Frame Buffer device driver
+ *
+ * Copyright (C) 2004 S.Hauer, Pengutronix
+ *
+ * Copyright (C) 1999 Eric A. Thomas
+ * Based on acornfb.c Copyright (C) Russell King.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * These are the bitfields for each
+ * display depth that we support.
+ */
+struct imxfb_rgb {
+ struct fb_bitfield red;
+ struct fb_bitfield green;
+ struct fb_bitfield blue;
+ struct fb_bitfield transp;
+};
+
+#define RGB_16 (0)
+#define RGB_8 (1)
+#define NR_RGB 2
+
+struct imxfb_info {
+ struct device *dev;
+ struct imxfb_rgb *rgb[NR_RGB];
+
+ u_int max_bpp;
+ u_int max_xres;
+ u_int max_yres;
+
+ /*
+ * These are the addresses we mapped
+ * the framebuffer memory region to.
+ */
+ dma_addr_t map_dma;
+ u_char * map_cpu;
+ u_int map_size;
+
+ u_char * screen_cpu;
+ dma_addr_t screen_dma;
+ u_int palette_size;
+
+ dma_addr_t dbar1;
+ dma_addr_t dbar2;
+
+ u_int pcr;
+ u_int pwmr;
+ u_int lscr1;
+ u_int cmap_inverse:1,
+ cmap_static:1,
+ unused:30;
+
+ void (*lcd_power)(int);
+ void (*backlight_power)(int);
+};
+
+#define IMX_NAME "IMX"
+
+/*
+ * Minimum X and Y resolutions
+ */
+#define MIN_XRES 64
+#define MIN_YRES 64
+
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 6a05b700083..549e2293926 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -135,9 +135,45 @@
#endif
#include "intelfb.h"
-#include "intelfbdrv.h"
#include "intelfbhw.h"
+static void __devinit get_initial_mode(struct intelfb_info *dinfo);
+static void update_dinfo(struct intelfb_info *dinfo,
+ struct fb_var_screeninfo *var);
+static int intelfb_get_fix(struct fb_fix_screeninfo *fix,
+ struct fb_info *info);
+
+static int intelfb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info);
+static int intelfb_set_par(struct fb_info *info);
+static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *info);
+
+static int intelfb_blank(int blank, struct fb_info *info);
+static int intelfb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info);
+
+static void intelfb_fillrect(struct fb_info *info,
+ const struct fb_fillrect *rect);
+static void intelfb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *region);
+static void intelfb_imageblit(struct fb_info *info,
+ const struct fb_image *image);
+static int intelfb_cursor(struct fb_info *info,
+ struct fb_cursor *cursor);
+
+static int intelfb_sync(struct fb_info *info);
+
+static int intelfb_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg,
+ struct fb_info *info);
+
+static int __devinit intelfb_pci_register(struct pci_dev *pdev,
+ const struct pci_device_id *ent);
+static void __devexit intelfb_pci_unregister(struct pci_dev *pdev);
+static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo);
+
/*
* Limiting the class to PCI_CLASS_DISPLAY_VGA prevents function 1 of the
* mobile chipsets from being registered.
diff --git a/drivers/video/intelfb/intelfbdrv.h b/drivers/video/intelfb/intelfbdrv.h
deleted file mode 100644
index cc305812888..00000000000
--- a/drivers/video/intelfb/intelfbdrv.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef _INTELFBDRV_H
-#define _INTELFBDRV_H
-
-/*
- ******************************************************************************
- * intelfb
- *
- * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G
- * integrated graphics chips.
- *
- * Copyright © 2004 Sylvain Meyer
- *
- * Author: Sylvain Meyer
- *
- ******************************************************************************
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-static void __devinit get_initial_mode(struct intelfb_info *dinfo);
-static void update_dinfo(struct intelfb_info *dinfo,
- struct fb_var_screeninfo *var);
-static int intelfb_get_fix(struct fb_fix_screeninfo *fix,
- struct fb_info *info);
-
-static int intelfb_check_var(struct fb_var_screeninfo *var,
- struct fb_info *info);
-static int intelfb_set_par(struct fb_info *info);
-static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info);
-
-static int intelfb_blank(int blank, struct fb_info *info);
-static int intelfb_pan_display(struct fb_var_screeninfo *var,
- struct fb_info *info);
-
-static void intelfb_fillrect(struct fb_info *info,
- const struct fb_fillrect *rect);
-static void intelfb_copyarea(struct fb_info *info,
- const struct fb_copyarea *region);
-static void intelfb_imageblit(struct fb_info *info,
- const struct fb_image *image);
-static int intelfb_cursor(struct fb_info *info,
- struct fb_cursor *cursor);
-
-static int intelfb_sync(struct fb_info *info);
-
-static int intelfb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- struct fb_info *info);
-
-static int __devinit intelfb_pci_register(struct pci_dev *pdev,
- const struct pci_device_id *ent);
-static void __devexit intelfb_pci_unregister(struct pci_dev *pdev);
-static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo);
-
-#endif
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index 849b47b210e..6ba10e3acef 100644
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -45,7 +45,7 @@ config LOGO_SGI_CLUT224
config LOGO_SUN_CLUT224
bool "224-color Sun Linux logo"
- depends on LOGO && (SPARC || SPARC64)
+ depends on LOGO && (SPARC32 || SPARC64)
default y
config LOGO_SUPERH_MONO
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 3a6555a8aaa..47733f58153 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -408,6 +408,7 @@ static int hwcur __devinitdata = 0;
static int noaccel __devinitdata = 0;
static int noscale __devinitdata = 0;
static int paneltweak __devinitdata = 0;
+static int vram __devinitdata = 0;
#ifdef CONFIG_MTRR
static int nomtrr __devinitdata = 0;
#endif
@@ -1180,7 +1181,7 @@ static int nvidiafb_check_var(struct fb_var_screeninfo *var,
var->xres_virtual = (var->xres_virtual + 63) & ~63;
- vramlen = info->fix.smem_len;
+ vramlen = info->screen_size;
pitch = ((var->xres_virtual * var->bits_per_pixel) + 7) / 8;
memlen = pitch * var->yres_virtual;
@@ -1343,7 +1344,7 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
/* maximize virtual vertical length */
lpitch = info->var.xres_virtual *
((info->var.bits_per_pixel + 7) >> 3);
- info->var.yres_virtual = info->fix.smem_len / lpitch;
+ info->var.yres_virtual = info->screen_size / lpitch;
info->pixmap.scan_align = 4;
info->pixmap.buf_align = 4;
@@ -1507,12 +1508,20 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
par->FbAddress = nvidiafb_fix.smem_start;
par->FbMapSize = par->RamAmountKBytes * 1024;
+ if (vram && vram * 1024 * 1024 < par->FbMapSize)
+ par->FbMapSize = vram * 1024 * 1024;
+
+ /* Limit amount of vram to 64 MB */
+ if (par->FbMapSize > 64 * 1024 * 1024)
+ par->FbMapSize = 64 * 1024 * 1024;
+
par->FbUsableSize = par->FbMapSize - (128 * 1024);
par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 :
16 * 1024;
par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize);
- nvidiafb_fix.smem_len = par->FbUsableSize;
+ info->screen_size = par->FbUsableSize;
+ nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;
if (!info->screen_base) {
printk(KERN_ERR PFX "cannot ioremap FB base\n");
@@ -1524,7 +1533,8 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
#ifdef CONFIG_MTRR
if (!nomtrr) {
par->mtrr.vram = mtrr_add(nvidiafb_fix.smem_start,
- par->FbMapSize, MTRR_TYPE_WRCOMB, 1);
+ par->RamAmountKBytes * 1024,
+ MTRR_TYPE_WRCOMB, 1);
if (par->mtrr.vram < 0) {
printk(KERN_ERR PFX "unable to setup MTRR\n");
} else {
@@ -1566,9 +1576,9 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
err_out_iounmap_fb:
iounmap(info->screen_base);
+ err_out_free_base1:
fb_destroy_modedb(info->monspecs.modedb);
nvidia_delete_i2c_busses(par);
- err_out_free_base1:
iounmap(par->REGS);
err_out_free_base0:
pci_release_regions(pd);
@@ -1645,6 +1655,8 @@ static int __devinit nvidiafb_setup(char *options)
noscale = 1;
} else if (!strncmp(this_opt, "paneltweak:", 11)) {
paneltweak = simple_strtoul(this_opt+11, NULL, 0);
+ } else if (!strncmp(this_opt, "vram:", 5)) {
+ vram = simple_strtoul(this_opt+5, NULL, 0);
#ifdef CONFIG_MTRR
} else if (!strncmp(this_opt, "nomtrr", 6)) {
nomtrr = 1;
@@ -1716,6 +1728,10 @@ module_param(forceCRTC, int, 0);
MODULE_PARM_DESC(forceCRTC,
"Forces usage of a particular CRTC in case autodetection "
"fails. (0 or 1) (default=autodetect)");
+module_param(vram, int, 0);
+MODULE_PARM_DESC(vram,
+ "amount of framebuffer memory to remap in MiB"
+ "(default=0 - remap entire memory)");
#ifdef CONFIG_MTRR
module_param(nomtrr, bool, 0);
MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) "
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
index d9a084e77a6..c46387024b1 100644
--- a/drivers/video/radeonfb.c
+++ b/drivers/video/radeonfb.c
@@ -2107,7 +2107,7 @@ static void radeon_write_mode (struct radeonfb_info *rinfo,
if (rinfo->arch == RADEON_M6) {
- for (i=0; i<8; i++)
+ for (i=0; i<7; i++)
OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val);
} else {
for (i=0; i<9; i++)
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 5bb8d60f35c..03d74e8ee06 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -1498,7 +1498,7 @@ static int __devinit savage_map_mmio (struct fb_info *info)
info->fix.mmio_start = par->mmio.pbase;
info->fix.mmio_len = par->mmio.len;
- par->bci_base = (u32*)(par->mmio.vbase + BCI_BUFFER_OFFSET);
+ par->bci_base = (u32 __iomem *)(par->mmio.vbase + BCI_BUFFER_OFFSET);
par->bci_ptr = 0;
savage_enable_mmio (par);
@@ -1514,7 +1514,7 @@ static void __devinit savage_unmap_mmio (struct fb_info *info)
savage_disable_mmio(par);
if (par->mmio.vbase) {
- iounmap ((void *)par->mmio.vbase);
+ iounmap(par->mmio.vbase);
par->mmio.vbase = NULL;
}
}
@@ -1553,7 +1553,7 @@ static int __devinit savage_map_video (struct fb_info *info,
#endif
/* Clear framebuffer, it's all white in memory after boot */
- memset (par->video.vbase, 0, par->video.len);
+ memset_io (par->video.vbase, 0, par->video.len);
return 0;
}
diff --git a/drivers/video/sis/init.c b/drivers/video/sis/init.c
index 1994054d45f..ecfd72178db 100644
--- a/drivers/video/sis/init.c
+++ b/drivers/video/sis/init.c
@@ -1384,7 +1384,7 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/* HELPER: SetLVDSetc */
/*********************************************/
-void
+static void
SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
USHORT temp;
@@ -1625,7 +1625,7 @@ SiS_ResetSegmentRegisters(SiS_Private *SiS_Pr,PSIS_HW_INFO HwInfo)
/* HELPER: GetVBType */
/*********************************************/
-void
+static void
SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
USHORT flag=0, rev=0, nolcd=0, p4_0f, p4_25, p4_27;
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h
index 35030d30043..7e36b7ac147 100644
--- a/drivers/video/sis/init.h
+++ b/drivers/video/sis/init.h
@@ -2394,11 +2394,9 @@ void SiS_SetRegOR(SISIOADDRESS Port,USHORT Index, USHORT DataOR);
void SiS_DisplayOn(SiS_Private *SiS_Pr);
void SiS_DisplayOff(SiS_Private *SiS_Pr);
void SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
-void SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
BOOLEAN SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
-void SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
BOOLEAN SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex);
UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
@@ -2444,7 +2442,6 @@ extern void SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT Mod
extern void SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
extern void SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
extern void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-extern void SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
extern void SiS_DisableBridge(SiS_Private *, PSIS_HW_INFO);
extern BOOLEAN SiS_SetCRT2Group(SiS_Private *, PSIS_HW_INFO, USHORT);
extern USHORT SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
index 2bc5b809791..274dacd54bb 100644
--- a/drivers/video/sis/init301.c
+++ b/drivers/video/sis/init301.c
@@ -86,6 +86,7 @@
#define SiS_I2CDELAYSHORT 150
static USHORT SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr);
+static void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx);
/*********************************************/
/* HELPER: Lock/Unlock CRT2 */
@@ -100,7 +101,7 @@ SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
}
-void
+static void
SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
if(HwInfo->jChipType >= SIS_315H)
@@ -4236,7 +4237,7 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
* from outside the context of a mode switch!
* MUST call getVBType before calling this
*/
-void
+static void
SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
USHORT temp=0,tempah;
@@ -9219,7 +9220,7 @@ SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
SiS_SetChReg(SiS_Pr, tempbx, 0);
}
-void
+static void
SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
{
if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
@@ -9323,7 +9324,7 @@ SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
/* Read from Chrontel 70xx */
/* Parameter is [Register no (S7-S0)] */
-USHORT
+static USHORT
SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
{
if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h
index f05aebc994b..f84eb54164a 100644
--- a/drivers/video/sis/init301.h
+++ b/drivers/video/sis/init301.h
@@ -293,7 +293,6 @@ static UCHAR SiS300_TrumpionData[7][80] = {
#endif
void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
void SiS_EnableCRT2(SiS_Private *SiS_Pr);
USHORT SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
void SiS_WaitRetrace1(SiS_Private *SiS_Pr);
@@ -310,7 +309,6 @@ USHORT SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
USHORT SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
void SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
BOOLEAN SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo);
void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
@@ -319,8 +317,6 @@ void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
-void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
void SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
#ifdef SIS315H
static void SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index b773c98f651..69826603681 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4762,7 +4762,8 @@ static void __devinit sisfb_post_sis315330(struct pci_dev *pdev)
#endif
-int __devinit sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int __devinit sisfb_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct sisfb_chip_info *chipinfo = &sisfb_chip_info[ent->driver_data];
struct sis_video_info *ivideo = NULL;
@@ -5940,7 +5941,7 @@ MODULE_PARM_DESC(videoram,
#endif
#endif
-int __devinit sisfb_init_module(void)
+static int __devinit sisfb_init_module(void)
{
sisfb_setdefaultparms();
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index e2fa9e1ddc3..1986a8b3833 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -36,6 +36,7 @@ static int tcx_blank(int, struct fb_info *);
static int tcx_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
static int tcx_ioctl(struct inode *, struct file *, unsigned int,
unsigned long, struct fb_info *);
+static int tcx_pan_display(struct fb_var_screeninfo *, struct fb_info *);
/*
* Frame buffer operations
@@ -45,6 +46,7 @@ static struct fb_ops tcx_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = tcx_setcolreg,
.fb_blank = tcx_blank,
+ .fb_pan_display = tcx_pan_display,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
@@ -153,6 +155,12 @@ static void tcx_reset (struct fb_info *info)
spin_unlock_irqrestore(&par->lock, flags);
}
+static int tcx_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ tcx_reset(info);
+ return 0;
+}
+
/**
* tcx_setcolreg - Optional function. Sets a color register.
* @regno: boolean, 0 copy local, 1 get_user() function
@@ -366,6 +374,9 @@ static void tcx_init_one(struct sbus_dev *sdev)
all->par.lowdepth = prom_getbool(sdev->prom_node, "tcx-8-bit");
sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+ all->info.var.red.length = 8;
+ all->info.var.green.length = 8;
+ all->info.var.blue.length = 8;
linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
all->info.var.xres);
@@ -439,6 +450,7 @@ static void tcx_init_one(struct sbus_dev *sdev)
return;
}
+ fb_set_cmap(&all->info.cmap, &all->info);
tcx_init_fix(&all->info, linebytes);
if (register_framebuffer(&all->info) < 0) {
@@ -466,7 +478,7 @@ int __init tcx_init(void)
return -ENODEV;
for_all_sbusdev(sdev, sbus) {
- if (!strcmp(sdev->prom_name, "tcx"))
+ if (!strcmp(sdev->prom_name, "SUNW,tcx"))
tcx_init_one(sdev);
}
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index c34ba39b6f7..7044226c5d4 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -317,30 +317,49 @@ static inline void do_setpalentry(struct tdfx_par *par, unsigned regno, u32 c)
static u32 do_calc_pll(int freq, int* freq_out)
{
- int m, n, k, best_m, best_n, best_k, f_cur, best_error;
+ int m, n, k, best_m, best_n, best_k, best_error;
int fref = 14318;
- /* this really could be done with more intelligence --
- 255*63*4 = 64260 iterations is silly */
best_error = freq;
best_n = best_m = best_k = 0;
- for (n = 1; n < 256; n++) {
- for (m = 1; m < 64; m++) {
- for (k = 0; k < 4; k++) {
- f_cur = fref*(n + 2)/(m + 2)/(1 << k);
- if (abs(f_cur - freq) < best_error) {
- best_error = abs(f_cur-freq);
- best_n = n;
- best_m = m;
- best_k = k;
+
+ for (k = 3; k >= 0; k--) {
+ for (m = 63; m >= 0; m--) {
+ /*
+ * Estimate value of n that produces target frequency
+ * with current m and k
+ */
+ int n_estimated = (freq * (m + 2) * (1 << k) / fref) - 2;
+
+ /* Search neighborhood of estimated n */
+ for (n = max(0, n_estimated - 1);
+ n <= min(255, n_estimated + 1); n++) {
+ /*
+ * Calculate PLL freqency with current m, k and
+ * estimated n
+ */
+ int f = fref * (n + 2) / (m + 2) / (1 << k);
+ int error = abs (f - freq);
+
+ /*
+ * If this is the closest we've come to the
+ * target frequency then remember n, m and k
+ */
+ if (error < best_error) {
+ best_error = error;
+ best_n = n;
+ best_m = m;
+ best_k = k;
}
}
}
}
+
n = best_n;
m = best_m;
k = best_k;
*freq_out = fref*(n + 2)/(m + 2)/(1 << k);
+
return (n << 8) | (m << 2) | k;
}
@@ -411,36 +430,35 @@ static void do_write_regs(struct fb_info *info, struct banshee_reg* reg)
static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id)
{
- u32 draminit0 = 0;
- u32 draminit1 = 0;
- u32 miscinit1 = 0;
- u32 lfbsize = 0;
- int sgram_p = 0;
+ u32 draminit0;
+ u32 draminit1;
+ u32 miscinit1;
+
+ int num_chips;
+ int chip_size; /* in MB */
+ u32 lfbsize;
+ int has_sgram;
draminit0 = tdfx_inl(par, DRAMINIT0);
draminit1 = tdfx_inl(par, DRAMINIT1);
+
+ num_chips = (draminit0 & DRAMINIT0_SGRAM_NUM) ? 8 : 4;
- if ((dev_id == PCI_DEVICE_ID_3DFX_BANSHEE) ||
- (dev_id == PCI_DEVICE_ID_3DFX_VOODOO3)) {
- sgram_p = (draminit1 & DRAMINIT1_MEM_SDRAM) ? 0 : 1;
-
- lfbsize = sgram_p ?
- (((draminit0 & DRAMINIT0_SGRAM_NUM) ? 2 : 1) *
- ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 8 : 4) * 1024 * 1024) :
- 16 * 1024 * 1024;
+ if (dev_id < PCI_DEVICE_ID_3DFX_VOODOO5) {
+ /* Banshee/Voodoo3 */
+ has_sgram = draminit1 & DRAMINIT1_MEM_SDRAM;
+ chip_size = has_sgram ? ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 2 : 1)
+ : 2;
} else {
/* Voodoo4/5 */
- u32 chips, psize, banks;
-
- chips = ((draminit0 & (1 << 26)) == 0) ? 4 : 8;
- psize = 1 << ((draminit0 & 0x38000000) >> 28);
- banks = ((draminit0 & (1 << 30)) == 0) ? 2 : 4;
- lfbsize = chips * psize * banks;
- lfbsize <<= 20;
- }
- /* disable block writes for SDRAM (why?) */
+ has_sgram = 0;
+ chip_size = 1 << ((draminit0 & DRAMINIT0_SGRAM_TYPE_MASK) >> DRAMINIT0_SGRAM_TYPE_SHIFT);
+ }
+ lfbsize = num_chips * chip_size * 1024 * 1024;
+
+ /* disable block writes for SDRAM */
miscinit1 = tdfx_inl(par, MISCINIT1);
- miscinit1 |= sgram_p ? 0 : MISCINIT1_2DBLOCK_DIS;
+ miscinit1 |= has_sgram ? 0 : MISCINIT1_2DBLOCK_DIS;
miscinit1 |= MISCINIT1_CLUT_INV;
banshee_make_room(par, 1);
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 3099630d0c3..9d9d2009ad8 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -45,9 +45,7 @@ static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *);
static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *);
static int tgafb_pci_register(struct pci_dev *, const struct pci_device_id *);
-#ifdef MODULE
static void tgafb_pci_unregister(struct pci_dev *);
-#endif
static const char *mode_option = "640x480@60";
@@ -1484,7 +1482,6 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
return ret;
}
-#ifdef MODULE
static void __exit
tgafb_pci_unregister(struct pci_dev *pdev)
{
@@ -1500,6 +1497,7 @@ tgafb_pci_unregister(struct pci_dev *pdev)
kfree(info);
}
+#ifdef MODULE
static void __exit
tgafb_exit(void)
{
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 8fc1278d7fb..3027841f9c2 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -19,9 +19,6 @@
#include <linux/fb.h>
#include <linux/ioport.h>
#include <linux/init.h>
-#ifdef __i386__
-#include <video/edid.h>
-#endif
#include <asm/io.h>
#include <asm/mtrr.h>