summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/atm/he.c6
-rw-r--r--drivers/base/core.c1
-rw-r--r--drivers/base/cpu.c6
-rw-r--r--drivers/base/dmapool.c4
-rw-r--r--drivers/base/memory.c34
-rw-r--r--drivers/base/topology.c2
-rw-r--r--drivers/block/DAC960.c4
-rw-r--r--drivers/block/Kconfig3
-rw-r--r--drivers/block/aoe/aoeblk.c2
-rw-r--r--drivers/block/cciss.c332
-rw-r--r--drivers/block/cciss.h6
-rw-r--r--drivers/block/cciss_cmd.h3
-rw-r--r--drivers/block/nbd.c16
-rw-r--r--drivers/block/paride/aten.c4
-rw-r--r--drivers/block/paride/bpck.c4
-rw-r--r--drivers/block/paride/bpck6.c17
-rw-r--r--drivers/block/paride/comm.c4
-rw-r--r--drivers/block/paride/dstr.c4
-rw-r--r--drivers/block/paride/epat.c4
-rw-r--r--drivers/block/paride/epia.c4
-rw-r--r--drivers/block/paride/fit2.c4
-rw-r--r--drivers/block/paride/fit3.c4
-rw-r--r--drivers/block/paride/friq.c4
-rw-r--r--drivers/block/paride/frpw.c4
-rw-r--r--drivers/block/paride/jumbo70
-rw-r--r--drivers/block/paride/kbic.c14
-rw-r--r--drivers/block/paride/ktti.c4
-rw-r--r--drivers/block/paride/on20.c4
-rw-r--r--drivers/block/paride/on26.c4
-rw-r--r--drivers/block/paride/paride.c47
-rw-r--r--drivers/block/paride/paride.h4
-rw-r--r--drivers/block/paride/pcd.c8
-rw-r--r--drivers/block/paride/pf.c8
-rw-r--r--drivers/block/paride/pg.c4
-rw-r--r--drivers/block/paride/pt.c4
-rw-r--r--drivers/block/pktcdvd.c2
-rw-r--r--drivers/bluetooth/hci_bcsp.c4
-rw-r--r--drivers/cdrom/optcd.c2
-rw-r--r--drivers/cdrom/sbpcd.c5
-rw-r--r--drivers/char/agp/amd64-agp.c2
-rw-r--r--drivers/char/decserial.c38
-rw-r--r--drivers/char/drm/drm_sman.c1
-rw-r--r--drivers/char/drm/drm_vm.c8
-rw-r--r--drivers/char/hvc_console.c1
-rw-r--r--drivers/char/hvcs.c426
-rw-r--r--drivers/char/hw_random/Kconfig19
-rw-r--r--drivers/char/hw_random/Makefile3
-rw-r--r--drivers/char/ip2/i2cmd.h5
-rw-r--r--drivers/char/ip2/i2lib.c1
-rw-r--r--drivers/char/ipmi/ipmi_bt_sm.c641
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c25
-rw-r--r--drivers/char/ipmi/ipmi_kcs_sm.c18
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c724
-rw-r--r--drivers/char/ipmi/ipmi_poweroff.c114
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c376
-rw-r--r--drivers/char/ipmi/ipmi_smic_sm.c14
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c121
-rw-r--r--drivers/char/istallion.c4
-rw-r--r--drivers/char/misc.c2
-rw-r--r--drivers/char/mmtimer.c23
-rw-r--r--drivers/char/moxa.c5
-rw-r--r--drivers/char/pcmcia/synclink_cs.c26
-rw-r--r--drivers/char/rio/rio_linux.c8
-rw-r--r--drivers/char/riscom8.c5
-rw-r--r--drivers/char/synclink.c26
-rw-r--r--drivers/char/synclink_gt.c27
-rw-r--r--drivers/char/synclinkmp.c26
-rw-r--r--drivers/char/sysrq.c14
-rw-r--r--drivers/char/toshiba.c1
-rw-r--r--drivers/char/tpm/tpm.c1
-rw-r--r--drivers/char/vt.c16
-rw-r--r--drivers/char/watchdog/pcwd_usb.c2
-rw-r--r--drivers/cpufreq/cpufreq.c2
-rw-r--r--drivers/dma/ioatdma.c4
-rw-r--r--drivers/edac/edac_mc.c1
-rw-r--r--drivers/ide/Kconfig16
-rw-r--r--drivers/ide/ide.c19
-rw-r--r--drivers/ide/pci/via82cxxx.c21
-rw-r--r--drivers/ieee1394/eth1394.c2
-rw-r--r--drivers/ieee1394/hosts.c2
-rw-r--r--drivers/ieee1394/nodemgr.c1
-rw-r--r--drivers/ieee1394/ohci1394.c8
-rw-r--r--drivers/ieee1394/pcilynx.c2
-rw-r--r--drivers/ieee1394/raw1394.c40
-rw-r--r--drivers/infiniband/hw/amso1100/c2_vq.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_av.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_cq.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_mrmw.c4
-rw-r--r--drivers/infiniband/hw/ehca/ehca_pd.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_av.c2
-rw-r--r--drivers/input/gameport/gameport.c1
-rw-r--r--drivers/input/misc/hp_sdc_rtc.c4
-rw-r--r--drivers/input/serio/serio.c1
-rw-r--r--drivers/input/touchscreen/ads7846.c2
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c34
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c12
-rw-r--r--drivers/isdn/hisax/isdnhdlc.h8
-rw-r--r--drivers/leds/Kconfig6
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/leds-wrap.c142
-rw-r--r--drivers/macintosh/apm_emu.c3
-rw-r--r--drivers/macintosh/therm_adt746x.c1
-rw-r--r--drivers/macintosh/via-pmu.c2
-rw-r--r--drivers/macintosh/windfarm_core.c1
-rw-r--r--drivers/md/dm-crypt.c2
-rw-r--r--drivers/md/dm-mpath.c2
-rw-r--r--drivers/md/dm-snap.c6
-rw-r--r--drivers/md/dm.c4
-rw-r--r--drivers/md/kcopyd.c2
-rw-r--r--drivers/md/md.c2
-rw-r--r--drivers/md/raid5.c4
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c2
-rw-r--r--drivers/media/dvb/dvb-usb/usb-urb.c2
-rw-r--r--drivers/media/dvb/frontends/l64781.c2
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c2
-rw-r--r--drivers/media/radio/Kconfig32
-rw-r--r--drivers/media/video/msp3400-driver.c2
-rw-r--r--drivers/media/video/tvaudio.c1
-rw-r--r--drivers/media/video/video-buf-dvb.c2
-rw-r--r--drivers/media/video/vivi.c1
-rw-r--r--drivers/message/fusion/mptbase.c255
-rw-r--r--drivers/message/fusion/mptfc.c5
-rw-r--r--drivers/message/fusion/mptscsih.c24
-rw-r--r--drivers/message/fusion/mptspi.c4
-rw-r--r--drivers/message/i2o/bus-osm.c3
-rw-r--r--drivers/message/i2o/device.c27
-rw-r--r--drivers/message/i2o/driver.c20
-rw-r--r--drivers/message/i2o/exec-osm.c10
-rw-r--r--drivers/message/i2o/i2o_block.c15
-rw-r--r--drivers/message/i2o/i2o_block.h2
-rw-r--r--drivers/message/i2o/i2o_config.c8
-rw-r--r--drivers/message/i2o/i2o_proc.c2
-rw-r--r--drivers/message/i2o/i2o_scsi.c23
-rw-r--r--drivers/message/i2o/pci.c5
-rw-r--r--drivers/mfd/ucb1x00-ts.c2
-rw-r--r--drivers/misc/tifm_core.c5
-rw-r--r--drivers/mtd/devices/m25p80.c2
-rw-r--r--drivers/net/de600.c1
-rw-r--r--drivers/net/irda/stir4200.c1
-rw-r--r--drivers/net/lasi_82596.c94
-rw-r--r--drivers/net/wireless/airo.c1
-rw-r--r--drivers/parport/parport_pc.c12
-rw-r--r--drivers/pci/msi.c2
-rw-r--r--drivers/pci/probe.c1
-rw-r--r--drivers/pcmcia/cs.c1
-rw-r--r--drivers/pnp/card.c30
-rw-r--r--drivers/pnp/interface.c17
-rw-r--r--drivers/pnp/pnpbios/core.c4
-rw-r--r--drivers/rtc/Kconfig12
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-ds1672.c9
-rw-r--r--drivers/rtc/rtc-ds1742.c67
-rw-r--r--drivers/rtc/rtc-omap.c572
-rw-r--r--drivers/rtc/rtc-rs5c372.c90
-rw-r--r--drivers/rtc/rtc-test.c9
-rw-r--r--drivers/rtc/rtc-x1205.c12
-rw-r--r--drivers/s390/block/dasd_devmap.c2
-rw-r--r--drivers/s390/block/dasd_eckd.c2
-rw-r--r--drivers/s390/block/dasd_fba.c2
-rw-r--r--drivers/s390/block/dasd_int.h2
-rw-r--r--drivers/s390/scsi/zfcp_def.h6
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c2
-rw-r--r--drivers/scsi/53c700.c82
-rw-r--r--drivers/scsi/53c700.h16
-rw-r--r--drivers/scsi/aic94xx/aic94xx.h4
-rw-r--r--drivers/scsi/aic94xx/aic94xx_hwi.c2
-rw-r--r--drivers/scsi/aic94xx/aic94xx_init.c4
-rw-r--r--drivers/scsi/ide-scsi.c6
-rw-r--r--drivers/scsi/ipr.c2
-rw-r--r--drivers/scsi/libsas/sas_init.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c2
-rw-r--r--drivers/scsi/scsi.c2
-rw-r--r--drivers/scsi/scsi_lib.c4
-rw-r--r--drivers/scsi/scsi_tgt_lib.c2
-rw-r--r--drivers/serial/8250_exar_st16c554.c52
-rw-r--r--drivers/serial/8250_pnp.c29
-rw-r--r--drivers/serial/Kconfig30
-rw-r--r--drivers/serial/Makefile2
-rw-r--r--drivers/serial/amba-pl010.c2
-rw-r--r--drivers/serial/dz.c371
-rw-r--r--drivers/serial/dz.h32
-rw-r--r--drivers/serial/mpsc.c22
-rw-r--r--drivers/serial/uartlite.c505
-rw-r--r--drivers/spi/spi.c25
-rw-r--r--drivers/spi/spi_bitbang.c2
-rw-r--r--drivers/spi/spi_butterfly.c2
-rw-r--r--drivers/usb/atm/ueagle-atm.c2
-rw-r--r--drivers/usb/core/buffer.c2
-rw-r--r--drivers/usb/core/hub.c7
-rw-r--r--drivers/usb/core/message.c2
-rw-r--r--drivers/usb/gadget/file_storage.c2
-rw-r--r--drivers/usb/gadget/gmidi.c2
-rw-r--r--drivers/usb/gadget/goku_udc.c2
-rw-r--r--drivers/usb/gadget/inode.c6
-rw-r--r--drivers/usb/gadget/net2280.c2
-rw-r--r--drivers/usb/gadget/omap_udc.c2
-rw-r--r--drivers/usb/gadget/zero.c2
-rw-r--r--drivers/usb/host/ehci-dbg.c2
-rw-r--r--drivers/usb/host/hc_crisv10.c16
-rw-r--r--drivers/usb/host/ohci-dbg.c2
-rw-r--r--drivers/usb/host/ohci-pnx4008.c2
-rw-r--r--drivers/usb/host/uhci-hcd.c2
-rw-r--r--drivers/usb/host/uhci-q.c2
-rw-r--r--drivers/usb/input/acecad.c2
-rw-r--r--drivers/usb/input/aiptek.c2
-rw-r--r--drivers/usb/input/ati_remote.c6
-rw-r--r--drivers/usb/input/hid-core.c10
-rw-r--r--drivers/usb/input/keyspan_remote.c2
-rw-r--r--drivers/usb/input/mtouchusb.c2
-rw-r--r--drivers/usb/input/powermate.c4
-rw-r--r--drivers/usb/input/touchkitusb.c2
-rw-r--r--drivers/usb/input/usbkbd.c8
-rw-r--r--drivers/usb/input/usbmouse.c4
-rw-r--r--drivers/usb/input/usbtouchscreen.c2
-rw-r--r--drivers/usb/input/xpad.c2
-rw-r--r--drivers/usb/input/yealink.c6
-rw-r--r--drivers/usb/misc/phidgetkit.c4
-rw-r--r--drivers/usb/misc/phidgetmotorcontrol.c4
-rw-r--r--drivers/usb/misc/usbtest.c36
-rw-r--r--drivers/usb/mon/mon_text.c10
-rw-r--r--drivers/usb/net/catc.c2
-rw-r--r--drivers/usb/net/net1080.c2
-rw-r--r--drivers/usb/net/pegasus.c2
-rw-r--r--drivers/usb/net/rndis_host.c2
-rw-r--r--drivers/usb/net/rtl8150.c2
-rw-r--r--drivers/usb/net/usbnet.c4
-rw-r--r--drivers/usb/serial/mos7720.c2
-rw-r--r--drivers/usb/serial/mos7840.c4
-rw-r--r--drivers/usb/storage/onetouch.c4
-rw-r--r--drivers/usb/storage/transport.c2
-rw-r--r--drivers/usb/storage/usb.c2
-rw-r--r--drivers/video/geode/gxfb_core.c2
-rw-r--r--drivers/w1/Makefile4
-rw-r--r--drivers/w1/slaves/Makefile4
-rw-r--r--drivers/w1/slaves/w1_ds2433.c30
-rw-r--r--drivers/w1/w1.c1
240 files changed, 4438 insertions, 2169 deletions
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index c7314a79da0..7d9b4e52f0b 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -820,7 +820,7 @@ he_init_group(struct he_dev *he_dev, int group)
void *cpuaddr;
#ifdef USE_RBPS_POOL
- cpuaddr = pci_pool_alloc(he_dev->rbps_pool, SLAB_KERNEL|SLAB_DMA, &dma_handle);
+ cpuaddr = pci_pool_alloc(he_dev->rbps_pool, GFP_KERNEL|GFP_DMA, &dma_handle);
if (cpuaddr == NULL)
return -ENOMEM;
#else
@@ -884,7 +884,7 @@ he_init_group(struct he_dev *he_dev, int group)
void *cpuaddr;
#ifdef USE_RBPL_POOL
- cpuaddr = pci_pool_alloc(he_dev->rbpl_pool, SLAB_KERNEL|SLAB_DMA, &dma_handle);
+ cpuaddr = pci_pool_alloc(he_dev->rbpl_pool, GFP_KERNEL|GFP_DMA, &dma_handle);
if (cpuaddr == NULL)
return -ENOMEM;
#else
@@ -1724,7 +1724,7 @@ __alloc_tpd(struct he_dev *he_dev)
struct he_tpd *tpd;
dma_addr_t dma_handle;
- tpd = pci_pool_alloc(he_dev->tpd_pool, SLAB_ATOMIC|SLAB_DMA, &dma_handle);
+ tpd = pci_pool_alloc(he_dev->tpd_pool, GFP_ATOMIC|GFP_DMA, &dma_handle);
if (tpd == NULL)
return NULL;
diff --git a/drivers/base/core.c b/drivers/base/core.c
index e4b530ef757..67b79a7592a 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -386,6 +386,7 @@ void device_initialize(struct device *dev)
INIT_LIST_HEAD(&dev->node);
init_MUTEX(&dev->sem);
device_init_wakeup(dev, 0);
+ set_dev_node(dev, -1);
}
#ifdef CONFIG_SYSFS_DEPRECATED
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 1f745f12f94..7fd095efaeb 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -104,8 +104,8 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL);
/*
* register_cpu - Setup a driverfs device for a CPU.
- * @cpu - Callers can set the cpu->no_control field to 1, to indicate not to
- * generate a control file in sysfs for this CPU.
+ * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
+ * sysfs for this CPU.
* @num - CPU number to use when creating the device.
*
* Initialize and register the CPU device.
@@ -119,7 +119,7 @@ int __devinit register_cpu(struct cpu *cpu, int num)
error = sysdev_register(&cpu->sysdev);
- if (!error && !cpu->no_control)
+ if (!error && cpu->hotpluggable)
register_cpu_control(cpu);
if (!error)
cpu_sys_devices[num] = &cpu->sysdev;
diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c
index b2efbd4cf71..dbe0735f8c9 100644
--- a/drivers/base/dmapool.c
+++ b/drivers/base/dmapool.c
@@ -126,7 +126,7 @@ dma_pool_create (const char *name, struct device *dev,
} else if (allocation < size)
return NULL;
- if (!(retval = kmalloc (sizeof *retval, SLAB_KERNEL)))
+ if (!(retval = kmalloc (sizeof *retval, GFP_KERNEL)))
return retval;
strlcpy (retval->name, name, sizeof retval->name);
@@ -297,7 +297,7 @@ restart:
}
}
}
- if (!(page = pool_alloc_page (pool, SLAB_ATOMIC))) {
+ if (!(page = pool_alloc_page (pool, GFP_ATOMIC))) {
if (mem_flags & __GFP_WAIT) {
DECLARE_WAITQUEUE (wait, current);
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index c6b7d9c4b65..74b96795d2f 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -290,9 +290,8 @@ static CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
static int block_size_init(void)
{
- sysfs_create_file(&memory_sysdev_class.kset.kobj,
- &class_attr_block_size_bytes.attr);
- return 0;
+ return sysfs_create_file(&memory_sysdev_class.kset.kobj,
+ &class_attr_block_size_bytes.attr);
}
/*
@@ -323,12 +322,14 @@ static CLASS_ATTR(probe, 0700, NULL, memory_probe_store);
static int memory_probe_init(void)
{
- sysfs_create_file(&memory_sysdev_class.kset.kobj,
- &class_attr_probe.attr);
- return 0;
+ return sysfs_create_file(&memory_sysdev_class.kset.kobj,
+ &class_attr_probe.attr);
}
#else
-#define memory_probe_init(...) do {} while (0)
+static inline int memory_probe_init(void)
+{
+ return 0;
+}
#endif
/*
@@ -431,9 +432,12 @@ int __init memory_dev_init(void)
{
unsigned int i;
int ret;
+ int err;
memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops;
ret = sysdev_class_register(&memory_sysdev_class);
+ if (ret)
+ goto out;
/*
* Create entries for memory sections that were found
@@ -442,11 +446,19 @@ int __init memory_dev_init(void)
for (i = 0; i < NR_MEM_SECTIONS; i++) {
if (!valid_section_nr(i))
continue;
- add_memory_block(0, __nr_to_section(i), MEM_ONLINE, 0);
+ err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, 0);
+ if (!ret)
+ ret = err;
}
- memory_probe_init();
- block_size_init();
-
+ err = memory_probe_init();
+ if (!ret)
+ ret = err;
+ err = block_size_init();
+ if (!ret)
+ ret = err;
+out:
+ if (ret)
+ printk(KERN_ERR "%s() failed: %d\n", __FUNCTION__, ret);
return ret;
}
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index 3d12b85b096..067a9e8bc37 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -108,7 +108,6 @@ static int __cpuinit topology_add_dev(unsigned int cpu)
return rc;
}
-#ifdef CONFIG_HOTPLUG_CPU
static void __cpuinit topology_remove_dev(unsigned int cpu)
{
struct sys_device *sys_dev = get_cpu_sysdev(cpu);
@@ -136,7 +135,6 @@ static int __cpuinit topology_cpu_callback(struct notifier_block *nfb,
}
return rc ? NOTIFY_BAD : NOTIFY_OK;
}
-#endif
static int __cpuinit topology_sysfs_init(void)
{
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 742d0740310..8d81a3a64c0 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -324,13 +324,13 @@ static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
Command->Next = Controller->FreeCommands;
Controller->FreeCommands = Command;
Controller->Commands[CommandIdentifier-1] = Command;
- ScatterGatherCPU = pci_pool_alloc(ScatterGatherPool, SLAB_ATOMIC,
+ ScatterGatherCPU = pci_pool_alloc(ScatterGatherPool, GFP_ATOMIC,
&ScatterGatherDMA);
if (ScatterGatherCPU == NULL)
return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION");
if (RequestSensePool != NULL) {
- RequestSenseCPU = pci_pool_alloc(RequestSensePool, SLAB_ATOMIC,
+ RequestSenseCPU = pci_pool_alloc(RequestSensePool, GFP_ATOMIC,
&RequestSenseDMA);
if (RequestSenseCPU == NULL) {
pci_pool_free(ScatterGatherPool, ScatterGatherCPU,
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index e00568e0952..85072446d77 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -168,7 +168,8 @@ config BLK_CPQ_CISS_DA
config CISS_SCSI_TAPE
bool "SCSI tape drive support for Smart Array 5xxx"
- depends on BLK_CPQ_CISS_DA && SCSI && PROC_FS
+ depends on BLK_CPQ_CISS_DA && PROC_FS
+ depends on SCSI=y || SCSI=BLK_CPQ_CISS_DA
help
When enabled (Y), this option allows SCSI tape drives and SCSI medium
changers (tape robots) to be accessed via a Compaq 5xxx array
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index aa25f8b09fe..478489c568a 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -12,7 +12,7 @@
#include <linux/netdevice.h>
#include "aoe.h"
-static kmem_cache_t *buf_pool_cache;
+static struct kmem_cache *buf_pool_cache;
static ssize_t aoedisk_show_state(struct gendisk * disk, char *page)
{
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 4105c3bf347..892e092afe9 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -47,14 +47,15 @@
#include <linux/completion.h>
#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
-#define DRIVER_NAME "HP CISS Driver (v 3.6.10)"
-#define DRIVER_VERSION CCISS_DRIVER_VERSION(3,6,10)
+#define DRIVER_NAME "HP CISS Driver (v 3.6.14)"
+#define DRIVER_VERSION CCISS_DRIVER_VERSION(3,6,14)
/* Embedded module documentation macros - see modules.h */
MODULE_AUTHOR("Hewlett-Packard Company");
-MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 3.6.10");
+MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 3.6.14");
MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
" SA6i P600 P800 P400 P400i E200 E200i E500");
+MODULE_VERSION("3.6.14");
MODULE_LICENSE("GPL");
#include "cciss_cmd.h"
@@ -81,7 +82,9 @@ static const struct pci_device_id cciss_pci_device_id[] = {
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3213},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3214},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3215},
- {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3233},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3237},
+ {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
{0,}
};
@@ -90,27 +93,29 @@ MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
/* board_id = Subsystem Device ID & Vendor ID
* product = Marketing Name for the board
* access = Address of the struct of function pointers
+ * nr_cmds = Number of commands supported by controller
*/
static struct board_type products[] = {
- {0x40700E11, "Smart Array 5300", &SA5_access},
- {0x40800E11, "Smart Array 5i", &SA5B_access},
- {0x40820E11, "Smart Array 532", &SA5B_access},
- {0x40830E11, "Smart Array 5312", &SA5B_access},
- {0x409A0E11, "Smart Array 641", &SA5_access},
- {0x409B0E11, "Smart Array 642", &SA5_access},
- {0x409C0E11, "Smart Array 6400", &SA5_access},
- {0x409D0E11, "Smart Array 6400 EM", &SA5_access},
- {0x40910E11, "Smart Array 6i", &SA5_access},
- {0x3225103C, "Smart Array P600", &SA5_access},
- {0x3223103C, "Smart Array P800", &SA5_access},
- {0x3234103C, "Smart Array P400", &SA5_access},
- {0x3235103C, "Smart Array P400i", &SA5_access},
- {0x3211103C, "Smart Array E200i", &SA5_access},
- {0x3212103C, "Smart Array E200", &SA5_access},
- {0x3213103C, "Smart Array E200i", &SA5_access},
- {0x3214103C, "Smart Array E200i", &SA5_access},
- {0x3215103C, "Smart Array E200i", &SA5_access},
- {0x3233103C, "Smart Array E500", &SA5_access},
+ {0x40700E11, "Smart Array 5300", &SA5_access, 512},
+ {0x40800E11, "Smart Array 5i", &SA5B_access, 512},
+ {0x40820E11, "Smart Array 532", &SA5B_access, 512},
+ {0x40830E11, "Smart Array 5312", &SA5B_access, 512},
+ {0x409A0E11, "Smart Array 641", &SA5_access, 512},
+ {0x409B0E11, "Smart Array 642", &SA5_access, 512},
+ {0x409C0E11, "Smart Array 6400", &SA5_access, 512},
+ {0x409D0E11, "Smart Array 6400 EM", &SA5_access, 512},
+ {0x40910E11, "Smart Array 6i", &SA5_access, 512},
+ {0x3225103C, "Smart Array P600", &SA5_access, 512},
+ {0x3223103C, "Smart Array P800", &SA5_access, 512},
+ {0x3234103C, "Smart Array P400", &SA5_access, 512},
+ {0x3235103C, "Smart Array P400i", &SA5_access, 512},
+ {0x3211103C, "Smart Array E200i", &SA5_access, 120},
+ {0x3212103C, "Smart Array E200", &SA5_access, 120},
+ {0x3213103C, "Smart Array E200i", &SA5_access, 120},
+ {0x3214103C, "Smart Array E200i", &SA5_access, 120},
+ {0x3215103C, "Smart Array E200i", &SA5_access, 120},
+ {0x3237103C, "Smart Array E500", &SA5_access, 512},
+ {0xFFFF103C, "Unknown Smart Array", &SA5_access, 120},
};
/* How long to wait (in milliseconds) for board to go into simple mode */
@@ -121,7 +126,6 @@ static struct board_type products[] = {
#define MAX_CMD_RETRIES 3
#define READ_AHEAD 1024
-#define NR_CMDS 384 /* #commands that can be outstanding */
#define MAX_CTLR 32
/* Originally cciss driver only supports 8 major numbers */
@@ -137,7 +141,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
unsigned int cmd, unsigned long arg);
static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
-static int revalidate_allvol(ctlr_info_t *host);
static int cciss_revalidate(struct gendisk *disk);
static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk);
static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
@@ -265,6 +268,7 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
"Firmware Version: %c%c%c%c\n"
"IRQ: %d\n"
"Logical drives: %d\n"
+ "Max sectors: %d\n"
"Current Q depth: %d\n"
"Current # commands on controller: %d\n"
"Max Q depth since init: %d\n"
@@ -275,7 +279,9 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
(unsigned long)h->board_id,
h->firm_ver[0], h->firm_ver[1], h->firm_ver[2],
h->firm_ver[3], (unsigned int)h->intr[SIMPLE_MODE_INT],
- h->num_luns, h->Qdepth, h->commands_outstanding,
+ h->num_luns,
+ h->cciss_max_sectors,
+ h->Qdepth, h->commands_outstanding,
h->maxQsinceinit, h->max_outstanding, h->maxSG);
pos += size;
@@ -400,8 +406,8 @@ static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool)
} else { /* get it out of the controllers pool */
do {
- i = find_first_zero_bit(h->cmd_pool_bits, NR_CMDS);
- if (i == NR_CMDS)
+ i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds);
+ if (i == h->nr_cmds)
return NULL;
} while (test_and_set_bit
(i & (BITS_PER_LONG - 1),
@@ -487,7 +493,7 @@ static int cciss_open(struct inode *inode, struct file *filep)
* but I'm already using way to many device nodes to claim another one
* for "raw controller".
*/
- if (drv->nr_blocks == 0) {
+ if (drv->heads == 0) {
if (iminor(inode) != 0) { /* not node 0? */
/* if not node 0 make sure it is a partition = 0 */
if (iminor(inode) & 0x0f) {
@@ -850,9 +856,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
}
case CCISS_REVALIDVOLS:
- if (bdev != bdev->bd_contains || drv != host->drv)
- return -ENXIO;
- return revalidate_allvol(host);
+ return rebuild_lun_table(host, NULL);
case CCISS_GETLUNINFO:{
LogvolInfo_struct luninfo;
@@ -1152,75 +1156,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
}
}
-/*
- * revalidate_allvol is for online array config utilities. After a
- * utility reconfigures the drives in the array, it can use this function
- * (through an ioctl) to make the driver zap any previous disk structs for
- * that controller and get new ones.
- *
- * Right now I'm using the getgeometry() function to do this, but this
- * function should probably be finer grained and allow you to revalidate one
- * particular logical volume (instead of all of them on a particular
- * controller).
- */
-static int revalidate_allvol(ctlr_info_t *host)
-{
- int ctlr = host->ctlr, i;
- unsigned long flags;
-
- spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
- if (host->usage_count > 1) {
- spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
- printk(KERN_WARNING "cciss: Device busy for volume"
- " revalidation (usage=%d)\n", host->usage_count);
- return -EBUSY;
- }
- host->usage_count++;
- spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
-
- for (i = 0; i < NWD; i++) {
- struct gendisk *disk = host->gendisk[i];
- if (disk) {
- request_queue_t *q = disk->queue;
-
- if (disk->flags & GENHD_FL_UP)
- del_gendisk(disk);
- if (q)
- blk_cleanup_queue(q);
- }
- }
-
- /*
- * Set the partition and block size structures for all volumes
- * on this controller to zero. We will reread all of this data
- */
- memset(host->drv, 0, sizeof(drive_info_struct)
- * CISS_MAX_LUN);
- /*
- * Tell the array controller not to give us any interrupts while
- * we check the new geometry. Then turn interrupts back on when
- * we're done.
- */
- host->access.set_intr_mask(host, CCISS_INTR_OFF);
- cciss_getgeometry(ctlr);
- host->access.set_intr_mask(host, CCISS_INTR_ON);
-
- /* Loop through each real device */
- for (i = 0; i < NWD; i++) {
- struct gendisk *disk = host->gendisk[i];
- drive_info_struct *drv = &(host->drv[i]);
- /* we must register the controller even if no disks exist */
- /* this is for the online array utilities */
- if (!drv->heads && i)
- continue;
- blk_queue_hardsect_size(drv->queue, drv->block_size);
- set_capacity(disk, drv->nr_blocks);
- add_disk(disk);
- }
- host->usage_count--;
- return 0;
-}
-
static inline void complete_buffers(struct bio *bio, int status)
{
while (bio) {
@@ -1243,7 +1178,7 @@ static void cciss_check_queues(ctlr_info_t *h)
* in case the interrupt we serviced was from an ioctl and did not
* free any new commands.
*/
- if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS)
+ if ((find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds)) == h->nr_cmds)
return;
/* We have room on the queue for more commands. Now we need to queue
@@ -1262,7 +1197,7 @@ static void cciss_check_queues(ctlr_info_t *h)
/* check to see if we have maxed out the number of commands
* that can be placed on the queue.
*/
- if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) {
+ if ((find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds)) == h->nr_cmds) {
if (curr_queue == start_queue) {
h->next_to_run =
(start_queue + 1) % (h->highest_lun + 1);
@@ -1380,6 +1315,11 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
/* if it's the controller it's already added */
if (drv_index) {
disk->queue = blk_init_queue(do_cciss_request, &h->lock);
+ sprintf(disk->disk_name, "cciss/c%dd%d", ctlr, drv_index);
+ disk->major = h->major;
+ disk->first_minor = drv_index << NWD_SHIFT;
+ disk->fops = &cciss_fops;
+ disk->private_data = &h->drv[drv_index];
/* Set up queue information */
disk->queue->backing_dev_info.ra_pages = READ_AHEAD;
@@ -1391,7 +1331,7 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
/* This is a limit in the driver and could be eliminated. */
blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES);
- blk_queue_max_sectors(disk->queue, 512);
+ blk_queue_max_sectors(disk->queue, h->cciss_max_sectors);
blk_queue_softirq_done(disk->queue, cciss_softirq_done);
@@ -1458,11 +1398,6 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk)
/* Set busy_configuring flag for this operation */
spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
- if (h->num_luns >= CISS_MAX_LUN) {
- spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
- return -EINVAL;
- }
-
if (h->busy_configuring) {
spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
return -EBUSY;
@@ -1495,17 +1430,8 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk)
0, 0, TYPE_CMD);
if (return_code == IO_OK) {
- listlength |=
- (0xff & (unsigned int)(ld_buff->LUNListLength[0]))
- << 24;
- listlength |=
- (0xff & (unsigned int)(ld_buff->LUNListLength[1]))
- << 16;
- listlength |=
- (0xff & (unsigned int)(ld_buff->LUNListLength[2]))
- << 8;
- listlength |=
- 0xff & (unsigned int)(ld_buff->LUNListLength[3]);
+ listlength =
+ be32_to_cpu(*(__u32 *) ld_buff->LUNListLength);
} else { /* reading number of logical volumes failed */
printk(KERN_WARNING "cciss: report logical volume"
" command failed\n");
@@ -1556,6 +1482,14 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk)
if (drv_index == -1)
goto freeret;
+ /*Check if the gendisk needs to be allocated */
+ if (!h->gendisk[drv_index]){
+ h->gendisk[drv_index] = alloc_disk(1 << NWD_SHIFT);
+ if (!h->gendisk[drv_index]){
+ printk(KERN_ERR "cciss: could not allocate new disk %d\n", drv_index);
+ goto mem_msg;
+ }
+ }
}
h->drv[drv_index].LunID = lunid;
cciss_update_drive_info(ctlr, drv_index);
@@ -1593,6 +1527,7 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk)
static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
int clear_all)
{
+ int i;
ctlr_info_t *h = get_host(disk);
if (!capable(CAP_SYS_RAWIO))
@@ -1616,9 +1551,35 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
del_gendisk(disk);
if (q) {
blk_cleanup_queue(q);
+ /* Set drv->queue to NULL so that we do not try
+ * to call blk_start_queue on this queue in the
+ * interrupt handler
+ */
drv->queue = NULL;
}
+ /* If clear_all is set then we are deleting the logical
+ * drive, not just refreshing its info. For drives
+ * other than disk 0 we will call put_disk. We do not
+ * do this for disk 0 as we need it to be able to
+ * configure the controller.
+ */
+ if (clear_all){
+ /* This isn't pretty, but we need to find the
+ * disk in our array and NULL our the pointer.
+ * This is so that we will call alloc_disk if
+ * this index is used again later.
+ */
+ for (i=0; i < CISS_MAX_LUN; i++){
+ if(h->gendisk[i] == disk){
+ h->gendisk[i] = NULL;
+ break;
+ }
+ }
+ put_disk(disk);
+ }
}
+ } else {
+ set_capacity(disk, 0);
}
--h->num_luns;
@@ -2136,7 +2097,7 @@ static int add_sendcmd_reject(__u8 cmd, int ctlr, unsigned long complete)
/* We've sent down an abort or reset, but something else
has completed */
- if (srl->ncompletions >= (NR_CMDS + 2)) {
+ if (srl->ncompletions >= (hba[ctlr]->nr_cmds + 2)) {
/* Uh oh. No room to save it for later... */
printk(KERN_WARNING "cciss%d: Sendcmd: Invalid command addr, "
"reject list overflow, command lost!\n", ctlr);
@@ -2673,7 +2634,7 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id)
a1 = a;
if ((a & 0x04)) {
a2 = (a >> 3);
- if (a2 >= NR_CMDS) {
+ if (a2 >= h->nr_cmds) {
printk(KERN_WARNING
"cciss: controller cciss%d failed, stopping.\n",
h->ctlr);
@@ -2827,23 +2788,21 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *c,
if (err > 0) {
printk(KERN_WARNING "cciss: only %d MSI-X vectors "
"available\n", err);
+ goto default_int_mode;
} else {
printk(KERN_WARNING "cciss: MSI-X init failed %d\n",
err);
+ goto default_int_mode;
}
}
if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) {
if (!pci_enable_msi(pdev)) {
- c->intr[SIMPLE_MODE_INT] = pdev->irq;
c->msi_vector = 1;
- return;
} else {
printk(KERN_WARNING "cciss: MSI init failed\n");
- c->intr[SIMPLE_MODE_INT] = pdev->irq;
- return;
}
}
- default_int_mode:
+default_int_mode:
#endif /* CONFIG_PCI_MSI */
/* if we get here we're going to use the default interrupt mode */
c->intr[SIMPLE_MODE_INT] = pdev->irq;
@@ -2956,16 +2915,10 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
if (board_id == products[i].board_id) {
c->product_name = products[i].product_name;
c->access = *(products[i].access);
+ c->nr_cmds = products[i].nr_cmds;
break;
}
}
- if (i == ARRAY_SIZE(products)) {
- printk(KERN_WARNING "cciss: Sorry, I don't know how"
- " to access the Smart Array controller %08lx\n",
- (unsigned long)board_id);
- err = -ENODEV;
- goto err_out_free_res;
- }
if ((readb(&c->cfgtable->Signature[0]) != 'C') ||
(readb(&c->cfgtable->Signature[1]) != 'I') ||
(readb(&c->cfgtable->Signature[2]) != 'S') ||
@@ -2974,6 +2927,27 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
err = -ENODEV;
goto err_out_free_res;
}
+ /* We didn't find the controller in our list. We know the
+ * signature is valid. If it's an HP device let's try to
+ * bind to the device and fire it up. Otherwise we bail.
+ */
+ if (i == ARRAY_SIZE(products)) {
+ if (subsystem_vendor_id == PCI_VENDOR_ID_HP) {
+ c->product_name = products[i-1].product_name;
+ c->access = *(products[i-1].access);
+ c->nr_cmds = products[i-1].nr_cmds;
+ printk(KERN_WARNING "cciss: This is an unknown "
+ "Smart Array controller.\n"
+ "cciss: Please update to the latest driver "
+ "available from www.hp.com.\n");
+ } else {
+ printk(KERN_WARNING "cciss: Sorry, I don't know how"
+ " to access the Smart Array controller %08lx\n"
+ , (unsigned long)board_id);
+ err = -ENODEV;
+ goto err_out_free_res;
+ }
+ }
#ifdef CONFIG_X86
{
/* Need to enable prefetch in the SCSI core for 6400 in x86 */
@@ -2984,6 +2958,17 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
}
#endif
+ /* Disabling DMA prefetch for the P600
+ * An ASIC bug may result in a prefetch beyond
+ * physical memory.
+ */
+ if(board_id == 0x3225103C) {
+ __u32 dma_prefetch;
+ dma_prefetch = readl(c->vaddr + I2O_DMA1_CFG);
+ dma_prefetch |= 0x8000;
+ writel(dma_prefetch, c->vaddr + I2O_DMA1_CFG);
+ }
+
#ifdef CCISS_DEBUG
printk("Trying to put board into Simple mode\n");
#endif /* CCISS_DEBUG */
@@ -3158,13 +3143,7 @@ geo_inq:
/* Returns -1 if no free entries are left. */
static int alloc_cciss_hba(void)
{
- struct gendisk *disk[NWD];
- int i, n;
- for (n = 0; n < NWD; n++) {
- disk[n] = alloc_disk(1 << NWD_SHIFT);
- if (!disk[n])
- goto out;
- }
+ int i;
for (i = 0; i < MAX_CTLR; i++) {
if (!hba[i]) {
@@ -3172,20 +3151,18 @@ static int alloc_cciss_hba(void)
p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL);
if (!p)
goto Enomem;
- for (n = 0; n < NWD; n++)
- p->gendisk[n] = disk[n];
+ p->gendisk[0] = alloc_disk(1 << NWD_SHIFT);
+ if (!p->gendisk[0])
+ goto Enomem;
hba[i] = p;
return i;
}
}
printk(KERN_WARNING "cciss: This driver supports a maximum"
" of %d controllers.\n", MAX_CTLR);
- goto out;
- Enomem:
+ return -1;
+Enomem:
printk(KERN_ERR "cciss: out of memory.\n");
- out:
- while (n--)
- put_disk(disk[n]);
return -1;
}
@@ -3195,7 +3172,7 @@ static void free_hba(int i)
int n;
hba[i] = NULL;
- for (n = 0; n < NWD; n++)
+ for (n = 0; n < CISS_MAX_LUN; n++)
put_disk(p->gendisk[n]);
kfree(p);
}
@@ -3208,9 +3185,8 @@ static void free_hba(int i)
static int __devinit cciss_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
- request_queue_t *q;
int i;
- int j;
+ int j = 0;
int rc;
int dac;
@@ -3269,15 +3245,15 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
hba[i]->intr[SIMPLE_MODE_INT], dac ? "" : " not");
hba[i]->cmd_pool_bits =
- kmalloc(((NR_CMDS + BITS_PER_LONG -
+ kmalloc(((hba[i]->nr_cmds + BITS_PER_LONG -
1) / BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL);
hba[i]->cmd_pool = (CommandList_struct *)
pci_alloc_consistent(hba[i]->pdev,
- NR_CMDS * sizeof(CommandList_struct),
+ hba[i]->nr_cmds * sizeof(CommandList_struct),
&(hba[i]->cmd_pool_dhandle));
hba[i]->errinfo_pool = (ErrorInfo_struct *)
pci_alloc_consistent(hba[i]->pdev,
- NR_CMDS * sizeof(ErrorInfo_struct),
+ hba[i]->nr_cmds * sizeof(ErrorInfo_struct),
&(hba[i]->errinfo_pool_dhandle));
if ((hba[i]->cmd_pool_bits == NULL)
|| (hba[i]->cmd_pool == NULL)
@@ -3288,7 +3264,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
#ifdef CONFIG_CISS_SCSI_TAPE
hba[i]->scsi_rejects.complete =
kmalloc(sizeof(hba[i]->scsi_rejects.complete[0]) *
- (NR_CMDS + 5), GFP_KERNEL);
+ (hba[i]->nr_cmds + 5), GFP_KERNEL);
if (hba[i]->scsi_rejects.complete == NULL) {
printk(KERN_ERR "cciss: out of memory");
goto clean4;
@@ -3302,7 +3278,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
/* command and error info recs zeroed out before
they are used */
memset(hba[i]->cmd_pool_bits, 0,
- ((NR_CMDS + BITS_PER_LONG -
+ ((hba[i]->nr_cmds + BITS_PER_LONG -
1) / BITS_PER_LONG) * sizeof(unsigned long));
#ifdef CCISS_DEBUG
@@ -3317,18 +3293,34 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);
cciss_procinit(i);
+
+ hba[i]->cciss_max_sectors = 2048;
+
hba[i]->busy_initializing = 0;
- for (j = 0; j < NWD; j++) { /* mfm */
+ do {
drive_info_struct *drv = &(hba[i]->drv[j]);
struct gendisk *disk = hba[i]->gendisk[j];
+ request_queue_t *q;
+
+ /* Check if the disk was allocated already */
+ if (!disk){
+ hba[i]->gendisk[j] = alloc_disk(1 << NWD_SHIFT);
+ disk = hba[i]->gendisk[j];
+ }
+
+ /* Check that the disk was able to be allocated */
+ if (!disk) {
+ printk(KERN_ERR "cciss: unable to allocate memory for disk %d\n", j);
+ goto clean4;
+ }
q = blk_init_queue(do_cciss_request, &hba[i]->lock);
if (!q) {
printk(KERN_ERR
"cciss: unable to allocate queue for disk %d\n",
j);
- break;
+ goto clean4;
}
drv->queue = q;
@@ -3341,7 +3333,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
/* This is a limit in the driver and could be eliminated. */
blk_queue_max_phys_segments(q, MAXSGENTRIES);
- blk_queue_max_sectors(q, 512);
+ blk_queue_max_sectors(q, hba[i]->cciss_max_sectors);
blk_queue_softirq_done(q, cciss_softirq_done);
@@ -3360,7 +3352,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
blk_queue_hardsect_size(q, drv->block_size);
set_capacity(disk, drv->nr_blocks);
add_disk(disk);
- }
+ j++;
+ } while (j <= hba[i]->highest_lun);
return 1;
@@ -3371,11 +3364,11 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
kfree(hba[i]->cmd_pool_bits);
if (hba[i]->cmd_pool)
pci_free_consistent(hba[i]->pdev,
- NR_CMDS * sizeof(CommandList_struct),
+ hba[i]->nr_cmds * sizeof(CommandList_struct),
hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
if (hba[i]->errinfo_pool)
pci_free_consistent(hba[i]->pdev,
- NR_CMDS * sizeof(ErrorInfo_struct),
+ hba[i]->nr_cmds * sizeof(ErrorInfo_struct),
hba[i]->errinfo_pool,
hba[i]->errinfo_pool_dhandle);
free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]);
@@ -3383,6 +3376,15 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
unregister_blkdev(hba[i]->major, hba[i]->devname);
clean1:
hba[i]->busy_initializing = 0;
+ /* cleanup any queues that may have been initialized */
+ for (j=0; j <= hba[i]->highest_lun; j++){
+ drive_info_struct *drv = &(hba[i]->drv[j]);
+ if (drv->queue)
+ blk_cleanup_queue(drv->queue);
+ }
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
free_hba(i);
return -1;
}
@@ -3430,7 +3432,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
remove_proc_entry(hba[i]->devname, proc_cciss);
/* remove it from the disk list */
- for (j = 0; j < NWD; j++) {
+ for (j = 0; j < CISS_MAX_LUN; j++) {
struct gendisk *disk = hba[i]->gendisk[j];
if (disk) {
request_queue_t *q = disk->queue;
@@ -3442,9 +3444,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
}
}
- pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct),
+ pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(CommandList_struct),
hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
- pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(ErrorInfo_struct),
+ pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(ErrorInfo_struct),
hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle);
kfree(hba[i]->cmd_pool_bits);
#ifdef CONFIG_CISS_SCSI_TAPE
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index 562235c1445..b70988dd33e 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -6,7 +6,6 @@
#include "cciss_cmd.h"
-#define NWD 16
#define NWD_SHIFT 4
#define MAX_PART (1 << NWD_SHIFT)
@@ -60,6 +59,7 @@ struct ctlr_info
__u32 board_id;
void __iomem *vaddr;
unsigned long paddr;
+ int nr_cmds; /* Number of commands allowed on this controller */
CfgTable_struct __iomem *cfgtable;
int interrupts_enabled;
int major;
@@ -76,6 +76,7 @@ struct ctlr_info
unsigned int intr[4];
unsigned int msix_vector;
unsigned int msi_vector;
+ int cciss_max_sectors;
BYTE cciss_read;
BYTE cciss_write;
BYTE cciss_read_capacity;
@@ -110,7 +111,7 @@ struct ctlr_info
int next_to_run;
// Disk structures we need to pass back
- struct gendisk *gendisk[NWD];
+ struct gendisk *gendisk[CISS_MAX_LUN];
#ifdef CONFIG_CISS_SCSI_TAPE
void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
/* list of block side commands the scsi error handling sucked up */
@@ -282,6 +283,7 @@ struct board_type {
__u32 board_id;
char *product_name;
struct access_method *access;
+ int nr_cmds; /* Max cmds this kind of ctlr can handle. */
};
#define CCISS_LOCK(i) (&hba[i]->lock)
diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h
index 4af7c4c0c7a..43bf5593b59 100644
--- a/drivers/block/cciss_cmd.h
+++ b/drivers/block/cciss_cmd.h
@@ -55,6 +55,7 @@
#define I2O_INT_MASK 0x34
#define I2O_IBPOST_Q 0x40
#define I2O_OBPOST_Q 0x44
+#define I2O_DMA1_CFG 0x214
//Configuration Table
#define CFGTBL_ChangeReq 0x00000001l
@@ -88,7 +89,7 @@ typedef union _u64bit
//###########################################################################
//STRUCTURES
//###########################################################################
-#define CISS_MAX_LUN 16
+#define CISS_MAX_LUN 1024
#define CISS_MAX_PHYS_LUN 1024
// SCSI-3 Cmmands
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 9d1035e8d9d..7bf2cfbd628 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -355,14 +355,30 @@ harderror:
return NULL;
}
+static ssize_t pid_show(struct gendisk *disk, char *page)
+{
+ return sprintf(page, "%ld\n",
+ (long) ((struct nbd_device *)disk->private_data)->pid);
+}
+
+static struct disk_attribute pid_attr = {
+ .attr = { .name = "pid", .mode = S_IRUGO },
+ .show = pid_show,
+};
+
static void nbd_do_it(struct nbd_device *lo)
{
struct request *req;
BUG_ON(lo->magic != LO_MAGIC);
+ lo->pid = current->pid;
+ sysfs_create_file(&lo->disk->kobj, &pid_attr.attr);
+
while ((req = nbd_read_stat(lo)) != NULL)
nbd_end_request(req);
+
+ sysfs_remove_file(&lo->disk->kobj, &pid_attr.attr);
return;
}
diff --git a/drivers/block/paride/aten.c b/drivers/block/paride/aten.c
index c4d696d43dc..2695465568a 100644
--- a/drivers/block/paride/aten.c
+++ b/drivers/block/paride/aten.c
@@ -149,12 +149,12 @@ static struct pi_protocol aten = {
static int __init aten_init(void)
{
- return pi_register(&aten)-1;
+ return paride_register(&aten);
}
static void __exit aten_exit(void)
{
- pi_unregister( &aten );
+ paride_unregister( &aten );
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/bpck.c b/drivers/block/paride/bpck.c
index d462ff6b139..4f27e7392e3 100644
--- a/drivers/block/paride/bpck.c
+++ b/drivers/block/paride/bpck.c
@@ -464,12 +464,12 @@ static struct pi_protocol bpck = {
static int __init bpck_init(void)
{
- return pi_register(&bpck)-1;
+ return paride_register(&bpck);
}
static void __exit bpck_exit(void)
{
- pi_unregister(&bpck);
+ paride_unregister(&bpck);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/bpck6.c b/drivers/block/paride/bpck6.c
index 41a237c5957..ad124525ac2 100644
--- a/drivers/block/paride/bpck6.c
+++ b/drivers/block/paride/bpck6.c
@@ -31,10 +31,7 @@ static int verbose; /* set this to 1 to see debugging messages and whatnot */
#include <linux/slab.h>
#include <linux/types.h>
#include <asm/io.h>
-
-#if defined(CONFIG_PARPORT_MODULE)||defined(CONFIG_PARPORT)
#include <linux/parport.h>
-#endif
#include "ppc6lnx.c"
#include "paride.h"
@@ -139,11 +136,6 @@ static int bpck6_test_port ( PIA *pi ) /* check for 8-bit port */
PPCSTRUCT(pi)->ppc_id=pi->unit;
PPCSTRUCT(pi)->lpt_addr=pi->port;
-#ifdef CONFIG_PARPORT_PC_MODULE
-#define CONFIG_PARPORT_PC
-#endif
-
-#ifdef CONFIG_PARPORT_PC
/* look at the parport device to see if what modes we can use */
if(((struct pardevice *)(pi->pardev))->port->modes &
(PARPORT_MODE_EPP)
@@ -161,11 +153,6 @@ static int bpck6_test_port ( PIA *pi ) /* check for 8-bit port */
{
return 1;
}
-#else
- /* there is no way of knowing what kind of port we have
- default to the highest mode possible */
- return 5;
-#endif
}
static int bpck6_probe_unit ( PIA *pi )
@@ -265,12 +252,12 @@ static int __init bpck6_init(void)
printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n");
if(verbose)
printk(KERN_DEBUG "bpck6: verbose debug enabled.\n");
- return pi_register(&bpck6) - 1;
+ return paride_register(&bpck6);
}
static void __exit bpck6_exit(void)
{
- pi_unregister(&bpck6);
+ paride_unregister(&bpck6);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/comm.c b/drivers/block/paride/comm.c
index 43d61359d8e..9bcd3549532 100644
--- a/drivers/block/paride/comm.c
+++ b/drivers/block/paride/comm.c
@@ -205,12 +205,12 @@ static struct pi_protocol comm = {
static int __init comm_init(void)
{
- return pi_register(&comm)-1;
+ return paride_register(&comm);
}
static void __exit comm_exit(void)
{
- pi_unregister(&comm);
+ paride_unregister(&comm);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/dstr.c b/drivers/block/paride/dstr.c
index 04d53bf58e8..accc5c777cb 100644
--- a/drivers/block/paride/dstr.c
+++ b/drivers/block/paride/dstr.c
@@ -220,12 +220,12 @@ static struct pi_protocol dstr = {
static int __init dstr_init(void)
{
- return pi_register(&dstr)-1;
+ return paride_register(&dstr);
}
static void __exit dstr_exit(void)
{
- pi_unregister(&dstr);
+ paride_unregister(&dstr);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/epat.c b/drivers/block/paride/epat.c
index 55d1c0a1fb9..1bcdff77322 100644
--- a/drivers/block/paride/epat.c
+++ b/drivers/block/paride/epat.c
@@ -327,12 +327,12 @@ static int __init epat_init(void)
#ifdef CONFIG_PARIDE_EPATC8
epatc8 = 1;
#endif
- return pi_register(&epat)-1;
+ return paride_register(&epat);
}
static void __exit epat_exit(void)
{
- pi_unregister(&epat);
+ paride_unregister(&epat);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/epia.c b/drivers/block/paride/epia.c
index 0f2e0c292d8..fb0e782d055 100644
--- a/drivers/block/paride/epia.c
+++ b/drivers/block/paride/epia.c
@@ -303,12 +303,12 @@ static struct pi_protocol epia = {
static int __init epia_init(void)
{
- return pi_register(&epia)-1;
+ return paride_register(&epia);
}
static void __exit epia_exit(void)
{
- pi_unregister(&epia);
+ paride_unregister(&epia);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/fit2.c b/drivers/block/paride/fit2.c
index e0f0691d8bc..381283753ae 100644
--- a/drivers/block/paride/fit2.c
+++ b/drivers/block/paride/fit2.c
@@ -138,12 +138,12 @@ static struct pi_protocol fit2 = {
static int __init fit2_init(void)
{
- return pi_register(&fit2)-1;
+ return paride_register(&fit2);
}
static void __exit fit2_exit(void)
{
- pi_unregister(&fit2);
+ paride_unregister(&fit2);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/fit3.c b/drivers/block/paride/fit3.c
index 15400e7bc66..275d269458e 100644
--- a/drivers/block/paride/fit3.c
+++ b/drivers/block/paride/fit3.c
@@ -198,12 +198,12 @@ static struct pi_protocol fit3 = {
static int __init fit3_init(void)
{
- return pi_register(&fit3)-1;
+ return paride_register(&fit3);
}
static void __exit fit3_exit(void)
{
- pi_unregister(&fit3);
+ paride_unregister(&fit3);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/friq.c b/drivers/block/paride/friq.c
index 5ea2904d281..4f2ba244689 100644
--- a/drivers/block/paride/friq.c
+++ b/drivers/block/paride/friq.c
@@ -263,12 +263,12 @@ static struct pi_protocol friq = {
static int __init friq_init(void)
{
- return pi_register(&friq)-1;
+ return paride_register(&friq);
}
static void __exit friq_exit(void)
{
- pi_unregister(&friq);
+ paride_unregister(&friq);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/frpw.c b/drivers/block/paride/frpw.c
index 56b3824b153..c3cde364603 100644
--- a/drivers/block/paride/frpw.c
+++ b/drivers/block/paride/frpw.c
@@ -300,12 +300,12 @@ static struct pi_protocol frpw = {
static int __init frpw_init(void)
{
- return pi_register(&frpw)-1;
+ return paride_register(&frpw);
}
static void __exit frpw_exit(void)
{
- pi_unregister(&frpw);
+ paride_unregister(&frpw);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/jumbo b/drivers/block/paride/jumbo
deleted file mode 100644
index e793b9cb7e7..00000000000
--- a/drivers/block/paride/jumbo
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/sh
-#
-# This script can be used to build "jumbo" modules that contain the
-# base PARIDE support, one protocol module and one high-level driver.
-#
-echo -n "High level driver [pcd] : "
-read X
-HLD=${X:-pcd}
-#
-echo -n "Protocol module [bpck] : "
-read X
-PROTO=${X:-bpck}
-#
-echo -n "Use MODVERSIONS [y] ? "
-read X
-UMODV=${X:-y}
-#
-echo -n "For SMP kernel [n] ? "
-read X
-USMP=${X:-n}
-#
-echo -n "Support PARPORT [n] ? "
-read X
-UPARP=${X:-n}
-#
-echo
-#
-case $USMP in
- y* | Y* ) FSMP="-DCONFIG_SMP"
- ;;
- *) FSMP=""
- ;;
-esac
-#
-MODI="-include ../../../include/linux/modversions.h"
-#
-case $UMODV in
- y* | Y* ) FMODV="-DMODVERSIONS $MODI"
- ;;
- *) FMODV=""
- ;;
-esac
-#
-case $UPARP in
- y* | Y* ) FPARP="-DCONFIG_PARPORT"
- ;;
- *) FPARP=""
- ;;
-esac
-#
-TARG=$HLD-$PROTO.o
-FPROTO=-DCONFIG_PARIDE_`echo "$PROTO" | tr [a-z] [A-Z]`
-FK="-D__KERNEL__ -I ../../../include"
-FLCH=-D_LINUX_CONFIG_H
-#
-echo cc $FK $FSMP $FLCH $FPARP $FPROTO $FMODV -Wall -O2 -o Jb.o -c paride.c
-cc $FK $FSMP $FLCH $FPARP $FPROTO $FMODV -Wall -O2 -o Jb.o -c paride.c
-#
-echo cc $FK $FSMP $FMODV -Wall -O2 -o Jp.o -c $PROTO.c
-cc $FK $FSMP $FMODV -Wall -O2 -o Jp.o -c $PROTO.c
-#
-echo cc $FK $FSMP $FMODV -DMODULE -DPARIDE_JUMBO -Wall -O2 -o Jd.o -c $HLD.c
-cc $FK $FSMP $FMODV -DMODULE -DPARIDE_JUMBO -Wall -O2 -o Jd.o -c $HLD.c
-#
-echo ld -r -o $TARG Jp.o Jb.o Jd.o
-ld -r -o $TARG Jp.o Jb.o Jd.o
-#
-#
-rm Jp.o Jb.o Jd.o
-#
diff --git a/drivers/block/paride/kbic.c b/drivers/block/paride/kbic.c
index d983bcea76f..35999c415ee 100644
--- a/drivers/block/paride/kbic.c
+++ b/drivers/block/paride/kbic.c
@@ -283,13 +283,21 @@ static struct pi_protocol k971 = {
static int __init kbic_init(void)
{
- return (pi_register(&k951)||pi_register(&k971))-1;
+ int rv;
+
+ rv = paride_register(&k951);
+ if (rv < 0)
+ return rv;
+ rv = paride_register(&k971);
+ if (rv < 0)
+ paride_unregister(&k951);
+ return rv;
}
static void __exit kbic_exit(void)
{
- pi_unregister(&k951);
- pi_unregister(&k971);
+ paride_unregister(&k951);
+ paride_unregister(&k971);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/ktti.c b/drivers/block/paride/ktti.c
index 6c7edbfba9a..117ab0e8ccf 100644
--- a/drivers/block/paride/ktti.c
+++ b/drivers/block/paride/ktti.c
@@ -115,12 +115,12 @@ static struct pi_protocol ktti = {
static int __init ktti_init(void)
{
- return pi_register(&ktti)-1;
+ return paride_register(&ktti);
}
static void __exit ktti_exit(void)
{
- pi_unregister(&ktti);
+ paride_unregister(&ktti);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/on20.c b/drivers/block/paride/on20.c
index 9f8e0109680..0173697a1a4 100644
--- a/drivers/block/paride/on20.c
+++ b/drivers/block/paride/on20.c
@@ -140,12 +140,12 @@ static struct pi_protocol on20 = {
static int __init on20_init(void)
{
- return pi_register(&on20)-1;
+ return paride_register(&on20);
}
static void __exit on20_exit(void)
{
- pi_unregister(&on20);
+ paride_unregister(&on20);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/on26.c b/drivers/block/paride/on26.c
index 0f833caa210..95ba256921f 100644
--- a/drivers/block/paride/on26.c
+++ b/drivers/block/paride/on26.c
@@ -306,12 +306,12 @@ static struct pi_protocol on26 = {
static int __init on26_init(void)
{
- return pi_register(&on26)-1;
+ return paride_register(&on26);
}
static void __exit on26_exit(void)
{
- pi_unregister(&on26);
+ paride_unregister(&on26);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/paride.c b/drivers/block/paride/paride.c
index 4b258f7836f..48c50f11f63 100644
--- a/drivers/block/paride/paride.c
+++ b/drivers/block/paride/paride.c
@@ -29,14 +29,7 @@
#include <linux/spinlock.h>
#include <linux/wait.h>
#include <linux/sched.h> /* TASK_* */
-
-#ifdef CONFIG_PARPORT_MODULE
-#define CONFIG_PARPORT
-#endif
-
-#ifdef CONFIG_PARPORT
#include <linux/parport.h>
-#endif
#include "paride.h"
@@ -76,8 +69,6 @@ void pi_read_block(PIA * pi, char *buf, int count)
EXPORT_SYMBOL(pi_read_block);
-#ifdef CONFIG_PARPORT
-
static void pi_wake_up(void *p)
{
PIA *pi = (PIA *) p;
@@ -100,11 +91,8 @@ static void pi_wake_up(void *p)
cont();
}
-#endif
-
int pi_schedule_claimed(PIA * pi, void (*cont) (void))
{
-#ifdef CONFIG_PARPORT
unsigned long flags;
spin_lock_irqsave(&pi_spinlock, flags);
@@ -115,7 +103,6 @@ int pi_schedule_claimed(PIA * pi, void (*cont) (void))
}
pi->claimed = 1;
spin_unlock_irqrestore(&pi_spinlock, flags);
-#endif
return 1;
}
EXPORT_SYMBOL(pi_schedule_claimed);
@@ -133,20 +120,16 @@ static void pi_claim(PIA * pi)
if (pi->claimed)
return;
pi->claimed = 1;
-#ifdef CONFIG_PARPORT
if (pi->pardev)
wait_event(pi->parq,
!parport_claim((struct pardevice *) pi->pardev));
-#endif
}
static void pi_unclaim(PIA * pi)
{
pi->claimed = 0;
-#ifdef CONFIG_PARPORT
if (pi->pardev)
parport_release((struct pardevice *) (pi->pardev));
-#endif
}
void pi_connect(PIA * pi)
@@ -167,21 +150,15 @@ EXPORT_SYMBOL(pi_disconnect);
static void pi_unregister_parport(PIA * pi)
{
-#ifdef CONFIG_PARPORT
if (pi->pardev) {
parport_unregister_device((struct pardevice *) (pi->pardev));
pi->pardev = NULL;
}
-#endif
}
void pi_release(PIA * pi)
{
pi_unregister_parport(pi);
-#ifndef CONFIG_PARPORT
- if (pi->reserved)
- release_region(pi->port, pi->reserved);
-#endif /* !CONFIG_PARPORT */
if (pi->proto->release_proto)
pi->proto->release_proto(pi);
module_put(pi->proto->owner);
@@ -229,7 +206,7 @@ static int pi_test_proto(PIA * pi, char *scratch, int verbose)
return res;
}
-int pi_register(PIP * pr)
+int paride_register(PIP * pr)
{
int k;
@@ -237,24 +214,24 @@ int pi_register(PIP * pr)
if (protocols[k] && !strcmp(pr->name, protocols[k]->name)) {
printk("paride: %s protocol already registered\n",
pr->name);
- return 0;
+ return -1;
}
k = 0;
while ((k < MAX_PROTOS) && (protocols[k]))
k++;
if (k == MAX_PROTOS) {
printk("paride: protocol table full\n");
- return 0;
+ return -1;
}
protocols[k] = pr;
pr->index = k;
printk("paride: %s registered as protocol %d\n", pr->name, k);
- return 1;
+ return 0;
}
-EXPORT_SYMBOL(pi_register);
+EXPORT_SYMBOL(paride_register);
-void pi_unregister(PIP * pr)
+void paride_unregister(PIP * pr)
{
if (!pr)
return;
@@ -265,12 +242,10 @@ void pi_unregister(PIP * pr)
protocols[pr->index] = NULL;
}
-EXPORT_SYMBOL(pi_unregister);
+EXPORT_SYMBOL(paride_unregister);
static int pi_register_parport(PIA * pi, int verbose)
{
-#ifdef CONFIG_PARPORT
-
struct parport *port;
port = parport_find_base(pi->port);
@@ -290,7 +265,6 @@ static int pi_register_parport(PIA * pi, int verbose)
printk("%s: 0x%x is %s\n", pi->device, pi->port, port->name);
pi->parname = (char *) port->name;
-#endif
return 1;
}
@@ -447,13 +421,6 @@ int pi_init(PIA * pi, int autoprobe, int port, int mode,
printk("%s: Adapter not found\n", device);
return 0;
}
-#ifndef CONFIG_PARPORT
- if (!request_region(pi->port, pi->reserved, pi->device)) {
- printk(KERN_WARNING "paride: Unable to request region 0x%x\n",
- pi->port);
- return 0;
- }
-#endif /* !CONFIG_PARPORT */
if (pi->parname)
printk("%s: Sharing %s at 0x%x\n", pi->device,
diff --git a/drivers/block/paride/paride.h b/drivers/block/paride/paride.h
index c6d98ef09e4..2bddbf45518 100644
--- a/drivers/block/paride/paride.h
+++ b/drivers/block/paride/paride.h
@@ -163,8 +163,8 @@ struct pi_protocol {
typedef struct pi_protocol PIP;
-extern int pi_register( PIP * );
-extern void pi_unregister ( PIP * );
+extern int paride_register( PIP * );
+extern void paride_unregister ( PIP * );
#endif /* __DRIVERS_PARIDE_H__ */
/* end of paride.h */
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index ac5ba462710..c852eed91e4 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -912,12 +912,12 @@ static int __init pcd_init(void)
int unit;
if (disable)
- return -1;
+ return -EINVAL;
pcd_init_units();
if (pcd_detect())
- return -1;
+ return -ENODEV;
/* get the atapi capabilities page */
pcd_probe_capabilities();
@@ -925,7 +925,7 @@ static int __init pcd_init(void)
if (register_blkdev(major, name)) {
for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
put_disk(cd->disk);
- return -1;
+ return -EBUSY;
}
pcd_queue = blk_init_queue(do_pcd_request, &pcd_lock);
@@ -933,7 +933,7 @@ static int __init pcd_init(void)
unregister_blkdev(major, name);
for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
put_disk(cd->disk);
- return -1;
+ return -ENOMEM;
}
for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index 1a9dee19efc..7cdaa195126 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -933,25 +933,25 @@ static int __init pf_init(void)
int unit;
if (disable)
- return -1;
+ return -EINVAL;
pf_init_units();
if (pf_detect())
- return -1;
+ return -ENODEV;
pf_busy = 0;
if (register_blkdev(major, name)) {
for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++)
put_disk(pf->disk);
- return -1;
+ return -EBUSY;
}
pf_queue = blk_init_queue(do_pf_request, &pf_spin_lock);
if (!pf_queue) {
unregister_blkdev(major, name);
for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++)
put_disk(pf->disk);
- return -1;
+ return -ENOMEM;
}
blk_queue_max_phys_segments(pf_queue, cluster);
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index 13f998aa1cd..9970aedbb5d 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -646,14 +646,14 @@ static int __init pg_init(void)
int err;
if (disable){
- err = -1;
+ err = -EINVAL;
goto out;
}
pg_init_units();
if (pg_detect()) {
- err = -1;
+ err = -ENODEV;
goto out;
}
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index 35fb2663672..c902b25e486 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -946,12 +946,12 @@ static int __init pt_init(void)
int err;
if (disable) {
- err = -1;
+ err = -EINVAL;
goto out;
}
if (pt_detect()) {
- err = -1;
+ err = -ENODEV;
goto out;
}
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index f2904f67af4..e45eaa26411 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -54,7 +54,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/miscdevice.h>
-#include <linux/suspend.h>
+#include <linux/freezer.h>
#include <linux/mutex.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_ioctl.h>
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index d0cface535f..5e2c3188200 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -330,7 +330,7 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
reliable packet if the number of packets sent but not yet ack'ed
is < than the winsize */
- spin_lock_irqsave(&bcsp->unack.lock, flags);
+ spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING);
if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type);
@@ -696,7 +696,7 @@ static void bcsp_timed_event(unsigned long arg)
BT_DBG("hu %p retransmitting %u pkts", hu, bcsp->unack.qlen);
- spin_lock_irqsave(&bcsp->unack.lock, flags);
+ spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING);
while ((skb = __skb_dequeue_tail(&bcsp->unack)) != NULL) {
bcsp->msgq_txseq = (bcsp->msgq_txseq - 1) & 0x07;
diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c
index 25032d7edc5..3541690a77d 100644
--- a/drivers/cdrom/optcd.c
+++ b/drivers/cdrom/optcd.c
@@ -101,7 +101,7 @@ static void debug(int debug_this, const char* fmt, ...)
return;
va_start(args, fmt);
- vsprintf(s, fmt, args);
+ vsnprintf(s, sizeof(s), fmt, args);
printk(KERN_DEBUG "optcd: %s\n", s);
va_end(args);
}
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
index ba50e5a712f..a1283b1ef98 100644
--- a/drivers/cdrom/sbpcd.c
+++ b/drivers/cdrom/sbpcd.c
@@ -770,11 +770,10 @@ static void msg(int level, const char *fmt, ...)
msgnum++;
if (msgnum>99) msgnum=0;
- sprintf(buf, MSG_LEVEL "%s-%d [%02d]: ", major_name, current_drive - D_S, msgnum);
va_start(args, fmt);
- vsprintf(&buf[18], fmt, args);
+ vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
- printk(buf);
+ printk(MSG_LEVEL "%s-%d [%02d]: %s", major_name, current_drive - D_S, msgnum, buf);
#if KLOGD_PAUSE
sbp_sleep(KLOGD_PAUSE); /* else messages get lost */
#endif /* KLOGD_PAUSE */
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 00b17ae3973..2f2c4efff8a 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -459,7 +459,7 @@ static const struct aper_size_info_32 nforce3_sizes[5] =
/* Handle shadow device of the Nvidia NForce3 */
/* CHECK-ME original 2.4 version set up some IORRs. Check if that is needed. */
-static int __devinit nforce3_agp_init(struct pci_dev *pdev)
+static int nforce3_agp_init(struct pci_dev *pdev)
{
u32 tmp, apbase, apbar, aplimit;
struct pci_dev *dev1;
diff --git a/drivers/char/decserial.c b/drivers/char/decserial.c
index 85f404e25c7..8ea2bea2b18 100644
--- a/drivers/char/decserial.c
+++ b/drivers/char/decserial.c
@@ -23,20 +23,12 @@
extern int zs_init(void);
#endif
-#ifdef CONFIG_DZ
-extern int dz_init(void);
-#endif
-
#ifdef CONFIG_SERIAL_CONSOLE
#ifdef CONFIG_ZS
extern void zs_serial_console_init(void);
#endif
-#ifdef CONFIG_DZ
-extern void dz_serial_console_init(void);
-#endif
-
#endif
/* rs_init - starts up the serial interface -
@@ -46,23 +38,11 @@ extern void dz_serial_console_init(void);
int __init rs_init(void)
{
-
-#if defined(CONFIG_ZS) && defined(CONFIG_DZ)
+#ifdef CONFIG_ZS
if (IOASIC)
return zs_init();
- else
- return dz_init();
-#else
-
-#ifdef CONFIG_ZS
- return zs_init();
-#endif
-
-#ifdef CONFIG_DZ
- return dz_init();
-#endif
-
#endif
+ return -ENXIO;
}
__initcall(rs_init);
@@ -76,21 +56,9 @@ __initcall(rs_init);
*/
static int __init decserial_console_init(void)
{
-#if defined(CONFIG_ZS) && defined(CONFIG_DZ)
+#ifdef CONFIG_ZS
if (IOASIC)
zs_serial_console_init();
- else
- dz_serial_console_init();
-#else
-
-#ifdef CONFIG_ZS
- zs_serial_console_init();
-#endif
-
-#ifdef CONFIG_DZ
- dz_serial_console_init();
-#endif
-
#endif
return 0;
}
diff --git a/drivers/char/drm/drm_sman.c b/drivers/char/drm/drm_sman.c
index 425c82336ee..19c81d2e13d 100644
--- a/drivers/char/drm/drm_sman.c
+++ b/drivers/char/drm/drm_sman.c
@@ -162,6 +162,7 @@ drm_sman_set_manager(drm_sman_t * sman, unsigned int manager,
return 0;
}
+EXPORT_SYMBOL(drm_sman_set_manager);
static drm_owner_item_t *drm_sman_get_owner_item(drm_sman_t * sman,
unsigned long owner)
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index b40ae438f53..ae2691942dd 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -147,14 +147,14 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
if (address > vma->vm_end)
return NOPAGE_SIGBUS; /* Disallow mremap */
if (!map)
- return NOPAGE_OOM; /* Nothing allocated */
+ return NOPAGE_SIGBUS; /* Nothing allocated */
offset = address - vma->vm_start;
i = (unsigned long)map->handle + offset;
page = (map->type == _DRM_CONSISTENT) ?
virt_to_page((void *)i) : vmalloc_to_page((void *)i);
if (!page)
- return NOPAGE_OOM;
+ return NOPAGE_SIGBUS;
get_page(page);
DRM_DEBUG("shm_nopage 0x%lx\n", address);
@@ -272,7 +272,7 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
if (address > vma->vm_end)
return NOPAGE_SIGBUS; /* Disallow mremap */
if (!dma->pagelist)
- return NOPAGE_OOM; /* Nothing allocated */
+ return NOPAGE_SIGBUS; /* Nothing allocated */
offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
page_nr = offset >> PAGE_SHIFT;
@@ -310,7 +310,7 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
if (address > vma->vm_end)
return NOPAGE_SIGBUS; /* Disallow mremap */
if (!entry->pagelist)
- return NOPAGE_OOM; /* Nothing allocated */
+ return NOPAGE_SIGBUS; /* Nothing allocated */
offset = address - vma->vm_start;
map_offset = map->offset - (unsigned long)dev->sg->virtual;
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 9902ffad3b1..cc2cd46bedc 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -38,6 +38,7 @@
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
+#include <linux/freezer.h>
#include <asm/uaccess.h>
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index 8728255c946..d090622f1de 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -337,11 +337,6 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp);
static void hvcs_close(struct tty_struct *tty, struct file *filp);
static void hvcs_hangup(struct tty_struct * tty);
-static void hvcs_create_device_attrs(struct hvcs_struct *hvcsd);
-static void hvcs_remove_device_attrs(struct vio_dev *vdev);
-static void hvcs_create_driver_attrs(void);
-static void hvcs_remove_driver_attrs(void);
-
static int __devinit hvcs_probe(struct vio_dev *dev,
const struct vio_device_id *id);
static int __devexit hvcs_remove(struct vio_dev *dev);
@@ -353,6 +348,172 @@ static void __exit hvcs_module_exit(void);
#define HVCS_TRY_WRITE 0x00000004
#define HVCS_READ_MASK (HVCS_SCHED_READ | HVCS_QUICK_READ)
+static inline struct hvcs_struct *from_vio_dev(struct vio_dev *viod)
+{
+ return viod->dev.driver_data;
+}
+/* The sysfs interface for the driver and devices */
+
+static ssize_t hvcs_partner_vtys_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct vio_dev *viod = to_vio_dev(dev);
+ struct hvcs_struct *hvcsd = from_vio_dev(viod);
+ unsigned long flags;
+ int retval;
+
+ spin_lock_irqsave(&hvcsd->lock, flags);
+ retval = sprintf(buf, "%X\n", hvcsd->p_unit_address);
+ spin_unlock_irqrestore(&hvcsd->lock, flags);
+ return retval;
+}
+static DEVICE_ATTR(partner_vtys, S_IRUGO, hvcs_partner_vtys_show, NULL);
+
+static ssize_t hvcs_partner_clcs_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct vio_dev *viod = to_vio_dev(dev);
+ struct hvcs_struct *hvcsd = from_vio_dev(viod);
+ unsigned long flags;
+ int retval;
+
+ spin_lock_irqsave(&hvcsd->lock, flags);
+ retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]);
+ spin_unlock_irqrestore(&hvcsd->lock, flags);
+ return retval;
+}
+static DEVICE_ATTR(partner_clcs, S_IRUGO, hvcs_partner_clcs_show, NULL);
+
+static ssize_t hvcs_current_vty_store(struct device *dev, struct device_attribute *attr, const char * buf,
+ size_t count)
+{
+ /*
+ * Don't need this feature at the present time because firmware doesn't
+ * yet support multiple partners.
+ */
+ printk(KERN_INFO "HVCS: Denied current_vty change: -EPERM.\n");
+ return -EPERM;
+}
+
+static ssize_t hvcs_current_vty_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct vio_dev *viod = to_vio_dev(dev);
+ struct hvcs_struct *hvcsd = from_vio_dev(viod);
+ unsigned long flags;
+ int retval;
+
+ spin_lock_irqsave(&hvcsd->lock, flags);
+ retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]);
+ spin_unlock_irqrestore(&hvcsd->lock, flags);
+ return retval;
+}
+
+static DEVICE_ATTR(current_vty,
+ S_IRUGO | S_IWUSR, hvcs_current_vty_show, hvcs_current_vty_store);
+
+static ssize_t hvcs_vterm_state_store(struct device *dev, struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct vio_dev *viod = to_vio_dev(dev);
+ struct hvcs_struct *hvcsd = from_vio_dev(viod);
+ unsigned long flags;
+
+ /* writing a '0' to this sysfs entry will result in the disconnect. */
+ if (simple_strtol(buf, NULL, 0) != 0)
+ return -EINVAL;
+
+ spin_lock_irqsave(&hvcsd->lock, flags);
+
+ if (hvcsd->open_count > 0) {
+ spin_unlock_irqrestore(&hvcsd->lock, flags);
+ printk(KERN_INFO "HVCS: vterm state unchanged. "
+ "The hvcs device node is still in use.\n");
+ return -EPERM;
+ }
+
+ if (hvcsd->connected == 0) {
+ spin_unlock_irqrestore(&hvcsd->lock, flags);
+ printk(KERN_INFO "HVCS: vterm state unchanged. The"
+ " vty-server is not connected to a vty.\n");
+ return -EPERM;
+ }
+
+ hvcs_partner_free(hvcsd);
+ printk(KERN_INFO "HVCS: Closed vty-server@%X and"
+ " partner vty@%X:%d connection.\n",
+ hvcsd->vdev->unit_address,
+ hvcsd->p_unit_address,
+ (uint32_t)hvcsd->p_partition_ID);
+
+ spin_unlock_irqrestore(&hvcsd->lock, flags);
+ return count;
+}
+
+static ssize_t hvcs_vterm_state_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct vio_dev *viod = to_vio_dev(dev);
+ struct hvcs_struct *hvcsd = from_vio_dev(viod);
+ unsigned long flags;
+ int retval;
+
+ spin_lock_irqsave(&hvcsd->lock, flags);
+ retval = sprintf(buf, "%d\n", hvcsd->connected);
+ spin_unlock_irqrestore(&hvcsd->lock, flags);
+ return retval;
+}
+static DEVICE_ATTR(vterm_state, S_IRUGO | S_IWUSR,
+ hvcs_vterm_state_show, hvcs_vterm_state_store);
+
+static ssize_t hvcs_index_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct vio_dev *viod = to_vio_dev(dev);
+ struct hvcs_struct *hvcsd = from_vio_dev(viod);
+ unsigned long flags;
+ int retval;
+
+ spin_lock_irqsave(&hvcsd->lock, flags);
+ retval = sprintf(buf, "%d\n", hvcsd->index);
+ spin_unlock_irqrestore(&hvcsd->lock, flags);
+ return retval;
+}
+
+static DEVICE_ATTR(index, S_IRUGO, hvcs_index_show, NULL);
+
+static struct attribute *hvcs_attrs[] = {
+ &dev_attr_partner_vtys.attr,
+ &dev_attr_partner_clcs.attr,
+ &dev_attr_current_vty.attr,
+ &dev_attr_vterm_state.attr,
+ &dev_attr_index.attr,
+ NULL,
+};
+
+static struct attribute_group hvcs_attr_group = {
+ .attrs = hvcs_attrs,
+};
+
+static ssize_t hvcs_rescan_show(struct device_driver *ddp, char *buf)
+{
+ /* A 1 means it is updating, a 0 means it is done updating */
+ return snprintf(buf, PAGE_SIZE, "%d\n", hvcs_rescan_status);
+}
+
+static ssize_t hvcs_rescan_store(struct device_driver *ddp, const char * buf,
+ size_t count)
+{
+ if ((simple_strtol(buf, NULL, 0) != 1)
+ && (hvcs_rescan_status != 0))
+ return -EINVAL;
+
+ hvcs_rescan_status = 1;
+ printk(KERN_INFO "HVCS: rescanning partner info for all"
+ " vty-servers.\n");
+ hvcs_rescan_devices_list();
+ hvcs_rescan_status = 0;
+ return count;
+}
+
+static DRIVER_ATTR(rescan,
+ S_IRUGO | S_IWUSR, hvcs_rescan_show, hvcs_rescan_store);
+
static void hvcs_kick(void)
{
hvcs_kicked = 1;
@@ -575,7 +736,7 @@ static void destroy_hvcs_struct(struct kobject *kobj)
spin_unlock_irqrestore(&hvcsd->lock, flags);
spin_unlock(&hvcs_structs_lock);
- hvcs_remove_device_attrs(vdev);
+ sysfs_remove_group(&vdev->dev.kobj, &hvcs_attr_group);
kfree(hvcsd);
}
@@ -608,6 +769,7 @@ static int __devinit hvcs_probe(
{
struct hvcs_struct *hvcsd;
int index;
+ int retval;
if (!dev || !id) {
printk(KERN_ERR "HVCS: probed with invalid parameter.\n");
@@ -658,14 +820,16 @@ static int __devinit hvcs_probe(
* the hvcs_struct has been added to the devices list then the user app
* will get -ENODEV.
*/
-
spin_lock(&hvcs_structs_lock);
-
list_add_tail(&(hvcsd->next), &hvcs_structs);
-
spin_unlock(&hvcs_structs_lock);
- hvcs_create_device_attrs(hvcsd);
+ retval = sysfs_create_group(&dev->dev.kobj, &hvcs_attr_group);
+ if (retval) {
+ printk(KERN_ERR "HVCS: Can't create sysfs attrs for vty-server@%X\n",
+ hvcsd->vdev->unit_address);
+ return retval;
+ }
printk(KERN_INFO "HVCS: vty-server@%X added to the vio bus.\n", dev->unit_address);
@@ -1354,8 +1518,10 @@ static int __init hvcs_module_init(void)
if (!hvcs_tty_driver)
return -ENOMEM;
- if (hvcs_alloc_index_list(num_ttys_to_alloc))
- return -ENOMEM;
+ if (hvcs_alloc_index_list(num_ttys_to_alloc)) {
+ rc = -ENOMEM;
+ goto index_fail;
+ }
hvcs_tty_driver->owner = THIS_MODULE;
@@ -1385,41 +1551,57 @@ static int __init hvcs_module_init(void)
* dynamically assigned major and minor numbers for our devices.
*/
if (tty_register_driver(hvcs_tty_driver)) {
- printk(KERN_ERR "HVCS: registration "
- " as a tty driver failed.\n");
- hvcs_free_index_list();
- put_tty_driver(hvcs_tty_driver);
- return -EIO;
+ printk(KERN_ERR "HVCS: registration as a tty driver failed.\n");
+ rc = -EIO;
+ goto register_fail;
}
hvcs_pi_buff = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!hvcs_pi_buff) {
- tty_unregister_driver(hvcs_tty_driver);
- hvcs_free_index_list();
- put_tty_driver(hvcs_tty_driver);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto buff_alloc_fail;
}
hvcs_task = kthread_run(khvcsd, NULL, "khvcsd");
if (IS_ERR(hvcs_task)) {
printk(KERN_ERR "HVCS: khvcsd creation failed. Driver not loaded.\n");
- kfree(hvcs_pi_buff);
- tty_unregister_driver(hvcs_tty_driver);
- hvcs_free_index_list();
- put_tty_driver(hvcs_tty_driver);
- return -EIO;
+ rc = -EIO;
+ goto kthread_fail;
}
rc = vio_register_driver(&hvcs_vio_driver);
+ if (rc) {
+ printk(KERN_ERR "HVCS: can't register vio driver\n");
+ goto vio_fail;
+ }
/*
* This needs to be done AFTER the vio_register_driver() call or else
* the kobjects won't be initialized properly.
*/
- hvcs_create_driver_attrs();
+ rc = driver_create_file(&(hvcs_vio_driver.driver), &driver_attr_rescan);
+ if (rc) {
+ printk(KERN_ERR "HVCS: sysfs attr create failed\n");
+ goto attr_fail;
+ }
printk(KERN_INFO "HVCS: driver module inserted.\n");
+ return 0;
+
+attr_fail:
+ vio_unregister_driver(&hvcs_vio_driver);
+vio_fail:
+ kthread_stop(hvcs_task);
+kthread_fail:
+ kfree(hvcs_pi_buff);
+buff_alloc_fail:
+ tty_unregister_driver(hvcs_tty_driver);
+register_fail:
+ hvcs_free_index_list();
+index_fail:
+ put_tty_driver(hvcs_tty_driver);
+ hvcs_tty_driver = NULL;
return rc;
}
@@ -1441,7 +1623,7 @@ static void __exit hvcs_module_exit(void)
hvcs_pi_buff = NULL;
spin_unlock(&hvcs_pi_lock);
- hvcs_remove_driver_attrs();
+ driver_remove_file(&hvcs_vio_driver.driver, &driver_attr_rescan);
vio_unregister_driver(&hvcs_vio_driver);
@@ -1456,191 +1638,3 @@ static void __exit hvcs_module_exit(void)
module_init(hvcs_module_init);
module_exit(hvcs_module_exit);
-
-static inline struct hvcs_struct *from_vio_dev(struct vio_dev *viod)
-{
- return viod->dev.driver_data;
-}
-/* The sysfs interface for the driver and devices */
-
-static ssize_t hvcs_partner_vtys_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct vio_dev *viod = to_vio_dev(dev);
- struct hvcs_struct *hvcsd = from_vio_dev(viod);
- unsigned long flags;
- int retval;
-
- spin_lock_irqsave(&hvcsd->lock, flags);
- retval = sprintf(buf, "%X\n", hvcsd->p_unit_address);
- spin_unlock_irqrestore(&hvcsd->lock, flags);
- return retval;
-}
-static DEVICE_ATTR(partner_vtys, S_IRUGO, hvcs_partner_vtys_show, NULL);
-
-static ssize_t hvcs_partner_clcs_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct vio_dev *viod = to_vio_dev(dev);
- struct hvcs_struct *hvcsd = from_vio_dev(viod);
- unsigned long flags;
- int retval;
-
- spin_lock_irqsave(&hvcsd->lock, flags);
- retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]);
- spin_unlock_irqrestore(&hvcsd->lock, flags);
- return retval;
-}
-static DEVICE_ATTR(partner_clcs, S_IRUGO, hvcs_partner_clcs_show, NULL);
-
-static ssize_t hvcs_current_vty_store(struct device *dev, struct device_attribute *attr, const char * buf,
- size_t count)
-{
- /*
- * Don't need this feature at the present time because firmware doesn't
- * yet support multiple partners.
- */
- printk(KERN_INFO "HVCS: Denied current_vty change: -EPERM.\n");
- return -EPERM;
-}
-
-static ssize_t hvcs_current_vty_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct vio_dev *viod = to_vio_dev(dev);
- struct hvcs_struct *hvcsd = from_vio_dev(viod);
- unsigned long flags;
- int retval;
-
- spin_lock_irqsave(&hvcsd->lock, flags);
- retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]);
- spin_unlock_irqrestore(&hvcsd->lock, flags);
- return retval;
-}
-
-static DEVICE_ATTR(current_vty,
- S_IRUGO | S_IWUSR, hvcs_current_vty_show, hvcs_current_vty_store);
-
-static ssize_t hvcs_vterm_state_store(struct device *dev, struct device_attribute *attr, const char *buf,
- size_t count)
-{
- struct vio_dev *viod = to_vio_dev(dev);
- struct hvcs_struct *hvcsd = from_vio_dev(viod);
- unsigned long flags;
-
- /* writing a '0' to this sysfs entry will result in the disconnect. */
- if (simple_strtol(buf, NULL, 0) != 0)
- return -EINVAL;
-
- spin_lock_irqsave(&hvcsd->lock, flags);
-
- if (hvcsd->open_count > 0) {
- spin_unlock_irqrestore(&hvcsd->lock, flags);
- printk(KERN_INFO "HVCS: vterm state unchanged. "
- "The hvcs device node is still in use.\n");
- return -EPERM;
- }
-
- if (hvcsd->connected == 0) {
- spin_unlock_irqrestore(&hvcsd->lock, flags);
- printk(KERN_INFO "HVCS: vterm state unchanged. The"
- " vty-server is not connected to a vty.\n");
- return -EPERM;
- }
-
- hvcs_partner_free(hvcsd);
- printk(KERN_INFO "HVCS: Closed vty-server@%X and"
- " partner vty@%X:%d connection.\n",
- hvcsd->vdev->unit_address,
- hvcsd->p_unit_address,
- (uint32_t)hvcsd->p_partition_ID);
-
- spin_unlock_irqrestore(&hvcsd->lock, flags);
- return count;
-}
-
-static ssize_t hvcs_vterm_state_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct vio_dev *viod = to_vio_dev(dev);
- struct hvcs_struct *hvcsd = from_vio_dev(viod);
- unsigned long flags;
- int retval;
-
- spin_lock_irqsave(&hvcsd->lock, flags);
- retval = sprintf(buf, "%d\n", hvcsd->connected);
- spin_unlock_irqrestore(&hvcsd->lock, flags);
- return retval;
-}
-static DEVICE_ATTR(vterm_state, S_IRUGO | S_IWUSR,
- hvcs_vterm_state_show, hvcs_vterm_state_store);
-
-static ssize_t hvcs_index_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct vio_dev *viod = to_vio_dev(dev);
- struct hvcs_struct *hvcsd = from_vio_dev(viod);
- unsigned long flags;
- int retval;
-
- spin_lock_irqsave(&hvcsd->lock, flags);
- retval = sprintf(buf, "%d\n", hvcsd->index);
- spin_unlock_irqrestore(&hvcsd->lock, flags);
- return retval;
-}
-
-static DEVICE_ATTR(index, S_IRUGO, hvcs_index_show, NULL);
-
-static struct attribute *hvcs_attrs[] = {
- &dev_attr_partner_vtys.attr,
- &dev_attr_partner_clcs.attr,
- &dev_attr_current_vty.attr,
- &dev_attr_vterm_state.attr,
- &dev_attr_index.attr,
- NULL,
-};
-
-static struct attribute_group hvcs_attr_group = {
- .attrs = hvcs_attrs,
-};
-
-static void hvcs_create_device_attrs(struct hvcs_struct *hvcsd)
-{
- struct vio_dev *vdev = hvcsd->vdev;
- sysfs_create_group(&vdev->dev.kobj, &hvcs_attr_group);
-}
-
-static void hvcs_remove_device_attrs(struct vio_dev *vdev)
-{
- sysfs_remove_group(&vdev->dev.kobj, &hvcs_attr_group);
-}
-
-static ssize_t hvcs_rescan_show(struct device_driver *ddp, char *buf)
-{
- /* A 1 means it is updating, a 0 means it is done updating */
- return snprintf(buf, PAGE_SIZE, "%d\n", hvcs_rescan_status);
-}
-
-static ssize_t hvcs_rescan_store(struct device_driver *ddp, const char * buf,
- size_t count)
-{
- if ((simple_strtol(buf, NULL, 0) != 1)
- && (hvcs_rescan_status != 0))
- return -EINVAL;
-
- hvcs_rescan_status = 1;
- printk(KERN_INFO "HVCS: rescanning partner info for all"
- " vty-servers.\n");
- hvcs_rescan_devices_list();
- hvcs_rescan_status = 0;
- return count;
-}
-static DRIVER_ATTR(rescan,
- S_IRUGO | S_IWUSR, hvcs_rescan_show, hvcs_rescan_store);
-
-static void hvcs_create_driver_attrs(void)
-{
- struct device_driver *driverfs = &(hvcs_vio_driver.driver);
- driver_create_file(driverfs, &driver_attr_rescan);
-}
-
-static void hvcs_remove_driver_attrs(void)
-{
- struct device_driver *driverfs = &(hvcs_vio_driver.driver);
- driver_remove_file(driverfs, &driver_attr_rescan);
-}
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 9f7635f7517..5f3acd8e64b 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -3,17 +3,20 @@
#
config HW_RANDOM
- bool "Hardware Random Number Generator Core support"
- default y
+ tristate "Hardware Random Number Generator Core support"
+ default m
---help---
Hardware Random Number Generator Core infrastructure.
+ To compile this driver as a module, choose M here: the
+ module will be called rng-core.
+
If unsure, say Y.
config HW_RANDOM_INTEL
tristate "Intel HW Random Number Generator support"
depends on HW_RANDOM && (X86 || IA64) && PCI
- default y
+ default HW_RANDOM
---help---
This driver provides kernel-side support for the Random Number
Generator hardware found on Intel i8xx-based motherboards.
@@ -26,7 +29,7 @@ config HW_RANDOM_INTEL
config HW_RANDOM_AMD
tristate "AMD HW Random Number Generator support"
depends on HW_RANDOM && X86 && PCI
- default y
+ default HW_RANDOM
---help---
This driver provides kernel-side support for the Random Number
Generator hardware found on AMD 76x-based motherboards.
@@ -39,7 +42,7 @@ config HW_RANDOM_AMD
config HW_RANDOM_GEODE
tristate "AMD Geode HW Random Number Generator support"
depends on HW_RANDOM && X86 && PCI
- default y
+ default HW_RANDOM
---help---
This driver provides kernel-side support for the Random Number
Generator hardware found on the AMD Geode LX.
@@ -52,7 +55,7 @@ config HW_RANDOM_GEODE
config HW_RANDOM_VIA
tristate "VIA HW Random Number Generator support"
depends on HW_RANDOM && X86_32
- default y
+ default HW_RANDOM
---help---
This driver provides kernel-side support for the Random Number
Generator hardware found on VIA based motherboards.
@@ -65,7 +68,7 @@ config HW_RANDOM_VIA
config HW_RANDOM_IXP4XX
tristate "Intel IXP4xx NPU HW Random Number Generator support"
depends on HW_RANDOM && ARCH_IXP4XX
- default y
+ default HW_RANDOM
---help---
This driver provides kernel-side support for the Random
Number Generator hardware found on the Intel IXP4xx NPU.
@@ -78,7 +81,7 @@ config HW_RANDOM_IXP4XX
config HW_RANDOM_OMAP
tristate "OMAP Random Number Generator support"
depends on HW_RANDOM && (ARCH_OMAP16XX || ARCH_OMAP24XX)
- default y
+ default HW_RANDOM
---help---
This driver provides kernel-side support for the Random Number
Generator hardware found on OMAP16xx and OMAP24xx multimedia
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index e263ae96f94..c41fa19454e 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -2,7 +2,8 @@
# Makefile for HW Random Number Generator (RNG) device drivers.
#
-obj-$(CONFIG_HW_RANDOM) += core.o
+obj-$(CONFIG_HW_RANDOM) += rng-core.o
+rng-core-y := core.o
obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
diff --git a/drivers/char/ip2/i2cmd.h b/drivers/char/ip2/i2cmd.h
index baa4e721b75..29277ec6b8e 100644
--- a/drivers/char/ip2/i2cmd.h
+++ b/drivers/char/ip2/i2cmd.h
@@ -367,11 +367,6 @@ static UCHAR cc02[];
#define CSE_NULL 3 // Replace with a null
#define CSE_MARK 4 // Replace with a 3-character sequence (as Unix)
-#define CMD_SET_REPLACEMENT(arg,ch) \
- (((cmdSyntaxPtr)(ct36a))->cmd[1] = (arg), \
- (((cmdSyntaxPtr)(ct36a))->cmd[2] = (ch), \
- (cmdSyntaxPtr)(ct36a))
-
#define CSE_REPLACE 0x8 // Replace the errored character with the
// replacement character defined here
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
index c213fdbdb2b..78045767ec3 100644
--- a/drivers/char/ip2/i2lib.c
+++ b/drivers/char/ip2/i2lib.c
@@ -1016,7 +1016,6 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count)
unsigned short channel;
unsigned short stuffIndex;
unsigned long flags;
- int rc = 0;
int bailout = 10;
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c
index 0030cd8e2e9..6c59baa887a 100644
--- a/drivers/char/ipmi/ipmi_bt_sm.c
+++ b/drivers/char/ipmi/ipmi_bt_sm.c
@@ -33,11 +33,13 @@
#include <linux/ipmi_msgdefs.h> /* for completion codes */
#include "ipmi_si_sm.h"
-static int bt_debug = 0x00; /* Production value 0, see following flags */
+#define BT_DEBUG_OFF 0 /* Used in production */
+#define BT_DEBUG_ENABLE 1 /* Generic messages */
+#define BT_DEBUG_MSG 2 /* Prints all request/response buffers */
+#define BT_DEBUG_STATES 4 /* Verbose look at state changes */
+
+static int bt_debug = BT_DEBUG_OFF;
-#define BT_DEBUG_ENABLE 1
-#define BT_DEBUG_MSG 2
-#define BT_DEBUG_STATES 4
module_param(bt_debug, int, 0644);
MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
@@ -47,38 +49,54 @@ MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
Since the Open IPMI architecture is single-message oriented at this
stage, the queue depth of BT is of no concern. */
-#define BT_NORMAL_TIMEOUT 5000000 /* seconds in microseconds */
-#define BT_RETRY_LIMIT 2
-#define BT_RESET_DELAY 6000000 /* 6 seconds after warm reset */
+#define BT_NORMAL_TIMEOUT 5 /* seconds */
+#define BT_NORMAL_RETRY_LIMIT 2
+#define BT_RESET_DELAY 6 /* seconds after warm reset */
+
+/* States are written in chronological order and usually cover
+ multiple rows of the state table discussion in the IPMI spec. */
enum bt_states {
- BT_STATE_IDLE,
+ BT_STATE_IDLE = 0, /* Order is critical in this list */
BT_STATE_XACTION_START,
BT_STATE_WRITE_BYTES,
- BT_STATE_WRITE_END,
BT_STATE_WRITE_CONSUME,
- BT_STATE_B2H_WAIT,
- BT_STATE_READ_END,
- BT_STATE_RESET1, /* These must come last */
+ BT_STATE_READ_WAIT,
+ BT_STATE_CLEAR_B2H,
+ BT_STATE_READ_BYTES,
+ BT_STATE_RESET1, /* These must come last */
BT_STATE_RESET2,
BT_STATE_RESET3,
BT_STATE_RESTART,
- BT_STATE_HOSED
+ BT_STATE_PRINTME,
+ BT_STATE_CAPABILITIES_BEGIN,
+ BT_STATE_CAPABILITIES_END,
+ BT_STATE_LONG_BUSY /* BT doesn't get hosed :-) */
};
+/* Macros seen at the end of state "case" blocks. They help with legibility
+ and debugging. */
+
+#define BT_STATE_CHANGE(X,Y) { bt->state = X; return Y; }
+
+#define BT_SI_SM_RETURN(Y) { last_printed = BT_STATE_PRINTME; return Y; }
+
struct si_sm_data {
enum bt_states state;
- enum bt_states last_state; /* assist printing and resets */
unsigned char seq; /* BT sequence number */
struct si_sm_io *io;
- unsigned char write_data[IPMI_MAX_MSG_LENGTH];
- int write_count;
- unsigned char read_data[IPMI_MAX_MSG_LENGTH];
- int read_count;
- int truncated;
- long timeout;
- unsigned int error_retries; /* end of "common" fields */
+ unsigned char write_data[IPMI_MAX_MSG_LENGTH];
+ int write_count;
+ unsigned char read_data[IPMI_MAX_MSG_LENGTH];
+ int read_count;
+ int truncated;
+ long timeout; /* microseconds countdown */
+ int error_retries; /* end of "common" fields */
int nonzero_status; /* hung BMCs stay all 0 */
+ enum bt_states complete; /* to divert the state machine */
+ int BT_CAP_outreqs;
+ long BT_CAP_req2rsp;
+ int BT_CAP_retries; /* Recommended retries */
};
#define BT_CLR_WR_PTR 0x01 /* See IPMI 1.5 table 11.6.4 */
@@ -111,86 +129,118 @@ struct si_sm_data {
static char *state2txt(unsigned char state)
{
switch (state) {
- case BT_STATE_IDLE: return("IDLE");
- case BT_STATE_XACTION_START: return("XACTION");
- case BT_STATE_WRITE_BYTES: return("WR_BYTES");
- case BT_STATE_WRITE_END: return("WR_END");
- case BT_STATE_WRITE_CONSUME: return("WR_CONSUME");
- case BT_STATE_B2H_WAIT: return("B2H_WAIT");
- case BT_STATE_READ_END: return("RD_END");
- case BT_STATE_RESET1: return("RESET1");
- case BT_STATE_RESET2: return("RESET2");
- case BT_STATE_RESET3: return("RESET3");
- case BT_STATE_RESTART: return("RESTART");
- case BT_STATE_HOSED: return("HOSED");
+ case BT_STATE_IDLE: return("IDLE");
+ case BT_STATE_XACTION_START: return("XACTION");
+ case BT_STATE_WRITE_BYTES: return("WR_BYTES");
+ case BT_STATE_WRITE_CONSUME: return("WR_CONSUME");
+ case BT_STATE_READ_WAIT: return("RD_WAIT");
+ case BT_STATE_CLEAR_B2H: return("CLEAR_B2H");
+ case BT_STATE_READ_BYTES: return("RD_BYTES");
+ case BT_STATE_RESET1: return("RESET1");
+ case BT_STATE_RESET2: return("RESET2");
+ case BT_STATE_RESET3: return("RESET3");
+ case BT_STATE_RESTART: return("RESTART");
+ case BT_STATE_LONG_BUSY: return("LONG_BUSY");
+ case BT_STATE_CAPABILITIES_BEGIN: return("CAP_BEGIN");
+ case BT_STATE_CAPABILITIES_END: return("CAP_END");
}
return("BAD STATE");
}
#define STATE2TXT state2txt(bt->state)
-static char *status2txt(unsigned char status, char *buf)
+static char *status2txt(unsigned char status)
{
+ /*
+ * This cannot be called by two threads at the same time and
+ * the buffer is always consumed immediately, so the static is
+ * safe to use.
+ */
+ static char buf[40];
+
strcpy(buf, "[ ");
- if (status & BT_B_BUSY) strcat(buf, "B_BUSY ");
- if (status & BT_H_BUSY) strcat(buf, "H_BUSY ");
- if (status & BT_OEM0) strcat(buf, "OEM0 ");
- if (status & BT_SMS_ATN) strcat(buf, "SMS ");
- if (status & BT_B2H_ATN) strcat(buf, "B2H ");
- if (status & BT_H2B_ATN) strcat(buf, "H2B ");
+ if (status & BT_B_BUSY)
+ strcat(buf, "B_BUSY ");
+ if (status & BT_H_BUSY)
+ strcat(buf, "H_BUSY ");
+ if (status & BT_OEM0)
+ strcat(buf, "OEM0 ");
+ if (status & BT_SMS_ATN)
+ strcat(buf, "SMS ");
+ if (status & BT_B2H_ATN)
+ strcat(buf, "B2H ");
+ if (status & BT_H2B_ATN)
+ strcat(buf, "H2B ");
strcat(buf, "]");
return buf;
}
-#define STATUS2TXT(buf) status2txt(status, buf)
+#define STATUS2TXT status2txt(status)
+
+/* called externally at insmod time, and internally on cleanup */
-/* This will be called from within this module on a hosed condition */
-#define FIRST_SEQ 0
static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io)
{
- bt->state = BT_STATE_IDLE;
- bt->last_state = BT_STATE_IDLE;
- bt->seq = FIRST_SEQ;
- bt->io = io;
- bt->write_count = 0;
- bt->read_count = 0;
- bt->error_retries = 0;
- bt->nonzero_status = 0;
- bt->truncated = 0;
- bt->timeout = BT_NORMAL_TIMEOUT;
+ memset(bt, 0, sizeof(struct si_sm_data));
+ if (bt->io != io) { /* external: one-time only things */
+ bt->io = io;
+ bt->seq = 0;
+ }
+ bt->state = BT_STATE_IDLE; /* start here */
+ bt->complete = BT_STATE_IDLE; /* end here */
+ bt->BT_CAP_req2rsp = BT_NORMAL_TIMEOUT * 1000000;
+ bt->BT_CAP_retries = BT_NORMAL_RETRY_LIMIT;
+ /* BT_CAP_outreqs == zero is a flag to read BT Capabilities */
return 3; /* We claim 3 bytes of space; ought to check SPMI table */
}
+/* Jam a completion code (probably an error) into a response */
+
+static void force_result(struct si_sm_data *bt, unsigned char completion_code)
+{
+ bt->read_data[0] = 4; /* # following bytes */
+ bt->read_data[1] = bt->write_data[1] | 4; /* Odd NetFn/LUN */
+ bt->read_data[2] = bt->write_data[2]; /* seq (ignored) */
+ bt->read_data[3] = bt->write_data[3]; /* Command */
+ bt->read_data[4] = completion_code;
+ bt->read_count = 5;
+}
+
+/* The upper state machine starts here */
+
static int bt_start_transaction(struct si_sm_data *bt,
unsigned char *data,
unsigned int size)
{
unsigned int i;
- if ((size < 2) || (size > (IPMI_MAX_MSG_LENGTH - 2)))
- return -1;
+ if (size < 2)
+ return IPMI_REQ_LEN_INVALID_ERR;
+ if (size > IPMI_MAX_MSG_LENGTH)
+ return IPMI_REQ_LEN_EXCEEDED_ERR;
- if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED))
- return -2;
+ if (bt->state == BT_STATE_LONG_BUSY)
+ return IPMI_NODE_BUSY_ERR;
+
+ if (bt->state != BT_STATE_IDLE)
+ return IPMI_NOT_IN_MY_STATE_ERR;
if (bt_debug & BT_DEBUG_MSG) {
- printk(KERN_WARNING "+++++++++++++++++++++++++++++++++++++\n");
- printk(KERN_WARNING "BT: write seq=0x%02X:", bt->seq);
+ printk(KERN_WARNING "BT: +++++++++++++++++ New command\n");
+ printk(KERN_WARNING "BT: NetFn/LUN CMD [%d data]:", size - 2);
for (i = 0; i < size; i ++)
- printk (" %02x", data[i]);
+ printk (" %02x", data[i]);
printk("\n");
}
bt->write_data[0] = size + 1; /* all data plus seq byte */
bt->write_data[1] = *data; /* NetFn/LUN */
- bt->write_data[2] = bt->seq;
+ bt->write_data[2] = bt->seq++;
memcpy(bt->write_data + 3, data + 1, size - 1);
bt->write_count = size + 2;
-
bt->error_retries = 0;
bt->nonzero_status = 0;
- bt->read_count = 0;
bt->truncated = 0;
bt->state = BT_STATE_XACTION_START;
- bt->last_state = BT_STATE_IDLE;
- bt->timeout = BT_NORMAL_TIMEOUT;
+ bt->timeout = bt->BT_CAP_req2rsp;
+ force_result(bt, IPMI_ERR_UNSPECIFIED);
return 0;
}
@@ -198,38 +248,30 @@ static int bt_start_transaction(struct si_sm_data *bt,
it calls this. Strip out the length and seq bytes. */
static int bt_get_result(struct si_sm_data *bt,
- unsigned char *data,
- unsigned int length)
+ unsigned char *data,
+ unsigned int length)
{
int i, msg_len;
msg_len = bt->read_count - 2; /* account for length & seq */
- /* Always NetFn, Cmd, cCode */
if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) {
- printk(KERN_DEBUG "BT results: bad msg_len = %d\n", msg_len);
- data[0] = bt->write_data[1] | 0x4; /* Kludge a response */
- data[1] = bt->write_data[3];
- data[2] = IPMI_ERR_UNSPECIFIED;
+ force_result(bt, IPMI_ERR_UNSPECIFIED);
msg_len = 3;
- } else {
- data[0] = bt->read_data[1];
- data[1] = bt->read_data[3];
- if (length < msg_len)
- bt->truncated = 1;
- if (bt->truncated) { /* can be set in read_all_bytes() */
- data[2] = IPMI_ERR_MSG_TRUNCATED;
- msg_len = 3;
- } else
- memcpy(data + 2, bt->read_data + 4, msg_len - 2);
+ }
+ data[0] = bt->read_data[1];
+ data[1] = bt->read_data[3];
+ if (length < msg_len || bt->truncated) {
+ data[2] = IPMI_ERR_MSG_TRUNCATED;
+ msg_len = 3;
+ } else
+ memcpy(data + 2, bt->read_data + 4, msg_len - 2);
- if (bt_debug & BT_DEBUG_MSG) {
- printk (KERN_WARNING "BT: res (raw)");
- for (i = 0; i < msg_len; i++)
- printk(" %02x", data[i]);
- printk ("\n");
- }
+ if (bt_debug & BT_DEBUG_MSG) {
+ printk (KERN_WARNING "BT: result %d bytes:", msg_len);
+ for (i = 0; i < msg_len; i++)
+ printk(" %02x", data[i]);
+ printk ("\n");
}
- bt->read_count = 0; /* paranoia */
return msg_len;
}
@@ -238,22 +280,40 @@ static int bt_get_result(struct si_sm_data *bt,
static void reset_flags(struct si_sm_data *bt)
{
+ if (bt_debug)
+ printk(KERN_WARNING "IPMI BT: flag reset %s\n",
+ status2txt(BT_STATUS));
if (BT_STATUS & BT_H_BUSY)
- BT_CONTROL(BT_H_BUSY);
- if (BT_STATUS & BT_B_BUSY)
- BT_CONTROL(BT_B_BUSY);
- BT_CONTROL(BT_CLR_WR_PTR);
- BT_CONTROL(BT_SMS_ATN);
-
- if (BT_STATUS & BT_B2H_ATN) {
- int i;
- BT_CONTROL(BT_H_BUSY);
- BT_CONTROL(BT_B2H_ATN);
- BT_CONTROL(BT_CLR_RD_PTR);
- for (i = 0; i < IPMI_MAX_MSG_LENGTH + 2; i++)
- BMC2HOST;
- BT_CONTROL(BT_H_BUSY);
- }
+ BT_CONTROL(BT_H_BUSY); /* force clear */
+ BT_CONTROL(BT_CLR_WR_PTR); /* always reset */
+ BT_CONTROL(BT_SMS_ATN); /* always clear */
+ BT_INTMASK_W(BT_BMC_HWRST);
+}
+
+/* Get rid of an unwanted/stale response. This should only be needed for
+ BMCs that support multiple outstanding requests. */
+
+static void drain_BMC2HOST(struct si_sm_data *bt)
+{
+ int i, size;
+
+ if (!(BT_STATUS & BT_B2H_ATN)) /* Not signalling a response */
+ return;
+
+ BT_CONTROL(BT_H_BUSY); /* now set */
+ BT_CONTROL(BT_B2H_ATN); /* always clear */
+ BT_STATUS; /* pause */
+ BT_CONTROL(BT_B2H_ATN); /* some BMCs are stubborn */
+ BT_CONTROL(BT_CLR_RD_PTR); /* always reset */
+ if (bt_debug)
+ printk(KERN_WARNING "IPMI BT: stale response %s; ",
+ status2txt(BT_STATUS));
+ size = BMC2HOST;
+ for (i = 0; i < size ; i++)
+ BMC2HOST;
+ BT_CONTROL(BT_H_BUSY); /* now clear */
+ if (bt_debug)
+ printk("drained %d bytes\n", size + 1);
}
static inline void write_all_bytes(struct si_sm_data *bt)
@@ -261,201 +321,256 @@ static inline void write_all_bytes(struct si_sm_data *bt)
int i;
if (bt_debug & BT_DEBUG_MSG) {
- printk(KERN_WARNING "BT: write %d bytes seq=0x%02X",
+ printk(KERN_WARNING "BT: write %d bytes seq=0x%02X",
bt->write_count, bt->seq);
for (i = 0; i < bt->write_count; i++)
printk (" %02x", bt->write_data[i]);
printk ("\n");
}
for (i = 0; i < bt->write_count; i++)
- HOST2BMC(bt->write_data[i]);
+ HOST2BMC(bt->write_data[i]);
}
static inline int read_all_bytes(struct si_sm_data *bt)
{
unsigned char i;
+ /* length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
+ Keep layout of first four bytes aligned with write_data[] */
+
bt->read_data[0] = BMC2HOST;
bt->read_count = bt->read_data[0];
- if (bt_debug & BT_DEBUG_MSG)
- printk(KERN_WARNING "BT: read %d bytes:", bt->read_count);
- /* minimum: length, NetFn, Seq, Cmd, cCode == 5 total, or 4 more
- following the length byte. */
if (bt->read_count < 4 || bt->read_count >= IPMI_MAX_MSG_LENGTH) {
if (bt_debug & BT_DEBUG_MSG)
- printk("bad length %d\n", bt->read_count);
+ printk(KERN_WARNING "BT: bad raw rsp len=%d\n",
+ bt->read_count);
bt->truncated = 1;
return 1; /* let next XACTION START clean it up */
}
for (i = 1; i <= bt->read_count; i++)
- bt->read_data[i] = BMC2HOST;
- bt->read_count++; /* account for the length byte */
+ bt->read_data[i] = BMC2HOST;
+ bt->read_count++; /* Account internally for length byte */
if (bt_debug & BT_DEBUG_MSG) {
- for (i = 0; i < bt->read_count; i++)
+ int max = bt->read_count;
+
+ printk(KERN_WARNING "BT: got %d bytes seq=0x%02X",
+ max, bt->read_data[2]);
+ if (max > 16)
+ max = 16;
+ for (i = 0; i < max; i++)
printk (" %02x", bt->read_data[i]);
- printk ("\n");
+ printk ("%s\n", bt->read_count == max ? "" : " ...");
}
- if (bt->seq != bt->write_data[2]) /* idiot check */
- printk(KERN_DEBUG "BT: internal error: sequence mismatch\n");
- /* per the spec, the (NetFn, Seq, Cmd) tuples should match */
- if ((bt->read_data[3] == bt->write_data[3]) && /* Cmd */
- (bt->read_data[2] == bt->write_data[2]) && /* Sequence */
- ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8)))
+ /* per the spec, the (NetFn[1], Seq[2], Cmd[3]) tuples must match */
+ if ((bt->read_data[3] == bt->write_data[3]) &&
+ (bt->read_data[2] == bt->write_data[2]) &&
+ ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8)))
return 1;
if (bt_debug & BT_DEBUG_MSG)
- printk(KERN_WARNING "BT: bad packet: "
+ printk(KERN_WARNING "IPMI BT: bad packet: "
"want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n",
- bt->write_data[1], bt->write_data[2], bt->write_data[3],
+ bt->write_data[1] | 0x04, bt->write_data[2], bt->write_data[3],
bt->read_data[1], bt->read_data[2], bt->read_data[3]);
return 0;
}
-/* Modifies bt->state appropriately, need to get into the bt_event() switch */
+/* Restart if retries are left, or return an error completion code */
-static void error_recovery(struct si_sm_data *bt, char *reason)
+static enum si_sm_result error_recovery(struct si_sm_data *bt,
+ unsigned char status,
+ unsigned char cCode)
{
- unsigned char status;
- char buf[40]; /* For getting status */
+ char *reason;
- bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */
+ bt->timeout = bt->BT_CAP_req2rsp;
- status = BT_STATUS;
- printk(KERN_DEBUG "BT: %s in %s %s\n", reason, STATE2TXT,
- STATUS2TXT(buf));
+ switch (cCode) {
+ case IPMI_TIMEOUT_ERR:
+ reason = "timeout";
+ break;
+ default:
+ reason = "internal error";
+ break;
+ }
+
+ printk(KERN_WARNING "IPMI BT: %s in %s %s ", /* open-ended line */
+ reason, STATE2TXT, STATUS2TXT);
+ /* Per the IPMI spec, retries are based on the sequence number
+ known only to this module, so manage a restart here. */
(bt->error_retries)++;
- if (bt->error_retries > BT_RETRY_LIMIT) {
- printk(KERN_DEBUG "retry limit (%d) exceeded\n", BT_RETRY_LIMIT);
- bt->state = BT_STATE_HOSED;
- if (!bt->nonzero_status)
- printk(KERN_ERR "IPMI: BT stuck, try power cycle\n");
- else if (bt->error_retries <= BT_RETRY_LIMIT + 1) {
- printk(KERN_DEBUG "IPMI: BT reset (takes 5 secs)\n");
- bt->state = BT_STATE_RESET1;
- }
- return;
+ if (bt->error_retries < bt->BT_CAP_retries) {
+ printk("%d retries left\n",
+ bt->BT_CAP_retries - bt->error_retries);
+ bt->state = BT_STATE_RESTART;
+ return SI_SM_CALL_WITHOUT_DELAY;
}
- /* Sometimes the BMC queues get in an "off-by-one" state...*/
- if ((bt->state == BT_STATE_B2H_WAIT) && (status & BT_B2H_ATN)) {
- printk(KERN_DEBUG "retry B2H_WAIT\n");
- return;
+ printk("failed %d retries, sending error response\n",
+ bt->BT_CAP_retries);
+ if (!bt->nonzero_status)
+ printk(KERN_ERR "IPMI BT: stuck, try power cycle\n");
+
+ /* this is most likely during insmod */
+ else if (bt->seq <= (unsigned char)(bt->BT_CAP_retries & 0xFF)) {
+ printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n");
+ bt->state = BT_STATE_RESET1;
+ return SI_SM_CALL_WITHOUT_DELAY;
}
- printk(KERN_DEBUG "restart command\n");
- bt->state = BT_STATE_RESTART;
+ /* Concoct a useful error message, set up the next state, and
+ be done with this sequence. */
+
+ bt->state = BT_STATE_IDLE;
+ switch (cCode) {
+ case IPMI_TIMEOUT_ERR:
+ if (status & BT_B_BUSY) {
+ cCode = IPMI_NODE_BUSY_ERR;
+ bt->state = BT_STATE_LONG_BUSY;
+ }
+ break;
+ default:
+ break;
+ }
+ force_result(bt, cCode);
+ return SI_SM_TRANSACTION_COMPLETE;
}
-/* Check the status and (possibly) advance the BT state machine. The
- default return is SI_SM_CALL_WITH_DELAY. */
+/* Check status and (usually) take action and change this state machine. */
static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
{
- unsigned char status;
- char buf[40]; /* For getting status */
+ unsigned char status, BT_CAP[8];
+ static enum bt_states last_printed = BT_STATE_PRINTME;
int i;
status = BT_STATUS;
bt->nonzero_status |= status;
-
- if ((bt_debug & BT_DEBUG_STATES) && (bt->state != bt->last_state))
+ if ((bt_debug & BT_DEBUG_STATES) && (bt->state != last_printed)) {
printk(KERN_WARNING "BT: %s %s TO=%ld - %ld \n",
STATE2TXT,
- STATUS2TXT(buf),
+ STATUS2TXT,
bt->timeout,
time);
- bt->last_state = bt->state;
+ last_printed = bt->state;
+ }
- if (bt->state == BT_STATE_HOSED)
- return SI_SM_HOSED;
+ /* Commands that time out may still (eventually) provide a response.
+ This stale response will get in the way of a new response so remove
+ it if possible (hopefully during IDLE). Even if it comes up later
+ it will be rejected by its (now-forgotten) seq number. */
+
+ if ((bt->state < BT_STATE_WRITE_BYTES) && (status & BT_B2H_ATN)) {
+ drain_BMC2HOST(bt);
+ BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
+ }
- if (bt->state != BT_STATE_IDLE) { /* do timeout test */
+ if ((bt->state != BT_STATE_IDLE) &&
+ (bt->state < BT_STATE_PRINTME)) { /* check timeout */
bt->timeout -= time;
- if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) {
- error_recovery(bt, "timed out");
- return SI_SM_CALL_WITHOUT_DELAY;
- }
+ if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1))
+ return error_recovery(bt,
+ status,
+ IPMI_TIMEOUT_ERR);
}
switch (bt->state) {
- case BT_STATE_IDLE: /* check for asynchronous messages */
+ /* Idle state first checks for asynchronous messages from another
+ channel, then does some opportunistic housekeeping. */
+
+ case BT_STATE_IDLE:
if (status & BT_SMS_ATN) {
BT_CONTROL(BT_SMS_ATN); /* clear it */
return SI_SM_ATTN;
}
- return SI_SM_IDLE;
- case BT_STATE_XACTION_START:
- if (status & BT_H_BUSY) {
+ if (status & BT_H_BUSY) /* clear a leftover H_BUSY */
BT_CONTROL(BT_H_BUSY);
- break;
- }
- if (status & BT_B2H_ATN)
- break;
- bt->state = BT_STATE_WRITE_BYTES;
- return SI_SM_CALL_WITHOUT_DELAY; /* for logging */
- case BT_STATE_WRITE_BYTES:
+ /* Read BT capabilities if it hasn't been done yet */
+ if (!bt->BT_CAP_outreqs)
+ BT_STATE_CHANGE(BT_STATE_CAPABILITIES_BEGIN,
+ SI_SM_CALL_WITHOUT_DELAY);
+ bt->timeout = bt->BT_CAP_req2rsp;
+ BT_SI_SM_RETURN(SI_SM_IDLE);
+
+ case BT_STATE_XACTION_START:
if (status & (BT_B_BUSY | BT_H2B_ATN))
- break;
+ BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
+ if (BT_STATUS & BT_H_BUSY)
+ BT_CONTROL(BT_H_BUSY); /* force clear */
+ BT_STATE_CHANGE(BT_STATE_WRITE_BYTES,
+ SI_SM_CALL_WITHOUT_DELAY);
+
+ case BT_STATE_WRITE_BYTES:
+ if (status & BT_H_BUSY)
+ BT_CONTROL(BT_H_BUSY); /* clear */
BT_CONTROL(BT_CLR_WR_PTR);
write_all_bytes(bt);
- BT_CONTROL(BT_H2B_ATN); /* clears too fast to catch? */
- bt->state = BT_STATE_WRITE_CONSUME;
- return SI_SM_CALL_WITHOUT_DELAY; /* it MIGHT sail through */
-
- case BT_STATE_WRITE_CONSUME: /* BMCs usually blow right thru here */
- if (status & (BT_H2B_ATN | BT_B_BUSY))
- break;
- bt->state = BT_STATE_B2H_WAIT;
- /* fall through with status */
-
- /* Stay in BT_STATE_B2H_WAIT until a packet matches. However, spinning
- hard here, constantly reading status, seems to hold off the
- generation of B2H_ATN so ALWAYS return CALL_WITH_DELAY. */
-
- case BT_STATE_B2H_WAIT:
- if (!(status & BT_B2H_ATN))
- break;
-
- /* Assume ordered, uncached writes: no need to wait */
- if (!(status & BT_H_BUSY))
- BT_CONTROL(BT_H_BUSY); /* set */
- BT_CONTROL(BT_B2H_ATN); /* clear it, ACK to the BMC */
- BT_CONTROL(BT_CLR_RD_PTR); /* reset the queue */
- i = read_all_bytes(bt);
- BT_CONTROL(BT_H_BUSY); /* clear */
- if (!i) /* Try this state again */
- break;
- bt->state = BT_STATE_READ_END;
- return SI_SM_CALL_WITHOUT_DELAY; /* for logging */
-
- case BT_STATE_READ_END:
-
- /* I could wait on BT_H_BUSY to go clear for a truly clean
- exit. However, this is already done in XACTION_START
- and the (possible) extra loop/status/possible wait affects
- performance. So, as long as it works, just ignore H_BUSY */
-
-#ifdef MAKE_THIS_TRUE_IF_NECESSARY
+ BT_CONTROL(BT_H2B_ATN); /* can clear too fast to catch */
+ BT_STATE_CHANGE(BT_STATE_WRITE_CONSUME,
+ SI_SM_CALL_WITHOUT_DELAY);
- if (status & BT_H_BUSY)
- break;
-#endif
- bt->seq++;
- bt->state = BT_STATE_IDLE;
- return SI_SM_TRANSACTION_COMPLETE;
+ case BT_STATE_WRITE_CONSUME:
+ if (status & (BT_B_BUSY | BT_H2B_ATN))
+ BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
+ BT_STATE_CHANGE(BT_STATE_READ_WAIT,
+ SI_SM_CALL_WITHOUT_DELAY);
+
+ /* Spinning hard can suppress B2H_ATN and force a timeout */
+
+ case BT_STATE_READ_WAIT:
+ if (!(status & BT_B2H_ATN))
+ BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
+ BT_CONTROL(BT_H_BUSY); /* set */
+
+ /* Uncached, ordered writes should just proceeed serially but
+ some BMCs don't clear B2H_ATN with one hit. Fast-path a
+ workaround without too much penalty to the general case. */
+
+ BT_CONTROL(BT_B2H_ATN); /* clear it to ACK the BMC */
+ BT_STATE_CHANGE(BT_STATE_CLEAR_B2H,
+ SI_SM_CALL_WITHOUT_DELAY);
+
+ case BT_STATE_CLEAR_B2H:
+ if (status & BT_B2H_ATN) { /* keep hitting it */
+ BT_CONTROL(BT_B2H_ATN);
+ BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
+ }
+ BT_STATE_CHANGE(BT_STATE_READ_BYTES,
+ SI_SM_CALL_WITHOUT_DELAY);
+
+ case BT_STATE_READ_BYTES:
+ if (!(status & BT_H_BUSY)) /* check in case of retry */
+ BT_CONTROL(BT_H_BUSY);
+ BT_CONTROL(BT_CLR_RD_PTR); /* start of BMC2HOST buffer */
+ i = read_all_bytes(bt); /* true == packet seq match */
+ BT_CONTROL(BT_H_BUSY); /* NOW clear */
+ if (!i) /* Not my message */
+ BT_STATE_CHANGE(BT_STATE_READ_WAIT,
+ SI_SM_CALL_WITHOUT_DELAY);
+ bt->state = bt->complete;
+ return bt->state == BT_STATE_IDLE ? /* where to next? */
+ SI_SM_TRANSACTION_COMPLETE : /* normal */
+ SI_SM_CALL_WITHOUT_DELAY; /* Startup magic */
+
+ case BT_STATE_LONG_BUSY: /* For example: after FW update */
+ if (!(status & BT_B_BUSY)) {
+ reset_flags(bt); /* next state is now IDLE */
+ bt_init_data(bt, bt->io);
+ }
+ return SI_SM_CALL_WITH_DELAY; /* No repeat printing */
case BT_STATE_RESET1:
- reset_flags(bt);
- bt->timeout = BT_RESET_DELAY;
- bt->state = BT_STATE_RESET2;
- break;
+ reset_flags(bt);
+ drain_BMC2HOST(bt);
+ BT_STATE_CHANGE(BT_STATE_RESET2,
+ SI_SM_CALL_WITH_DELAY);
case BT_STATE_RESET2: /* Send a soft reset */
BT_CONTROL(BT_CLR_WR_PTR);
@@ -464,29 +579,59 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
HOST2BMC(42); /* Sequence number */
HOST2BMC(3); /* Cmd == Soft reset */
BT_CONTROL(BT_H2B_ATN);
- bt->state = BT_STATE_RESET3;
- break;
+ bt->timeout = BT_RESET_DELAY * 1000000;
+ BT_STATE_CHANGE(BT_STATE_RESET3,
+ SI_SM_CALL_WITH_DELAY);
- case BT_STATE_RESET3:
+ case BT_STATE_RESET3: /* Hold off everything for a bit */
if (bt->timeout > 0)
- return SI_SM_CALL_WITH_DELAY;
- bt->state = BT_STATE_RESTART; /* printk in debug modes */
- break;
+ return SI_SM_CALL_WITH_DELAY;
+ drain_BMC2HOST(bt);
+ BT_STATE_CHANGE(BT_STATE_RESTART,
+ SI_SM_CALL_WITH_DELAY);
- case BT_STATE_RESTART: /* don't reset retries! */
- reset_flags(bt);
- bt->write_data[2] = ++bt->seq;
+ case BT_STATE_RESTART: /* don't reset retries or seq! */
bt->read_count = 0;
bt->nonzero_status = 0;
- bt->timeout = BT_NORMAL_TIMEOUT;
- bt->state = BT_STATE_XACTION_START;
- break;
-
- default: /* HOSED is supposed to be caught much earlier */
- error_recovery(bt, "internal logic error");
- break;
- }
- return SI_SM_CALL_WITH_DELAY;
+ bt->timeout = bt->BT_CAP_req2rsp;
+ BT_STATE_CHANGE(BT_STATE_XACTION_START,
+ SI_SM_CALL_WITH_DELAY);
+
+ /* Get BT Capabilities, using timing of upper level state machine.
+ Set outreqs to prevent infinite loop on timeout. */
+ case BT_STATE_CAPABILITIES_BEGIN:
+ bt->BT_CAP_outreqs = 1;
+ {
+ unsigned char GetBT_CAP[] = { 0x18, 0x36 };
+ bt->state = BT_STATE_IDLE;
+ bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP));
+ }
+ bt->complete = BT_STATE_CAPABILITIES_END;
+ BT_STATE_CHANGE(BT_STATE_XACTION_START,
+ SI_SM_CALL_WITH_DELAY);
+
+ case BT_STATE_CAPABILITIES_END:
+ i = bt_get_result(bt, BT_CAP, sizeof(BT_CAP));
+ bt_init_data(bt, bt->io);
+ if ((i == 8) && !BT_CAP[2]) {
+ bt->BT_CAP_outreqs = BT_CAP[3];
+ bt->BT_CAP_req2rsp = BT_CAP[6] * 1000000;
+ bt->BT_CAP_retries = BT_CAP[7];
+ } else
+ printk(KERN_WARNING "IPMI BT: using default values\n");
+ if (!bt->BT_CAP_outreqs)
+ bt->BT_CAP_outreqs = 1;
+ printk(KERN_WARNING "IPMI BT: req2rsp=%ld secs retries=%d\n",
+ bt->BT_CAP_req2rsp / 1000000L, bt->BT_CAP_retries);
+ bt->timeout = bt->BT_CAP_req2rsp;
+ return SI_SM_CALL_WITHOUT_DELAY;
+
+ default: /* should never occur */
+ return error_recovery(bt,
+ status,
+ IPMI_ERR_UNSPECIFIED);
+ }
+ return SI_SM_CALL_WITH_DELAY;
}
static int bt_detect(struct si_sm_data *bt)
@@ -497,7 +642,7 @@ static int bt_detect(struct si_sm_data *bt)
test that first. The calling routine uses negative logic. */
if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF))
- return 1;
+ return 1;
reset_flags(bt);
return 0;
}
@@ -513,11 +658,11 @@ static int bt_size(void)
struct si_sm_handlers bt_smi_handlers =
{
- .init_data = bt_init_data,
- .start_transaction = bt_start_transaction,
- .get_result = bt_get_result,
- .event = bt_event,
- .detect = bt_detect,
- .cleanup = bt_cleanup,
- .size = bt_size,
+ .init_data = bt_init_data,
+ .start_transaction = bt_start_transaction,
+ .get_result = bt_get_result,
+ .event = bt_event,
+ .detect = bt_detect,
+ .cleanup = bt_cleanup,
+ .size = bt_size,
};
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 81fcf0ce21d..375d3378eec 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -596,6 +596,31 @@ static int ipmi_ioctl(struct inode *inode,
rv = 0;
break;
}
+
+ case IPMICTL_GET_MAINTENANCE_MODE_CMD:
+ {
+ int mode;
+
+ mode = ipmi_get_maintenance_mode(priv->user);
+ if (copy_to_user(arg, &mode, sizeof(mode))) {
+ rv = -EFAULT;
+ break;
+ }
+ rv = 0;
+ break;
+ }
+
+ case IPMICTL_SET_MAINTENANCE_MODE_CMD:
+ {
+ int mode;
+
+ if (copy_from_user(&mode, arg, sizeof(mode))) {
+ rv = -EFAULT;
+ break;
+ }
+ rv = ipmi_set_maintenance_mode(priv->user, mode);
+ break;
+ }
}
return rv;
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c
index 2062675f9e9..c1b8228cb7b 100644
--- a/drivers/char/ipmi/ipmi_kcs_sm.c
+++ b/drivers/char/ipmi/ipmi_kcs_sm.c
@@ -93,8 +93,8 @@ enum kcs_states {
state machine. */
};
-#define MAX_KCS_READ_SIZE 80
-#define MAX_KCS_WRITE_SIZE 80
+#define MAX_KCS_READ_SIZE IPMI_MAX_MSG_LENGTH
+#define MAX_KCS_WRITE_SIZE IPMI_MAX_MSG_LENGTH
/* Timeouts in microseconds. */
#define IBF_RETRY_TIMEOUT 1000000
@@ -261,12 +261,14 @@ static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data,
{
unsigned int i;
- if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) {
- return -1;
- }
- if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) {
- return -2;
- }
+ if (size < 2)
+ return IPMI_REQ_LEN_INVALID_ERR;
+ if (size > MAX_KCS_WRITE_SIZE)
+ return IPMI_REQ_LEN_EXCEEDED_ERR;
+
+ if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED))
+ return IPMI_NOT_IN_MY_STATE_ERR;
+
if (kcs_debug & KCS_DEBUG_MSG) {
printk(KERN_DEBUG "start_kcs_transaction -");
for (i = 0; i < size; i ++) {
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index c47add8e47d..5703ee28e1c 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -48,7 +48,7 @@
#define PFX "IPMI message handler: "
-#define IPMI_DRIVER_VERSION "39.0"
+#define IPMI_DRIVER_VERSION "39.1"
static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
static int ipmi_init_msghandler(void);
@@ -59,6 +59,9 @@ static int initialized = 0;
static struct proc_dir_entry *proc_ipmi_root = NULL;
#endif /* CONFIG_PROC_FS */
+/* Remain in auto-maintenance mode for this amount of time (in ms). */
+#define IPMI_MAINTENANCE_MODE_TIMEOUT 30000
+
#define MAX_EVENTS_IN_QUEUE 25
/* Don't let a message sit in a queue forever, always time it with at lest
@@ -193,17 +196,28 @@ struct ipmi_smi
struct kref refcount;
+ /* Used for a list of interfaces. */
+ struct list_head link;
+
/* The list of upper layers that are using me. seq_lock
* protects this. */
struct list_head users;
+ /* Information to supply to users. */
+ unsigned char ipmi_version_major;
+ unsigned char ipmi_version_minor;
+
/* Used for wake ups at startup. */
wait_queue_head_t waitq;
struct bmc_device *bmc;
char *my_dev_name;
+ char *sysfs_name;
- /* This is the lower-layer's sender routine. */
+ /* This is the lower-layer's sender routine. Note that you
+ * must either be holding the ipmi_interfaces_mutex or be in
+ * an umpreemptible region to use this. You must fetch the
+ * value into a local variable and make sure it is not NULL. */
struct ipmi_smi_handlers *handlers;
void *send_info;
@@ -242,6 +256,7 @@ struct ipmi_smi
spinlock_t events_lock; /* For dealing with event stuff. */
struct list_head waiting_events;
unsigned int waiting_events_count; /* How many events in queue? */
+ int delivering_events;
/* The event receiver for my BMC, only really used at panic
shutdown as a place to store this. */
@@ -250,6 +265,12 @@ struct ipmi_smi
unsigned char local_sel_device;
unsigned char local_event_generator;
+ /* For handling of maintenance mode. */
+ int maintenance_mode;
+ int maintenance_mode_enable;
+ int auto_maintenance_timeout;
+ spinlock_t maintenance_mode_lock; /* Used in a timer... */
+
/* A cheap hack, if this is non-null and a message to an
interface comes in with a NULL user, call this routine with
it. Note that the message will still be freed by the
@@ -338,13 +359,6 @@ struct ipmi_smi
};
#define to_si_intf_from_dev(device) container_of(device, struct ipmi_smi, dev)
-/* Used to mark an interface entry that cannot be used but is not a
- * free entry, either, primarily used at creation and deletion time so
- * a slot doesn't get reused too quickly. */
-#define IPMI_INVALID_INTERFACE_ENTRY ((ipmi_smi_t) ((long) 1))
-#define IPMI_INVALID_INTERFACE(i) (((i) == NULL) \
- || (i == IPMI_INVALID_INTERFACE_ENTRY))
-
/**
* The driver model view of the IPMI messaging driver.
*/
@@ -354,16 +368,13 @@ static struct device_driver ipmidriver = {
};
static DEFINE_MUTEX(ipmidriver_mutex);
-#define MAX_IPMI_INTERFACES 4
-static ipmi_smi_t ipmi_interfaces[MAX_IPMI_INTERFACES];
-
-/* Directly protects the ipmi_interfaces data structure. */
-static DEFINE_SPINLOCK(interfaces_lock);
+static struct list_head ipmi_interfaces = LIST_HEAD_INIT(ipmi_interfaces);
+static DEFINE_MUTEX(ipmi_interfaces_mutex);
/* List of watchers that want to know when smi's are added and
deleted. */
static struct list_head smi_watchers = LIST_HEAD_INIT(smi_watchers);
-static DECLARE_RWSEM(smi_watchers_sem);
+static DEFINE_MUTEX(smi_watchers_mutex);
static void free_recv_msg_list(struct list_head *q)
@@ -423,48 +434,84 @@ static void intf_free(struct kref *ref)
kfree(intf);
}
+struct watcher_entry {
+ int intf_num;
+ ipmi_smi_t intf;
+ struct list_head link;
+};
+
int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher)
{
- int i;
- unsigned long flags;
+ ipmi_smi_t intf;
+ struct list_head to_deliver = LIST_HEAD_INIT(to_deliver);
+ struct watcher_entry *e, *e2;
+
+ mutex_lock(&smi_watchers_mutex);
+
+ mutex_lock(&ipmi_interfaces_mutex);
- down_write(&smi_watchers_sem);
- list_add(&(watcher->link), &smi_watchers);
- up_write(&smi_watchers_sem);
- spin_lock_irqsave(&interfaces_lock, flags);
- for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
- ipmi_smi_t intf = ipmi_interfaces[i];
- if (IPMI_INVALID_INTERFACE(intf))
+ /* Build a list of things to deliver. */
+ list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
+ if (intf->intf_num == -1)
continue;
- spin_unlock_irqrestore(&interfaces_lock, flags);
- watcher->new_smi(i, intf->si_dev);
- spin_lock_irqsave(&interfaces_lock, flags);
+ e = kmalloc(sizeof(*e), GFP_KERNEL);
+ if (!e)
+ goto out_err;
+ kref_get(&intf->refcount);
+ e->intf = intf;
+ e->intf_num = intf->intf_num;
+ list_add_tail(&e->link, &to_deliver);
}
- spin_unlock_irqrestore(&interfaces_lock, flags);
+
+ /* We will succeed, so add it to the list. */
+ list_add(&watcher->link, &smi_watchers);
+
+ mutex_unlock(&ipmi_interfaces_mutex);
+
+ list_for_each_entry_safe(e, e2, &to_deliver, link) {
+ list_del(&e->link);
+ watcher->new_smi(e->intf_num, e->intf->si_dev);
+ kref_put(&e->intf->refcount, intf_free);
+ kfree(e);
+ }
+
+ mutex_unlock(&smi_watchers_mutex);
+
return 0;
+
+ out_err:
+ mutex_unlock(&ipmi_interfaces_mutex);
+ mutex_unlock(&smi_watchers_mutex);
+ list_for_each_entry_safe(e, e2, &to_deliver, link) {
+ list_del(&e->link);
+ kref_put(&e->intf->refcount, intf_free);
+ kfree(e);
+ }
+ return -ENOMEM;
}
int ipmi_smi_watcher_unregister(struct ipmi_smi_watcher *watcher)
{
- down_write(&smi_watchers_sem);
+ mutex_lock(&smi_watchers_mutex);
list_del(&(watcher->link));
- up_write(&smi_watchers_sem);
+ mutex_unlock(&smi_watchers_mutex);
return 0;
}
+/*
+ * Must be called with smi_watchers_mutex held.
+ */
static void
call_smi_watchers(int i, struct device *dev)
{
struct ipmi_smi_watcher *w;
- down_read(&smi_watchers_sem);
list_for_each_entry(w, &smi_watchers, link) {
if (try_module_get(w->owner)) {
w->new_smi(i, dev);
module_put(w->owner);
}
}
- up_read(&smi_watchers_sem);
}
static int
@@ -590,6 +637,17 @@ static void deliver_response(struct ipmi_recv_msg *msg)
}
}
+static void
+deliver_err_response(struct ipmi_recv_msg *msg, int err)
+{
+ msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
+ msg->msg_data[0] = err;
+ msg->msg.netfn |= 1; /* Convert to a response. */
+ msg->msg.data_len = 1;
+ msg->msg.data = msg->msg_data;
+ deliver_response(msg);
+}
+
/* Find the next sequence number not being used and add the given
message with the given timeout to the sequence table. This must be
called with the interface's seq_lock held. */
@@ -727,14 +785,8 @@ static int intf_err_seq(ipmi_smi_t intf,
}
spin_unlock_irqrestore(&(intf->seq_lock), flags);
- if (msg) {
- msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
- msg->msg_data[0] = err;
- msg->msg.netfn |= 1; /* Convert to a response. */
- msg->msg.data_len = 1;
- msg->msg.data = msg->msg_data;
- deliver_response(msg);
- }
+ if (msg)
+ deliver_err_response(msg, err);
return rv;
}
@@ -776,17 +828,18 @@ int ipmi_create_user(unsigned int if_num,
if (!new_user)
return -ENOMEM;
- spin_lock_irqsave(&interfaces_lock, flags);
- intf = ipmi_interfaces[if_num];
- if ((if_num >= MAX_IPMI_INTERFACES) || IPMI_INVALID_INTERFACE(intf)) {
- spin_unlock_irqrestore(&interfaces_lock, flags);
- rv = -EINVAL;
- goto out_kfree;
+ mutex_lock(&ipmi_interfaces_mutex);
+ list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
+ if (intf->intf_num == if_num)
+ goto found;
}
+ /* Not found, return an error */
+ rv = -EINVAL;
+ goto out_kfree;
+ found:
/* Note that each existing user holds a refcount to the interface. */
kref_get(&intf->refcount);
- spin_unlock_irqrestore(&interfaces_lock, flags);
kref_init(&new_user->refcount);
new_user->handler = handler;
@@ -807,6 +860,10 @@ int ipmi_create_user(unsigned int if_num,
}
}
+ /* Hold the lock so intf->handlers is guaranteed to be good
+ * until now */
+ mutex_unlock(&ipmi_interfaces_mutex);
+
new_user->valid = 1;
spin_lock_irqsave(&intf->seq_lock, flags);
list_add_rcu(&new_user->link, &intf->users);
@@ -817,6 +874,7 @@ int ipmi_create_user(unsigned int if_num,
out_kref:
kref_put(&intf->refcount, intf_free);
out_kfree:
+ mutex_unlock(&ipmi_interfaces_mutex);
kfree(new_user);
return rv;
}
@@ -846,6 +904,7 @@ int ipmi_destroy_user(ipmi_user_t user)
&& (intf->seq_table[i].recv_msg->user == user))
{
intf->seq_table[i].inuse = 0;
+ ipmi_free_recv_msg(intf->seq_table[i].recv_msg);
}
}
spin_unlock_irqrestore(&intf->seq_lock, flags);
@@ -872,9 +931,13 @@ int ipmi_destroy_user(ipmi_user_t user)
kfree(rcvr);
}
- module_put(intf->handlers->owner);
- if (intf->handlers->dec_usecount)
- intf->handlers->dec_usecount(intf->send_info);
+ mutex_lock(&ipmi_interfaces_mutex);
+ if (intf->handlers) {
+ module_put(intf->handlers->owner);
+ if (intf->handlers->dec_usecount)
+ intf->handlers->dec_usecount(intf->send_info);
+ }
+ mutex_unlock(&ipmi_interfaces_mutex);
kref_put(&intf->refcount, intf_free);
@@ -887,8 +950,8 @@ void ipmi_get_version(ipmi_user_t user,
unsigned char *major,
unsigned char *minor)
{
- *major = ipmi_version_major(&user->intf->bmc->id);
- *minor = ipmi_version_minor(&user->intf->bmc->id);
+ *major = user->intf->ipmi_version_major;
+ *minor = user->intf->ipmi_version_minor;
}
int ipmi_set_my_address(ipmi_user_t user,
@@ -931,6 +994,65 @@ int ipmi_get_my_LUN(ipmi_user_t user,
return 0;
}
+int ipmi_get_maintenance_mode(ipmi_user_t user)
+{
+ int mode;
+ unsigned long flags;
+
+ spin_lock_irqsave(&user->intf->maintenance_mode_lock, flags);
+ mode = user->intf->maintenance_mode;
+ spin_unlock_irqrestore(&user->intf->maintenance_mode_lock, flags);
+
+ return mode;
+}
+EXPORT_SYMBOL(ipmi_get_maintenance_mode);
+
+static void maintenance_mode_update(ipmi_smi_t intf)
+{
+ if (intf->handlers->set_maintenance_mode)
+ intf->handlers->set_maintenance_mode(
+ intf->send_info, intf->maintenance_mode_enable);
+}
+
+int ipmi_set_maintenance_mode(ipmi_user_t user, int mode)
+{
+ int rv = 0;
+ unsigned long flags;
+ ipmi_smi_t intf = user->intf;
+
+ spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
+ if (intf->maintenance_mode != mode) {
+ switch (mode) {
+ case IPMI_MAINTENANCE_MODE_AUTO:
+ intf->maintenance_mode = mode;
+ intf->maintenance_mode_enable
+ = (intf->auto_maintenance_timeout > 0);
+ break;
+
+ case IPMI_MAINTENANCE_MODE_OFF:
+ intf->maintenance_mode = mode;
+ intf->maintenance_mode_enable = 0;
+ break;
+
+ case IPMI_MAINTENANCE_MODE_ON:
+ intf->maintenance_mode = mode;
+ intf->maintenance_mode_enable = 1;
+ break;
+
+ default:
+ rv = -EINVAL;
+ goto out_unlock;
+ }
+
+ maintenance_mode_update(intf);
+ }
+ out_unlock:
+ spin_unlock_irqrestore(&intf->maintenance_mode_lock, flags);
+
+ return rv;
+}
+EXPORT_SYMBOL(ipmi_set_maintenance_mode);
+
int ipmi_set_gets_events(ipmi_user_t user, int val)
{
unsigned long flags;
@@ -943,20 +1065,33 @@ int ipmi_set_gets_events(ipmi_user_t user, int val)
spin_lock_irqsave(&intf->events_lock, flags);
user->gets_events = val;
- if (val) {
- /* Deliver any queued events. */
+ if (intf->delivering_events)
+ /*
+ * Another thread is delivering events for this, so
+ * let it handle any new events.
+ */
+ goto out;
+
+ /* Deliver any queued events. */
+ while (user->gets_events && !list_empty(&intf->waiting_events)) {
list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link)
list_move_tail(&msg->link, &msgs);
intf->waiting_events_count = 0;
- }
- /* Hold the events lock while doing this to preserve order. */
- list_for_each_entry_safe(msg, msg2, &msgs, link) {
- msg->user = user;
- kref_get(&user->refcount);
- deliver_response(msg);
+ intf->delivering_events = 1;
+ spin_unlock_irqrestore(&intf->events_lock, flags);
+
+ list_for_each_entry_safe(msg, msg2, &msgs, link) {
+ msg->user = user;
+ kref_get(&user->refcount);
+ deliver_response(msg);
+ }
+
+ spin_lock_irqsave(&intf->events_lock, flags);
+ intf->delivering_events = 0;
}
+ out:
spin_unlock_irqrestore(&intf->events_lock, flags);
return 0;
@@ -1067,7 +1202,8 @@ int ipmi_unregister_for_cmd(ipmi_user_t user,
void ipmi_user_set_run_to_completion(ipmi_user_t user, int val)
{
ipmi_smi_t intf = user->intf;
- intf->handlers->set_run_to_completion(intf->send_info, val);
+ if (intf->handlers)
+ intf->handlers->set_run_to_completion(intf->send_info, val);
}
static unsigned char
@@ -1178,10 +1314,11 @@ static int i_ipmi_request(ipmi_user_t user,
int retries,
unsigned int retry_time_ms)
{
- int rv = 0;
- struct ipmi_smi_msg *smi_msg;
- struct ipmi_recv_msg *recv_msg;
- unsigned long flags;
+ int rv = 0;
+ struct ipmi_smi_msg *smi_msg;
+ struct ipmi_recv_msg *recv_msg;
+ unsigned long flags;
+ struct ipmi_smi_handlers *handlers;
if (supplied_recv) {
@@ -1204,6 +1341,13 @@ static int i_ipmi_request(ipmi_user_t user,
}
}
+ rcu_read_lock();
+ handlers = intf->handlers;
+ if (!handlers) {
+ rv = -ENODEV;
+ goto out_err;
+ }
+
recv_msg->user = user;
if (user)
kref_get(&user->refcount);
@@ -1246,6 +1390,24 @@ static int i_ipmi_request(ipmi_user_t user,
goto out_err;
}
+ if (((msg->netfn == IPMI_NETFN_APP_REQUEST)
+ && ((msg->cmd == IPMI_COLD_RESET_CMD)
+ || (msg->cmd == IPMI_WARM_RESET_CMD)))
+ || (msg->netfn == IPMI_NETFN_FIRMWARE_REQUEST))
+ {
+ spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
+ intf->auto_maintenance_timeout
+ = IPMI_MAINTENANCE_MODE_TIMEOUT;
+ if (!intf->maintenance_mode
+ && !intf->maintenance_mode_enable)
+ {
+ intf->maintenance_mode_enable = 1;
+ maintenance_mode_update(intf);
+ }
+ spin_unlock_irqrestore(&intf->maintenance_mode_lock,
+ flags);
+ }
+
if ((msg->data_len + 2) > IPMI_MAX_MSG_LENGTH) {
spin_lock_irqsave(&intf->counter_lock, flags);
intf->sent_invalid_commands++;
@@ -1520,11 +1682,14 @@ static int i_ipmi_request(ipmi_user_t user,
printk("\n");
}
#endif
- intf->handlers->sender(intf->send_info, smi_msg, priority);
+
+ handlers->sender(intf->send_info, smi_msg, priority);
+ rcu_read_unlock();
return 0;
out_err:
+ rcu_read_unlock();
ipmi_free_smi_msg(smi_msg);
ipmi_free_recv_msg(recv_msg);
return rv;
@@ -1604,6 +1769,7 @@ int ipmi_request_supply_msgs(ipmi_user_t user,
-1, 0);
}
+#ifdef CONFIG_PROC_FS
static int ipmb_file_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -1692,6 +1858,7 @@ static int stat_file_read_proc(char *page, char **start, off_t off,
return (out - ((char *) page));
}
+#endif /* CONFIG_PROC_FS */
int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
read_proc_t *read_proc, write_proc_t *write_proc,
@@ -1817,13 +1984,12 @@ static int __find_bmc_prod_dev_id(struct device *dev, void *data)
struct bmc_device *bmc = dev_get_drvdata(dev);
return (bmc->id.product_id == id->product_id
- && bmc->id.product_id == id->product_id
&& bmc->id.device_id == id->device_id);
}
static struct bmc_device *ipmi_find_bmc_prod_dev_id(
struct device_driver *drv,
- unsigned char product_id, unsigned char device_id)
+ unsigned int product_id, unsigned char device_id)
{
struct prod_dev_id id = {
.product_id = product_id,
@@ -1940,6 +2106,9 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr,
static void remove_files(struct bmc_device *bmc)
{
+ if (!bmc->dev)
+ return;
+
device_remove_file(&bmc->dev->dev,
&bmc->device_id_attr);
device_remove_file(&bmc->dev->dev,
@@ -1973,7 +2142,8 @@ cleanup_bmc_device(struct kref *ref)
bmc = container_of(ref, struct bmc_device, refcount);
remove_files(bmc);
- platform_device_unregister(bmc->dev);
+ if (bmc->dev)
+ platform_device_unregister(bmc->dev);
kfree(bmc);
}
@@ -1981,7 +2151,11 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf)
{
struct bmc_device *bmc = intf->bmc;
- sysfs_remove_link(&intf->si_dev->kobj, "bmc");
+ if (intf->sysfs_name) {
+ sysfs_remove_link(&intf->si_dev->kobj, intf->sysfs_name);
+ kfree(intf->sysfs_name);
+ intf->sysfs_name = NULL;
+ }
if (intf->my_dev_name) {
sysfs_remove_link(&bmc->dev->dev.kobj, intf->my_dev_name);
kfree(intf->my_dev_name);
@@ -1990,6 +2164,7 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf)
mutex_lock(&ipmidriver_mutex);
kref_put(&bmc->refcount, cleanup_bmc_device);
+ intf->bmc = NULL;
mutex_unlock(&ipmidriver_mutex);
}
@@ -1997,6 +2172,56 @@ static int create_files(struct bmc_device *bmc)
{
int err;
+ bmc->device_id_attr.attr.name = "device_id";
+ bmc->device_id_attr.attr.owner = THIS_MODULE;
+ bmc->device_id_attr.attr.mode = S_IRUGO;
+ bmc->device_id_attr.show = device_id_show;
+
+ bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs";
+ bmc->provides_dev_sdrs_attr.attr.owner = THIS_MODULE;
+ bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
+ bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
+
+ bmc->revision_attr.attr.name = "revision";
+ bmc->revision_attr.attr.owner = THIS_MODULE;
+ bmc->revision_attr.attr.mode = S_IRUGO;
+ bmc->revision_attr.show = revision_show;
+
+ bmc->firmware_rev_attr.attr.name = "firmware_revision";
+ bmc->firmware_rev_attr.attr.owner = THIS_MODULE;
+ bmc->firmware_rev_attr.attr.mode = S_IRUGO;
+ bmc->firmware_rev_attr.show = firmware_rev_show;
+
+ bmc->version_attr.attr.name = "ipmi_version";
+ bmc->version_attr.attr.owner = THIS_MODULE;
+ bmc->version_attr.attr.mode = S_IRUGO;
+ bmc->version_attr.show = ipmi_version_show;
+
+ bmc->add_dev_support_attr.attr.name = "additional_device_support";
+ bmc->add_dev_support_attr.attr.owner = THIS_MODULE;
+ bmc->add_dev_support_attr.attr.mode = S_IRUGO;
+ bmc->add_dev_support_attr.show = add_dev_support_show;
+
+ bmc->manufacturer_id_attr.attr.name = "manufacturer_id";
+ bmc->manufacturer_id_attr.attr.owner = THIS_MODULE;
+ bmc->manufacturer_id_attr.attr.mode = S_IRUGO;
+ bmc->manufacturer_id_attr.show = manufacturer_id_show;
+
+ bmc->product_id_attr.attr.name = "product_id";
+ bmc->product_id_attr.attr.owner = THIS_MODULE;
+ bmc->product_id_attr.attr.mode = S_IRUGO;
+ bmc->product_id_attr.show = product_id_show;
+
+ bmc->guid_attr.attr.name = "guid";
+ bmc->guid_attr.attr.owner = THIS_MODULE;
+ bmc->guid_attr.attr.mode = S_IRUGO;
+ bmc->guid_attr.show = guid_show;
+
+ bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
+ bmc->aux_firmware_rev_attr.attr.owner = THIS_MODULE;
+ bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
+ bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
+
err = device_create_file(&bmc->dev->dev,
&bmc->device_id_attr);
if (err) goto out;
@@ -2066,7 +2291,8 @@ out:
return err;
}
-static int ipmi_bmc_register(ipmi_smi_t intf)
+static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
+ const char *sysfs_name)
{
int rv;
struct bmc_device *bmc = intf->bmc;
@@ -2106,9 +2332,39 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
bmc->id.product_id,
bmc->id.device_id);
} else {
- bmc->dev = platform_device_alloc("ipmi_bmc",
- bmc->id.device_id);
+ char name[14];
+ unsigned char orig_dev_id = bmc->id.device_id;
+ int warn_printed = 0;
+
+ snprintf(name, sizeof(name),
+ "ipmi_bmc.%4.4x", bmc->id.product_id);
+
+ while (ipmi_find_bmc_prod_dev_id(&ipmidriver,
+ bmc->id.product_id,
+ bmc->id.device_id))
+ {
+ if (!warn_printed) {
+ printk(KERN_WARNING PFX
+ "This machine has two different BMCs"
+ " with the same product id and device"
+ " id. This is an error in the"
+ " firmware, but incrementing the"
+ " device id to work around the problem."
+ " Prod ID = 0x%x, Dev ID = 0x%x\n",
+ bmc->id.product_id, bmc->id.device_id);
+ warn_printed = 1;
+ }
+ bmc->id.device_id++; /* Wraps at 255 */
+ if (bmc->id.device_id == orig_dev_id) {
+ printk(KERN_ERR PFX
+ "Out of device ids!\n");
+ break;
+ }
+ }
+
+ bmc->dev = platform_device_alloc(name, bmc->id.device_id);
if (!bmc->dev) {
+ mutex_unlock(&ipmidriver_mutex);
printk(KERN_ERR
"ipmi_msghandler:"
" Unable to allocate platform device\n");
@@ -2121,6 +2377,8 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
rv = platform_device_add(bmc->dev);
mutex_unlock(&ipmidriver_mutex);
if (rv) {
+ platform_device_put(bmc->dev);
+ bmc->dev = NULL;
printk(KERN_ERR
"ipmi_msghandler:"
" Unable to register bmc device: %d\n",
@@ -2130,57 +2388,6 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
return rv;
}
- bmc->device_id_attr.attr.name = "device_id";
- bmc->device_id_attr.attr.owner = THIS_MODULE;
- bmc->device_id_attr.attr.mode = S_IRUGO;
- bmc->device_id_attr.show = device_id_show;
-
- bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs";
- bmc->provides_dev_sdrs_attr.attr.owner = THIS_MODULE;
- bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
- bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
-
- bmc->revision_attr.attr.name = "revision";
- bmc->revision_attr.attr.owner = THIS_MODULE;
- bmc->revision_attr.attr.mode = S_IRUGO;
- bmc->revision_attr.show = revision_show;
-
- bmc->firmware_rev_attr.attr.name = "firmware_revision";
- bmc->firmware_rev_attr.attr.owner = THIS_MODULE;
- bmc->firmware_rev_attr.attr.mode = S_IRUGO;
- bmc->firmware_rev_attr.show = firmware_rev_show;
-
- bmc->version_attr.attr.name = "ipmi_version";
- bmc->version_attr.attr.owner = THIS_MODULE;
- bmc->version_attr.attr.mode = S_IRUGO;
- bmc->version_attr.show = ipmi_version_show;
-
- bmc->add_dev_support_attr.attr.name
- = "additional_device_support";
- bmc->add_dev_support_attr.attr.owner = THIS_MODULE;
- bmc->add_dev_support_attr.attr.mode = S_IRUGO;
- bmc->add_dev_support_attr.show = add_dev_support_show;
-
- bmc->manufacturer_id_attr.attr.name = "manufacturer_id";
- bmc->manufacturer_id_attr.attr.owner = THIS_MODULE;
- bmc->manufacturer_id_attr.attr.mode = S_IRUGO;
- bmc->manufacturer_id_attr.show = manufacturer_id_show;
-
- bmc->product_id_attr.attr.name = "product_id";
- bmc->product_id_attr.attr.owner = THIS_MODULE;
- bmc->product_id_attr.attr.mode = S_IRUGO;
- bmc->product_id_attr.show = product_id_show;
-
- bmc->guid_attr.attr.name = "guid";
- bmc->guid_attr.attr.owner = THIS_MODULE;
- bmc->guid_attr.attr.mode = S_IRUGO;
- bmc->guid_attr.show = guid_show;
-
- bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
- bmc->aux_firmware_rev_attr.attr.owner = THIS_MODULE;
- bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
- bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
-
rv = create_files(bmc);
if (rv) {
mutex_lock(&ipmidriver_mutex);
@@ -2202,29 +2409,44 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
* create symlink from system interface device to bmc device
* and back.
*/
+ intf->sysfs_name = kstrdup(sysfs_name, GFP_KERNEL);
+ if (!intf->sysfs_name) {
+ rv = -ENOMEM;
+ printk(KERN_ERR
+ "ipmi_msghandler: allocate link to BMC: %d\n",
+ rv);
+ goto out_err;
+ }
+
rv = sysfs_create_link(&intf->si_dev->kobj,
- &bmc->dev->dev.kobj, "bmc");
+ &bmc->dev->dev.kobj, intf->sysfs_name);
if (rv) {
+ kfree(intf->sysfs_name);
+ intf->sysfs_name = NULL;
printk(KERN_ERR
"ipmi_msghandler: Unable to create bmc symlink: %d\n",
rv);
goto out_err;
}
- size = snprintf(dummy, 0, "ipmi%d", intf->intf_num);
+ size = snprintf(dummy, 0, "ipmi%d", ifnum);
intf->my_dev_name = kmalloc(size+1, GFP_KERNEL);
if (!intf->my_dev_name) {
+ kfree(intf->sysfs_name);
+ intf->sysfs_name = NULL;
rv = -ENOMEM;
printk(KERN_ERR
"ipmi_msghandler: allocate link from BMC: %d\n",
rv);
goto out_err;
}
- snprintf(intf->my_dev_name, size+1, "ipmi%d", intf->intf_num);
+ snprintf(intf->my_dev_name, size+1, "ipmi%d", ifnum);
rv = sysfs_create_link(&bmc->dev->dev.kobj, &intf->si_dev->kobj,
intf->my_dev_name);
if (rv) {
+ kfree(intf->sysfs_name);
+ intf->sysfs_name = NULL;
kfree(intf->my_dev_name);
intf->my_dev_name = NULL;
printk(KERN_ERR
@@ -2409,17 +2631,14 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
void *send_info,
struct ipmi_device_id *device_id,
struct device *si_dev,
+ const char *sysfs_name,
unsigned char slave_addr)
{
int i, j;
int rv;
ipmi_smi_t intf;
- unsigned long flags;
- int version_major;
- int version_minor;
-
- version_major = ipmi_version_major(device_id);
- version_minor = ipmi_version_minor(device_id);
+ ipmi_smi_t tintf;
+ struct list_head *link;
/* Make sure the driver is actually initialized, this handles
problems with initialization order. */
@@ -2437,12 +2656,16 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
if (!intf)
return -ENOMEM;
memset(intf, 0, sizeof(*intf));
+
+ intf->ipmi_version_major = ipmi_version_major(device_id);
+ intf->ipmi_version_minor = ipmi_version_minor(device_id);
+
intf->bmc = kzalloc(sizeof(*intf->bmc), GFP_KERNEL);
if (!intf->bmc) {
kfree(intf);
return -ENOMEM;
}
- intf->intf_num = -1;
+ intf->intf_num = -1; /* Mark it invalid for now. */
kref_init(&intf->refcount);
intf->bmc->id = *device_id;
intf->si_dev = si_dev;
@@ -2470,26 +2693,30 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
INIT_LIST_HEAD(&intf->waiting_events);
intf->waiting_events_count = 0;
mutex_init(&intf->cmd_rcvrs_mutex);
+ spin_lock_init(&intf->maintenance_mode_lock);
INIT_LIST_HEAD(&intf->cmd_rcvrs);
init_waitqueue_head(&intf->waitq);
spin_lock_init(&intf->counter_lock);
intf->proc_dir = NULL;
- rv = -ENOMEM;
- spin_lock_irqsave(&interfaces_lock, flags);
- for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
- if (ipmi_interfaces[i] == NULL) {
- intf->intf_num = i;
- /* Reserve the entry till we are done. */
- ipmi_interfaces[i] = IPMI_INVALID_INTERFACE_ENTRY;
- rv = 0;
+ mutex_lock(&smi_watchers_mutex);
+ mutex_lock(&ipmi_interfaces_mutex);
+ /* Look for a hole in the numbers. */
+ i = 0;
+ link = &ipmi_interfaces;
+ list_for_each_entry_rcu(tintf, &ipmi_interfaces, link) {
+ if (tintf->intf_num != i) {
+ link = &tintf->link;
break;
}
+ i++;
}
- spin_unlock_irqrestore(&interfaces_lock, flags);
- if (rv)
- goto out;
+ /* Add the new interface in numeric order. */
+ if (i == 0)
+ list_add_rcu(&intf->link, &ipmi_interfaces);
+ else
+ list_add_tail_rcu(&intf->link, link);
rv = handlers->start_processing(send_info, intf);
if (rv)
@@ -2497,8 +2724,9 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
get_guid(intf);
- if ((version_major > 1)
- || ((version_major == 1) && (version_minor >= 5)))
+ if ((intf->ipmi_version_major > 1)
+ || ((intf->ipmi_version_major == 1)
+ && (intf->ipmi_version_minor >= 5)))
{
/* Start scanning the channels to see what is
available. */
@@ -2521,64 +2749,67 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
if (rv == 0)
rv = add_proc_entries(intf, i);
- rv = ipmi_bmc_register(intf);
+ rv = ipmi_bmc_register(intf, i, sysfs_name);
out:
if (rv) {
if (intf->proc_dir)
remove_proc_entries(intf);
+ intf->handlers = NULL;
+ list_del_rcu(&intf->link);
+ mutex_unlock(&ipmi_interfaces_mutex);
+ mutex_unlock(&smi_watchers_mutex);
+ synchronize_rcu();
kref_put(&intf->refcount, intf_free);
- if (i < MAX_IPMI_INTERFACES) {
- spin_lock_irqsave(&interfaces_lock, flags);
- ipmi_interfaces[i] = NULL;
- spin_unlock_irqrestore(&interfaces_lock, flags);
- }
} else {
- spin_lock_irqsave(&interfaces_lock, flags);
- ipmi_interfaces[i] = intf;
- spin_unlock_irqrestore(&interfaces_lock, flags);
+ /* After this point the interface is legal to use. */
+ intf->intf_num = i;
+ mutex_unlock(&ipmi_interfaces_mutex);
call_smi_watchers(i, intf->si_dev);
+ mutex_unlock(&smi_watchers_mutex);
}
return rv;
}
+static void cleanup_smi_msgs(ipmi_smi_t intf)
+{
+ int i;
+ struct seq_table *ent;
+
+ /* No need for locks, the interface is down. */
+ for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
+ ent = &(intf->seq_table[i]);
+ if (!ent->inuse)
+ continue;
+ deliver_err_response(ent->recv_msg, IPMI_ERR_UNSPECIFIED);
+ }
+}
+
int ipmi_unregister_smi(ipmi_smi_t intf)
{
- int i;
struct ipmi_smi_watcher *w;
- unsigned long flags;
+ int intf_num = intf->intf_num;
ipmi_bmc_unregister(intf);
- spin_lock_irqsave(&interfaces_lock, flags);
- for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
- if (ipmi_interfaces[i] == intf) {
- /* Set the interface number reserved until we
- * are done. */
- ipmi_interfaces[i] = IPMI_INVALID_INTERFACE_ENTRY;
- intf->intf_num = -1;
- break;
- }
- }
- spin_unlock_irqrestore(&interfaces_lock,flags);
+ mutex_lock(&smi_watchers_mutex);
+ mutex_lock(&ipmi_interfaces_mutex);
+ intf->intf_num = -1;
+ intf->handlers = NULL;
+ list_del_rcu(&intf->link);
+ mutex_unlock(&ipmi_interfaces_mutex);
+ synchronize_rcu();
- if (i == MAX_IPMI_INTERFACES)
- return -ENODEV;
+ cleanup_smi_msgs(intf);
remove_proc_entries(intf);
/* Call all the watcher interfaces to tell them that
an interface is gone. */
- down_read(&smi_watchers_sem);
list_for_each_entry(w, &smi_watchers, link)
- w->smi_gone(i);
- up_read(&smi_watchers_sem);
-
- /* Allow the entry to be reused now. */
- spin_lock_irqsave(&interfaces_lock, flags);
- ipmi_interfaces[i] = NULL;
- spin_unlock_irqrestore(&interfaces_lock,flags);
+ w->smi_gone(intf_num);
+ mutex_unlock(&smi_watchers_mutex);
kref_put(&intf->refcount, intf_free);
return 0;
@@ -2660,6 +2891,7 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf,
struct ipmi_ipmb_addr *ipmb_addr;
struct ipmi_recv_msg *recv_msg;
unsigned long flags;
+ struct ipmi_smi_handlers *handlers;
if (msg->rsp_size < 10) {
/* Message not big enough, just ignore it. */
@@ -2716,10 +2948,16 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf,
printk("\n");
}
#endif
- intf->handlers->sender(intf->send_info, msg, 0);
-
- rv = -1; /* We used the message, so return the value that
- causes it to not be freed or queued. */
+ rcu_read_lock();
+ handlers = intf->handlers;
+ if (handlers) {
+ handlers->sender(intf->send_info, msg, 0);
+ /* We used the message, so return the value
+ that causes it to not be freed or
+ queued. */
+ rv = -1;
+ }
+ rcu_read_unlock();
} else {
/* Deliver the message to the user. */
spin_lock_irqsave(&intf->counter_lock, flags);
@@ -3309,16 +3547,6 @@ void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf)
rcu_read_unlock();
}
-static void
-handle_msg_timeout(struct ipmi_recv_msg *msg)
-{
- msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
- msg->msg_data[0] = IPMI_TIMEOUT_COMPLETION_CODE;
- msg->msg.netfn |= 1; /* Convert to a response. */
- msg->msg.data_len = 1;
- msg->msg.data = msg->msg_data;
- deliver_response(msg);
-}
static struct ipmi_smi_msg *
smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg,
@@ -3350,7 +3578,11 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
struct list_head *timeouts, long timeout_period,
int slot, unsigned long *flags)
{
- struct ipmi_recv_msg *msg;
+ struct ipmi_recv_msg *msg;
+ struct ipmi_smi_handlers *handlers;
+
+ if (intf->intf_num == -1)
+ return;
if (!ent->inuse)
return;
@@ -3393,13 +3625,19 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
return;
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);
+ handlers = intf->handlers;
+ if (handlers)
+ intf->handlers->sender(intf->send_info,
+ smi_msg, 0);
+ else
+ ipmi_free_smi_msg(smi_msg);
+
spin_lock_irqsave(&intf->seq_lock, *flags);
}
}
@@ -3411,18 +3649,12 @@ static void ipmi_timeout_handler(long timeout_period)
struct ipmi_recv_msg *msg, *msg2;
struct ipmi_smi_msg *smi_msg, *smi_msg2;
unsigned long flags;
- int i, j;
+ int i;
INIT_LIST_HEAD(&timeouts);
- spin_lock(&interfaces_lock);
- for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
- intf = ipmi_interfaces[i];
- if (IPMI_INVALID_INTERFACE(intf))
- continue;
- kref_get(&intf->refcount);
- spin_unlock(&interfaces_lock);
-
+ rcu_read_lock();
+ list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
/* See if any waiting messages need to be processed. */
spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
list_for_each_entry_safe(smi_msg, smi_msg2,
@@ -3442,35 +3674,60 @@ static void ipmi_timeout_handler(long timeout_period)
have timed out, putting them in the timeouts
list. */
spin_lock_irqsave(&intf->seq_lock, flags);
- for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++)
- check_msg_timeout(intf, &(intf->seq_table[j]),
- &timeouts, timeout_period, j,
+ for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++)
+ check_msg_timeout(intf, &(intf->seq_table[i]),
+ &timeouts, timeout_period, i,
&flags);
spin_unlock_irqrestore(&intf->seq_lock, flags);
list_for_each_entry_safe(msg, msg2, &timeouts, link)
- handle_msg_timeout(msg);
-
- kref_put(&intf->refcount, intf_free);
- spin_lock(&interfaces_lock);
+ deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE);
+
+ /*
+ * Maintenance mode handling. Check the timeout
+ * optimistically before we claim the lock. It may
+ * mean a timeout gets missed occasionally, but that
+ * only means the timeout gets extended by one period
+ * in that case. No big deal, and it avoids the lock
+ * most of the time.
+ */
+ if (intf->auto_maintenance_timeout > 0) {
+ spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
+ if (intf->auto_maintenance_timeout > 0) {
+ intf->auto_maintenance_timeout
+ -= timeout_period;
+ if (!intf->maintenance_mode
+ && (intf->auto_maintenance_timeout <= 0))
+ {
+ intf->maintenance_mode_enable = 0;
+ maintenance_mode_update(intf);
+ }
+ }
+ spin_unlock_irqrestore(&intf->maintenance_mode_lock,
+ flags);
+ }
}
- spin_unlock(&interfaces_lock);
+ rcu_read_unlock();
}
static void ipmi_request_event(void)
{
- ipmi_smi_t intf;
- int i;
+ ipmi_smi_t intf;
+ struct ipmi_smi_handlers *handlers;
- spin_lock(&interfaces_lock);
- for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
- intf = ipmi_interfaces[i];
- if (IPMI_INVALID_INTERFACE(intf))
+ rcu_read_lock();
+ /* Called from the timer, no need to check if handlers is
+ * valid. */
+ list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
+ /* No event requests when in maintenance mode. */
+ if (intf->maintenance_mode_enable)
continue;
- intf->handlers->request_events(intf->send_info);
+ handlers = intf->handlers;
+ if (handlers)
+ handlers->request_events(intf->send_info);
}
- spin_unlock(&interfaces_lock);
+ rcu_read_unlock();
}
static struct timer_list ipmi_timer;
@@ -3599,7 +3856,6 @@ static void send_panic_events(char *str)
struct kernel_ipmi_msg msg;
ipmi_smi_t intf;
unsigned char data[16];
- int i;
struct ipmi_system_interface_addr *si;
struct ipmi_addr addr;
struct ipmi_smi_msg smi_msg;
@@ -3633,9 +3889,9 @@ static void send_panic_events(char *str)
recv_msg.done = dummy_recv_done_handler;
/* For every registered interface, send the event. */
- for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
- intf = ipmi_interfaces[i];
- if (IPMI_INVALID_INTERFACE(intf))
+ list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
+ if (!intf->handlers)
+ /* Interface is not ready. */
continue;
/* Send the event announcing the panic. */
@@ -3660,13 +3916,14 @@ static void send_panic_events(char *str)
if (!str)
return;
- for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
+ /* For every registered interface, send the event. */
+ list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
char *p = str;
struct ipmi_ipmb_addr *ipmb;
int j;
- intf = ipmi_interfaces[i];
- if (IPMI_INVALID_INTERFACE(intf))
+ if (intf->intf_num == -1)
+ /* Interface was not ready yet. */
continue;
/* First job here is to figure out where to send the
@@ -3792,7 +4049,6 @@ static int panic_event(struct notifier_block *this,
unsigned long event,
void *ptr)
{
- int i;
ipmi_smi_t intf;
if (has_panicked)
@@ -3800,9 +4056,9 @@ static int panic_event(struct notifier_block *this,
has_panicked = 1;
/* For every registered interface, set it to run to completion. */
- for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
- intf = ipmi_interfaces[i];
- if (IPMI_INVALID_INTERFACE(intf))
+ list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
+ if (!intf->handlers)
+ /* Interface is not ready. */
continue;
intf->handlers->set_run_to_completion(intf->send_info, 1);
@@ -3823,7 +4079,6 @@ static struct notifier_block panic_block = {
static int ipmi_init_msghandler(void)
{
- int i;
int rv;
if (initialized)
@@ -3838,9 +4093,6 @@ static int ipmi_init_msghandler(void)
printk(KERN_INFO "ipmi message handler version "
IPMI_DRIVER_VERSION "\n");
- for (i = 0; i < MAX_IPMI_INTERFACES; i++)
- ipmi_interfaces[i] = NULL;
-
#ifdef CONFIG_PROC_FS
proc_ipmi_root = proc_mkdir("ipmi", NULL);
if (!proc_ipmi_root) {
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index 8d941db8345..597eb4f88b8 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -43,6 +43,9 @@
#define PFX "IPMI poweroff: "
+static void ipmi_po_smi_gone(int if_num);
+static void ipmi_po_new_smi(int if_num, struct device *device);
+
/* Definitions for controlling power off (if the system supports it). It
* conveniently matches the IPMI chassis control values. */
#define IPMI_CHASSIS_POWER_DOWN 0 /* power down, the default. */
@@ -51,6 +54,37 @@
/* the IPMI data command */
static int poweroff_powercycle;
+/* Which interface to use, -1 means the first we see. */
+static int ifnum_to_use = -1;
+
+/* Our local state. */
+static int ready = 0;
+static ipmi_user_t ipmi_user;
+static int ipmi_ifnum;
+static void (*specific_poweroff_func)(ipmi_user_t user) = NULL;
+
+/* Holds the old poweroff function so we can restore it on removal. */
+static void (*old_poweroff_func)(void);
+
+static int set_param_ifnum(const char *val, struct kernel_param *kp)
+{
+ int rv = param_set_int(val, kp);
+ if (rv)
+ return rv;
+ if ((ifnum_to_use < 0) || (ifnum_to_use == ipmi_ifnum))
+ return 0;
+
+ ipmi_po_smi_gone(ipmi_ifnum);
+ ipmi_po_new_smi(ifnum_to_use, NULL);
+ return 0;
+}
+
+module_param_call(ifnum_to_use, set_param_ifnum, param_get_int,
+ &ifnum_to_use, 0644);
+MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog "
+ "timer. Setting to -1 defaults to the first registered "
+ "interface");
+
/* parameter definition to allow user to flag power cycle */
module_param(poweroff_powercycle, int, 0644);
MODULE_PARM_DESC(poweroff_powercycle, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
@@ -142,6 +176,42 @@ static int ipmi_request_in_rc_mode(ipmi_user_t user,
#define IPMI_ATCA_GET_ADDR_INFO_CMD 0x01
#define IPMI_PICMG_ID 0
+#define IPMI_NETFN_OEM 0x2e
+#define IPMI_ATCA_PPS_GRACEFUL_RESTART 0x11
+#define IPMI_ATCA_PPS_IANA "\x00\x40\x0A"
+#define IPMI_MOTOROLA_MANUFACTURER_ID 0x0000A1
+#define IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID 0x0051
+
+static void (*atca_oem_poweroff_hook)(ipmi_user_t user) = NULL;
+
+static void pps_poweroff_atca (ipmi_user_t user)
+{
+ struct ipmi_system_interface_addr smi_addr;
+ struct kernel_ipmi_msg send_msg;
+ int rv;
+ /*
+ * Configure IPMI address for local access
+ */
+ smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
+ smi_addr.channel = IPMI_BMC_CHANNEL;
+ smi_addr.lun = 0;
+
+ printk(KERN_INFO PFX "PPS powerdown hook used");
+
+ send_msg.netfn = IPMI_NETFN_OEM;
+ send_msg.cmd = IPMI_ATCA_PPS_GRACEFUL_RESTART;
+ send_msg.data = IPMI_ATCA_PPS_IANA;
+ send_msg.data_len = 3;
+ rv = ipmi_request_in_rc_mode(user,
+ (struct ipmi_addr *) &smi_addr,
+ &send_msg);
+ if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) {
+ printk(KERN_ERR PFX "Unable to send ATCA ,"
+ " IPMI error 0x%x\n", rv);
+ }
+ return;
+}
+
static int ipmi_atca_detect (ipmi_user_t user)
{
struct ipmi_system_interface_addr smi_addr;
@@ -167,6 +237,13 @@ static int ipmi_atca_detect (ipmi_user_t user)
rv = ipmi_request_wait_for_response(user,
(struct ipmi_addr *) &smi_addr,
&send_msg);
+
+ printk(KERN_INFO PFX "ATCA Detect mfg 0x%X prod 0x%X\n", mfg_id, prod_id);
+ if((mfg_id == IPMI_MOTOROLA_MANUFACTURER_ID)
+ && (prod_id == IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID)) {
+ printk(KERN_INFO PFX "Installing Pigeon Point Systems Poweroff Hook\n");
+ atca_oem_poweroff_hook = pps_poweroff_atca;
+ }
return !rv;
}
@@ -200,12 +277,19 @@ static void ipmi_poweroff_atca (ipmi_user_t user)
rv = ipmi_request_in_rc_mode(user,
(struct ipmi_addr *) &smi_addr,
&send_msg);
- if (rv) {
+ /** At this point, the system may be shutting down, and most
+ ** serial drivers (if used) will have interrupts turned off
+ ** it may be better to ignore IPMI_UNKNOWN_ERR_COMPLETION_CODE
+ ** return code
+ **/
+ if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) {
printk(KERN_ERR PFX "Unable to send ATCA powerdown message,"
" IPMI error 0x%x\n", rv);
goto out;
}
+ if(atca_oem_poweroff_hook)
+ return atca_oem_poweroff_hook(user);
out:
return;
}
@@ -440,15 +524,6 @@ static struct poweroff_function poweroff_functions[] = {
/ sizeof(struct poweroff_function))
-/* Our local state. */
-static int ready = 0;
-static ipmi_user_t ipmi_user;
-static void (*specific_poweroff_func)(ipmi_user_t user) = NULL;
-
-/* Holds the old poweroff function so we can restore it on removal. */
-static void (*old_poweroff_func)(void);
-
-
/* Called on a powerdown request. */
static void ipmi_poweroff_function (void)
{
@@ -473,6 +548,9 @@ static void ipmi_po_new_smi(int if_num, struct device *device)
if (ready)
return;
+ if ((ifnum_to_use >= 0) && (ifnum_to_use != if_num))
+ return;
+
rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL,
&ipmi_user);
if (rv) {
@@ -481,6 +559,8 @@ static void ipmi_po_new_smi(int if_num, struct device *device)
return;
}
+ ipmi_ifnum = if_num;
+
/*
* Do a get device ide and store some results, since this is
* used by several functions.
@@ -541,9 +621,15 @@ static void ipmi_po_new_smi(int if_num, struct device *device)
static void ipmi_po_smi_gone(int if_num)
{
- /* This can never be called, because once poweroff driver is
- registered, the interface can't go away until the power
- driver is unregistered. */
+ if (!ready)
+ return;
+
+ if (ipmi_ifnum != if_num)
+ return;
+
+ ready = 0;
+ ipmi_destroy_user(ipmi_user);
+ pm_power_off = old_poweroff_func;
}
static struct ipmi_smi_watcher smi_watcher =
@@ -616,9 +702,9 @@ static int ipmi_poweroff_init (void)
printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv);
goto out_err;
}
-#endif
out_err:
+#endif
return rv;
}
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index bb1fac104fd..81a0c89598e 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -61,6 +61,10 @@
#include "ipmi_si_sm.h"
#include <linux/init.h>
#include <linux/dmi.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+
+#define PFX "ipmi_si: "
/* Measure times between events in the driver. */
#undef DEBUG_TIMING
@@ -92,7 +96,7 @@ enum si_intf_state {
enum si_type {
SI_KCS, SI_SMIC, SI_BT
};
-static char *si_to_str[] = { "KCS", "SMIC", "BT" };
+static char *si_to_str[] = { "kcs", "smic", "bt" };
#define DEVICE_NAME "ipmi_si"
@@ -222,7 +226,10 @@ struct smi_info
static int force_kipmid[SI_MAX_PARMS];
static int num_force_kipmid;
+static int unload_when_empty = 1;
+
static int try_smi_init(struct smi_info *smi);
+static void cleanup_one_si(struct smi_info *to_clean);
static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list);
static int register_xaction_notifier(struct notifier_block * nb)
@@ -240,14 +247,18 @@ static void deliver_recv_msg(struct smi_info *smi_info,
spin_lock(&(smi_info->si_lock));
}
-static void return_hosed_msg(struct smi_info *smi_info)
+static void return_hosed_msg(struct smi_info *smi_info, int cCode)
{
struct ipmi_smi_msg *msg = smi_info->curr_msg;
+ if (cCode < 0 || cCode > IPMI_ERR_UNSPECIFIED)
+ cCode = IPMI_ERR_UNSPECIFIED;
+ /* else use it as is */
+
/* Make it a reponse */
msg->rsp[0] = msg->data[0] | 4;
msg->rsp[1] = msg->data[1];
- msg->rsp[2] = 0xFF; /* Unknown error. */
+ msg->rsp[2] = cCode;
msg->rsp_size = 3;
smi_info->curr_msg = NULL;
@@ -298,7 +309,7 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info)
smi_info->curr_msg->data,
smi_info->curr_msg->data_size);
if (err) {
- return_hosed_msg(smi_info);
+ return_hosed_msg(smi_info, err);
}
rv = SI_SM_CALL_WITHOUT_DELAY;
@@ -640,7 +651,7 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
/* If we were handling a user message, format
a response to send to the upper layer to
tell it about the error. */
- return_hosed_msg(smi_info);
+ return_hosed_msg(smi_info, IPMI_ERR_UNSPECIFIED);
}
si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
}
@@ -684,22 +695,24 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
{
/* We are idle and the upper layer requested that I fetch
events, so do so. */
- unsigned char msg[2];
+ atomic_set(&smi_info->req_events, 0);
- spin_lock(&smi_info->count_lock);
- smi_info->flag_fetches++;
- spin_unlock(&smi_info->count_lock);
+ smi_info->curr_msg = ipmi_alloc_smi_msg();
+ if (!smi_info->curr_msg)
+ goto out;
- atomic_set(&smi_info->req_events, 0);
- msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
- msg[1] = IPMI_GET_MSG_FLAGS_CMD;
+ smi_info->curr_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
+ smi_info->curr_msg->data[1] = IPMI_READ_EVENT_MSG_BUFFER_CMD;
+ smi_info->curr_msg->data_size = 2;
smi_info->handlers->start_transaction(
- smi_info->si_sm, msg, 2);
- smi_info->si_state = SI_GETTING_FLAGS;
+ smi_info->si_sm,
+ smi_info->curr_msg->data,
+ smi_info->curr_msg->data_size);
+ smi_info->si_state = SI_GETTING_EVENTS;
goto restart;
}
-
+ out:
return si_sm_result;
}
@@ -714,6 +727,15 @@ static void sender(void *send_info,
struct timeval t;
#endif
+ if (atomic_read(&smi_info->stop_operation)) {
+ msg->rsp[0] = msg->data[0] | 4;
+ msg->rsp[1] = msg->data[1];
+ msg->rsp[2] = IPMI_ERR_UNSPECIFIED;
+ msg->rsp_size = 3;
+ deliver_recv_msg(smi_info, msg);
+ return;
+ }
+
spin_lock_irqsave(&(smi_info->msg_lock), flags);
#ifdef DEBUG_TIMING
do_gettimeofday(&t);
@@ -805,13 +827,21 @@ static void poll(void *send_info)
{
struct smi_info *smi_info = send_info;
- smi_event_handler(smi_info, 0);
+ /*
+ * Make sure there is some delay in the poll loop so we can
+ * drive time forward and timeout things.
+ */
+ udelay(10);
+ smi_event_handler(smi_info, 10);
}
static void request_events(void *send_info)
{
struct smi_info *smi_info = send_info;
+ if (atomic_read(&smi_info->stop_operation))
+ return;
+
atomic_set(&smi_info->req_events, 1);
}
@@ -949,12 +979,21 @@ static int smi_start_processing(void *send_info,
return 0;
}
+static void set_maintenance_mode(void *send_info, int enable)
+{
+ struct smi_info *smi_info = send_info;
+
+ if (!enable)
+ atomic_set(&smi_info->req_events, 0);
+}
+
static struct ipmi_smi_handlers handlers =
{
.owner = THIS_MODULE,
.start_processing = smi_start_processing,
.sender = sender,
.request_events = request_events,
+ .set_maintenance_mode = set_maintenance_mode,
.set_run_to_completion = set_run_to_completion,
.poll = poll,
};
@@ -987,6 +1026,16 @@ static int num_regshifts = 0;
static int slave_addrs[SI_MAX_PARMS];
static int num_slave_addrs = 0;
+#define IPMI_IO_ADDR_SPACE 0
+#define IPMI_MEM_ADDR_SPACE 1
+static char *addr_space_to_str[] = { "I/O", "mem" };
+
+static int hotmod_handler(const char *val, struct kernel_param *kp);
+
+module_param_call(hotmod, hotmod_handler, NULL, NULL, 0200);
+MODULE_PARM_DESC(hotmod, "Add and remove interfaces. See"
+ " Documentation/IPMI.txt in the kernel sources for the"
+ " gory details.");
module_param_named(trydefaults, si_trydefaults, bool, 0);
MODULE_PARM_DESC(trydefaults, "Setting this to 'false' will disable the"
@@ -1038,12 +1087,12 @@ module_param_array(force_kipmid, int, &num_force_kipmid, 0);
MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or"
" disabled(0). Normally the IPMI driver auto-detects"
" this, but the value may be overridden by this parm.");
+module_param(unload_when_empty, int, 0);
+MODULE_PARM_DESC(unload_when_empty, "Unload the module if no interfaces are"
+ " specified or found, default is 1. Setting to 0"
+ " is useful for hot add of devices using hotmod.");
-#define IPMI_IO_ADDR_SPACE 0
-#define IPMI_MEM_ADDR_SPACE 1
-static char *addr_space_to_str[] = { "I/O", "memory" };
-
static void std_irq_cleanup(struct smi_info *info)
{
if (info->si_type == SI_BT)
@@ -1317,6 +1366,234 @@ static int mem_setup(struct smi_info *info)
return 0;
}
+/*
+ * Parms come in as <op1>[:op2[:op3...]]. ops are:
+ * add|remove,kcs|bt|smic,mem|i/o,<address>[,<opt1>[,<opt2>[,...]]]
+ * Options are:
+ * rsp=<regspacing>
+ * rsi=<regsize>
+ * rsh=<regshift>
+ * irq=<irq>
+ * ipmb=<ipmb addr>
+ */
+enum hotmod_op { HM_ADD, HM_REMOVE };
+struct hotmod_vals {
+ char *name;
+ int val;
+};
+static struct hotmod_vals hotmod_ops[] = {
+ { "add", HM_ADD },
+ { "remove", HM_REMOVE },
+ { NULL }
+};
+static struct hotmod_vals hotmod_si[] = {
+ { "kcs", SI_KCS },
+ { "smic", SI_SMIC },
+ { "bt", SI_BT },
+ { NULL }
+};
+static struct hotmod_vals hotmod_as[] = {
+ { "mem", IPMI_MEM_ADDR_SPACE },
+ { "i/o", IPMI_IO_ADDR_SPACE },
+ { NULL }
+};
+static int ipmi_strcasecmp(const char *s1, const char *s2)
+{
+ while (*s1 || *s2) {
+ if (!*s1)
+ return -1;
+ if (!*s2)
+ return 1;
+ if (*s1 != *s2)
+ return *s1 - *s2;
+ s1++;
+ s2++;
+ }
+ return 0;
+}
+static int parse_str(struct hotmod_vals *v, int *val, char *name, char **curr)
+{
+ char *s;
+ int i;
+
+ s = strchr(*curr, ',');
+ if (!s) {
+ printk(KERN_WARNING PFX "No hotmod %s given.\n", name);
+ return -EINVAL;
+ }
+ *s = '\0';
+ s++;
+ for (i = 0; hotmod_ops[i].name; i++) {
+ if (ipmi_strcasecmp(*curr, v[i].name) == 0) {
+ *val = v[i].val;
+ *curr = s;
+ return 0;
+ }
+ }
+
+ printk(KERN_WARNING PFX "Invalid hotmod %s '%s'\n", name, *curr);
+ return -EINVAL;
+}
+
+static int hotmod_handler(const char *val, struct kernel_param *kp)
+{
+ char *str = kstrdup(val, GFP_KERNEL);
+ int rv = -EINVAL;
+ char *next, *curr, *s, *n, *o;
+ enum hotmod_op op;
+ enum si_type si_type;
+ int addr_space;
+ unsigned long addr;
+ int regspacing;
+ int regsize;
+ int regshift;
+ int irq;
+ int ipmb;
+ int ival;
+ struct smi_info *info;
+
+ if (!str)
+ return -ENOMEM;
+
+ /* Kill any trailing spaces, as we can get a "\n" from echo. */
+ ival = strlen(str) - 1;
+ while ((ival >= 0) && isspace(str[ival])) {
+ str[ival] = '\0';
+ ival--;
+ }
+
+ for (curr = str; curr; curr = next) {
+ regspacing = 1;
+ regsize = 1;
+ regshift = 0;
+ irq = 0;
+ ipmb = 0x20;
+
+ next = strchr(curr, ':');
+ if (next) {
+ *next = '\0';
+ next++;
+ }
+
+ rv = parse_str(hotmod_ops, &ival, "operation", &curr);
+ if (rv)
+ break;
+ op = ival;
+
+ rv = parse_str(hotmod_si, &ival, "interface type", &curr);
+ if (rv)
+ break;
+ si_type = ival;
+
+ rv = parse_str(hotmod_as, &addr_space, "address space", &curr);
+ if (rv)
+ break;
+
+ s = strchr(curr, ',');
+ if (s) {
+ *s = '\0';
+ s++;
+ }
+ addr = simple_strtoul(curr, &n, 0);
+ if ((*n != '\0') || (*curr == '\0')) {
+ printk(KERN_WARNING PFX "Invalid hotmod address"
+ " '%s'\n", curr);
+ break;
+ }
+
+ while (s) {
+ curr = s;
+ s = strchr(curr, ',');
+ if (s) {
+ *s = '\0';
+ s++;
+ }
+ o = strchr(curr, '=');
+ if (o) {
+ *o = '\0';
+ o++;
+ }
+#define HOTMOD_INT_OPT(name, val) \
+ if (ipmi_strcasecmp(curr, name) == 0) { \
+ if (!o) { \
+ printk(KERN_WARNING PFX \
+ "No option given for '%s'\n", \
+ curr); \
+ goto out; \
+ } \
+ val = simple_strtoul(o, &n, 0); \
+ if ((*n != '\0') || (*o == '\0')) { \
+ printk(KERN_WARNING PFX \
+ "Bad option given for '%s'\n", \
+ curr); \
+ goto out; \
+ } \
+ }
+
+ HOTMOD_INT_OPT("rsp", regspacing)
+ else HOTMOD_INT_OPT("rsi", regsize)
+ else HOTMOD_INT_OPT("rsh", regshift)
+ else HOTMOD_INT_OPT("irq", irq)
+ else HOTMOD_INT_OPT("ipmb", ipmb)
+ else {
+ printk(KERN_WARNING PFX
+ "Invalid hotmod option '%s'\n",
+ curr);
+ goto out;
+ }
+#undef HOTMOD_INT_OPT
+ }
+
+ if (op == HM_ADD) {
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info) {
+ rv = -ENOMEM;
+ goto out;
+ }
+
+ info->addr_source = "hotmod";
+ info->si_type = si_type;
+ info->io.addr_data = addr;
+ info->io.addr_type = addr_space;
+ if (addr_space == IPMI_MEM_ADDR_SPACE)
+ info->io_setup = mem_setup;
+ else
+ info->io_setup = port_setup;
+
+ info->io.addr = NULL;
+ info->io.regspacing = regspacing;
+ if (!info->io.regspacing)
+ info->io.regspacing = DEFAULT_REGSPACING;
+ info->io.regsize = regsize;
+ if (!info->io.regsize)
+ info->io.regsize = DEFAULT_REGSPACING;
+ info->io.regshift = regshift;
+ info->irq = irq;
+ if (info->irq)
+ info->irq_setup = std_irq_setup;
+ info->slave_addr = ipmb;
+
+ try_smi_init(info);
+ } else {
+ /* remove */
+ struct smi_info *e, *tmp_e;
+
+ mutex_lock(&smi_infos_lock);
+ list_for_each_entry_safe(e, tmp_e, &smi_infos, link) {
+ if (e->io.addr_type != addr_space)
+ continue;
+ if (e->si_type != si_type)
+ continue;
+ if (e->io.addr_data == addr)
+ cleanup_one_si(e);
+ }
+ mutex_unlock(&smi_infos_lock);
+ }
+ }
+ out:
+ kfree(str);
+ return rv;
+}
static __devinit void hardcode_find_bmc(void)
{
@@ -1333,11 +1610,11 @@ static __devinit void hardcode_find_bmc(void)
info->addr_source = "hardcoded";
- if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) {
+ if (!si_type[i] || ipmi_strcasecmp(si_type[i], "kcs") == 0) {
info->si_type = SI_KCS;
- } else if (strcmp(si_type[i], "smic") == 0) {
+ } else if (ipmi_strcasecmp(si_type[i], "smic") == 0) {
info->si_type = SI_SMIC;
- } else if (strcmp(si_type[i], "bt") == 0) {
+ } else if (ipmi_strcasecmp(si_type[i], "bt") == 0) {
info->si_type = SI_BT;
} else {
printk(KERN_WARNING
@@ -1952,19 +2229,9 @@ static int try_get_dev_id(struct smi_info *smi_info)
static int type_file_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
- char *out = (char *) page;
struct smi_info *smi = data;
- switch (smi->si_type) {
- case SI_KCS:
- return sprintf(out, "kcs\n");
- case SI_SMIC:
- return sprintf(out, "smic\n");
- case SI_BT:
- return sprintf(out, "bt\n");
- default:
- return 0;
- }
+ return sprintf(page, "%s\n", si_to_str[smi->si_type]);
}
static int stat_file_read_proc(char *page, char **start, off_t off,
@@ -2000,7 +2267,24 @@ static int stat_file_read_proc(char *page, char **start, off_t off,
out += sprintf(out, "incoming_messages: %ld\n",
smi->incoming_messages);
- return (out - ((char *) page));
+ return out - page;
+}
+
+static int param_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ struct smi_info *smi = data;
+
+ return sprintf(page,
+ "%s,%s,0x%lx,rsp=%d,rsi=%d,rsh=%d,irq=%d,ipmb=%d\n",
+ si_to_str[smi->si_type],
+ addr_space_to_str[smi->io.addr_type],
+ smi->io.addr_data,
+ smi->io.regspacing,
+ smi->io.regsize,
+ smi->io.regshift,
+ smi->irq,
+ smi->slave_addr);
}
/*
@@ -2362,6 +2646,7 @@ static int try_smi_init(struct smi_info *new_smi)
new_smi,
&new_smi->device_id,
new_smi->dev,
+ "bmc",
new_smi->slave_addr);
if (rv) {
printk(KERN_ERR
@@ -2390,6 +2675,16 @@ static int try_smi_init(struct smi_info *new_smi)
goto out_err_stop_timer;
}
+ rv = ipmi_smi_add_proc_entry(new_smi->intf, "params",
+ param_read_proc, NULL,
+ new_smi, THIS_MODULE);
+ if (rv) {
+ printk(KERN_ERR
+ "ipmi_si: Unable to create proc entry: %d\n",
+ rv);
+ goto out_err_stop_timer;
+ }
+
list_add_tail(&new_smi->link, &smi_infos);
mutex_unlock(&smi_infos_lock);
@@ -2483,7 +2778,12 @@ static __devinit int init_ipmi_si(void)
#endif
#ifdef CONFIG_PCI
- pci_module_init(&ipmi_pci_driver);
+ rv = pci_register_driver(&ipmi_pci_driver);
+ if (rv){
+ printk(KERN_ERR
+ "init_ipmi_si: Unable to register PCI driver: %d\n",
+ rv);
+ }
#endif
if (si_trydefaults) {
@@ -2498,7 +2798,7 @@ static __devinit int init_ipmi_si(void)
}
mutex_lock(&smi_infos_lock);
- if (list_empty(&smi_infos)) {
+ if (unload_when_empty && list_empty(&smi_infos)) {
mutex_unlock(&smi_infos_lock);
#ifdef CONFIG_PCI
pci_unregister_driver(&ipmi_pci_driver);
@@ -2513,7 +2813,7 @@ static __devinit int init_ipmi_si(void)
}
module_init(init_ipmi_si);
-static void __devexit cleanup_one_si(struct smi_info *to_clean)
+static void cleanup_one_si(struct smi_info *to_clean)
{
int rv;
unsigned long flags;
diff --git a/drivers/char/ipmi/ipmi_smic_sm.c b/drivers/char/ipmi/ipmi_smic_sm.c
index 39d7e5ef1a2..e64ea7d25d2 100644
--- a/drivers/char/ipmi/ipmi_smic_sm.c
+++ b/drivers/char/ipmi/ipmi_smic_sm.c
@@ -141,12 +141,14 @@ static int start_smic_transaction(struct si_sm_data *smic,
{
unsigned int i;
- if ((size < 2) || (size > MAX_SMIC_WRITE_SIZE)) {
- return -1;
- }
- if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) {
- return -2;
- }
+ if (size < 2)
+ return IPMI_REQ_LEN_INVALID_ERR;
+ if (size > MAX_SMIC_WRITE_SIZE)
+ return IPMI_REQ_LEN_EXCEEDED_ERR;
+
+ if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED))
+ return IPMI_NOT_IN_MY_STATE_ERR;
+
if (smic_debug & SMIC_DEBUG_MSG) {
printk(KERN_INFO "start_smic_transaction -");
for (i = 0; i < size; i ++) {
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 73f759eaa5a..90fb2a54191 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -135,6 +135,7 @@
static int nowayout = WATCHDOG_NOWAYOUT;
static ipmi_user_t watchdog_user = NULL;
+static int watchdog_ifnum;
/* Default the timeout to 10 seconds. */
static int timeout = 10;
@@ -161,6 +162,8 @@ static struct fasync_struct *fasync_q = NULL;
static char pretimeout_since_last_heartbeat = 0;
static char expect_close;
+static int ifnum_to_use = -1;
+
static DECLARE_RWSEM(register_sem);
/* Parameters to ipmi_set_timeout */
@@ -169,6 +172,8 @@ static DECLARE_RWSEM(register_sem);
#define IPMI_SET_TIMEOUT_FORCE_HB 2
static int ipmi_set_timeout(int do_heartbeat);
+static void ipmi_register_watchdog(int ipmi_intf);
+static void ipmi_unregister_watchdog(int ipmi_intf);
/* If true, the driver will start running as soon as it is configured
and ready. */
@@ -245,6 +250,26 @@ static int get_param_str(char *buffer, struct kernel_param *kp)
return strlen(buffer);
}
+
+static int set_param_wdog_ifnum(const char *val, struct kernel_param *kp)
+{
+ int rv = param_set_int(val, kp);
+ if (rv)
+ return rv;
+ if ((ifnum_to_use < 0) || (ifnum_to_use == watchdog_ifnum))
+ return 0;
+
+ ipmi_unregister_watchdog(watchdog_ifnum);
+ ipmi_register_watchdog(ifnum_to_use);
+ return 0;
+}
+
+module_param_call(ifnum_to_use, set_param_wdog_ifnum, get_param_int,
+ &ifnum_to_use, 0644);
+MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog "
+ "timer. Setting to -1 defaults to the first registered "
+ "interface");
+
module_param_call(timeout, set_param_int, get_param_int, &timeout, 0644);
MODULE_PARM_DESC(timeout, "Timeout value in seconds.");
@@ -263,12 +288,13 @@ module_param_call(preop, set_param_str, get_param_str, preop_op, 0644);
MODULE_PARM_DESC(preop, "Pretimeout driver operation. One of: "
"preop_none, preop_panic, preop_give_data.");
-module_param(start_now, int, 0);
+module_param(start_now, int, 0444);
MODULE_PARM_DESC(start_now, "Set to 1 to start the watchdog as"
"soon as the driver is loaded.");
module_param(nowayout, int, 0644);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
+ "(default=CONFIG_WATCHDOG_NOWAYOUT)");
/* Default state of the timer. */
static unsigned char ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
@@ -872,6 +898,11 @@ static void ipmi_register_watchdog(int ipmi_intf)
if (watchdog_user)
goto out;
+ if ((ifnum_to_use >= 0) && (ifnum_to_use != ipmi_intf))
+ goto out;
+
+ watchdog_ifnum = ipmi_intf;
+
rv = ipmi_create_user(ipmi_intf, &ipmi_hndlrs, NULL, &watchdog_user);
if (rv < 0) {
printk(KERN_CRIT PFX "Unable to register with ipmi\n");
@@ -901,6 +932,39 @@ static void ipmi_register_watchdog(int ipmi_intf)
}
}
+static void ipmi_unregister_watchdog(int ipmi_intf)
+{
+ int rv;
+
+ down_write(&register_sem);
+
+ if (!watchdog_user)
+ goto out;
+
+ if (watchdog_ifnum != ipmi_intf)
+ goto out;
+
+ /* Make sure no one can call us any more. */
+ misc_deregister(&ipmi_wdog_miscdev);
+
+ /* Wait to make sure the message makes it out. The lower layer has
+ pointers to our buffers, we want to make sure they are done before
+ we release our memory. */
+ while (atomic_read(&set_timeout_tofree))
+ schedule_timeout_uninterruptible(1);
+
+ /* Disconnect from IPMI. */
+ rv = ipmi_destroy_user(watchdog_user);
+ if (rv) {
+ printk(KERN_WARNING PFX "error unlinking from IPMI: %d\n",
+ rv);
+ }
+ watchdog_user = NULL;
+
+ out:
+ up_write(&register_sem);
+}
+
#ifdef HAVE_NMI_HANDLER
static int
ipmi_nmi(void *dev_id, int cpu, int handled)
@@ -1004,9 +1068,7 @@ static void ipmi_new_smi(int if_num, struct device *device)
static void ipmi_smi_gone(int if_num)
{
- /* This can never be called, because once the watchdog is
- registered, the interface can't go away until the watchdog
- is unregistered. */
+ ipmi_unregister_watchdog(if_num);
}
static struct ipmi_smi_watcher smi_watcher =
@@ -1148,30 +1210,32 @@ static int __init ipmi_wdog_init(void)
check_parms();
+ register_reboot_notifier(&wdog_reboot_notifier);
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &wdog_panic_notifier);
+
rv = ipmi_smi_watcher_register(&smi_watcher);
if (rv) {
#ifdef HAVE_NMI_HANDLER
if (preaction_val == WDOG_PRETIMEOUT_NMI)
release_nmi(&ipmi_nmi_handler);
#endif
+ atomic_notifier_chain_unregister(&panic_notifier_list,
+ &wdog_panic_notifier);
+ unregister_reboot_notifier(&wdog_reboot_notifier);
printk(KERN_WARNING PFX "can't register smi watcher\n");
return rv;
}
- register_reboot_notifier(&wdog_reboot_notifier);
- atomic_notifier_chain_register(&panic_notifier_list,
- &wdog_panic_notifier);
-
printk(KERN_INFO PFX "driver initialized\n");
return 0;
}
-static __exit void ipmi_unregister_watchdog(void)
+static void __exit ipmi_wdog_exit(void)
{
- int rv;
-
- down_write(&register_sem);
+ ipmi_smi_watcher_unregister(&smi_watcher);
+ ipmi_unregister_watchdog(watchdog_ifnum);
#ifdef HAVE_NMI_HANDLER
if (nmi_handler_registered)
@@ -1179,37 +1243,8 @@ static __exit void ipmi_unregister_watchdog(void)
#endif
atomic_notifier_chain_unregister(&panic_notifier_list,
- &wdog_panic_notifier);
+ &wdog_panic_notifier);
unregister_reboot_notifier(&wdog_reboot_notifier);
-
- if (! watchdog_user)
- goto out;
-
- /* Make sure no one can call us any more. */
- misc_deregister(&ipmi_wdog_miscdev);
-
- /* Wait to make sure the message makes it out. The lower layer has
- pointers to our buffers, we want to make sure they are done before
- we release our memory. */
- while (atomic_read(&set_timeout_tofree))
- schedule_timeout_uninterruptible(1);
-
- /* Disconnect from IPMI. */
- rv = ipmi_destroy_user(watchdog_user);
- if (rv) {
- printk(KERN_WARNING PFX "error unlinking from IPMI: %d\n",
- rv);
- }
- watchdog_user = NULL;
-
- out:
- up_write(&register_sem);
-}
-
-static void __exit ipmi_wdog_exit(void)
-{
- ipmi_smi_watcher_unregister(&smi_watcher);
- ipmi_unregister_watchdog();
}
module_exit(ipmi_wdog_exit);
module_init(ipmi_wdog_init);
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index bd9195e1795..8f591945ebd 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -3476,6 +3476,8 @@ static int stli_initecp(stlibrd_t *brdp)
if (sig.magic != cpu_to_le32(ECP_MAGIC))
{
release_region(brdp->iobase, brdp->iosize);
+ iounmap(brdp->membase);
+ brdp->membase = NULL;
return -ENODEV;
}
@@ -3632,6 +3634,8 @@ static int stli_initonb(stlibrd_t *brdp)
sig.magic3 != cpu_to_le16(ONB_MAGIC3))
{
release_region(brdp->iobase, brdp->iosize);
+ iounmap(brdp->membase);
+ brdp->membase = NULL;
return -ENODEV;
}
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 7a484fc7cb9..7e975f60692 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -199,6 +199,8 @@ int misc_register(struct miscdevice * misc)
dev_t dev;
int err = 0;
+ INIT_LIST_HEAD(&misc->list);
+
down(&misc_sem);
list_for_each_entry(c, &misc_list, list) {
if (c->minor == misc->minor) {
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c
index 22b9905c1e5..c09160383a5 100644
--- a/drivers/char/mmtimer.c
+++ b/drivers/char/mmtimer.c
@@ -680,7 +680,7 @@ static int __init mmtimer_init(void)
if (sn_rtc_cycles_per_second < 100000) {
printk(KERN_ERR "%s: unable to determine clock frequency\n",
MMTIMER_NAME);
- return -1;
+ goto out1;
}
mmtimer_femtoperiod = ((unsigned long)1E15 + sn_rtc_cycles_per_second /
@@ -689,13 +689,13 @@ static int __init mmtimer_init(void)
if (request_irq(SGI_MMTIMER_VECTOR, mmtimer_interrupt, IRQF_PERCPU, MMTIMER_NAME, NULL)) {
printk(KERN_WARNING "%s: unable to allocate interrupt.",
MMTIMER_NAME);
- return -1;
+ goto out1;
}
if (misc_register(&mmtimer_miscdev)) {
printk(KERN_ERR "%s: failed to register device\n",
MMTIMER_NAME);
- return -1;
+ goto out2;
}
/* Get max numbered node, calculate slots needed */
@@ -709,16 +709,18 @@ static int __init mmtimer_init(void)
if (timers == NULL) {
printk(KERN_ERR "%s: failed to allocate memory for device\n",
MMTIMER_NAME);
- return -1;
+ goto out3;
}
+ memset(timers,0,(sizeof(mmtimer_t *)*maxn));
+
/* Allocate mmtimer_t's for each online node */
for_each_online_node(node) {
timers[node] = kmalloc_node(sizeof(mmtimer_t)*NUM_COMPARATORS, GFP_KERNEL, node);
if (timers[node] == NULL) {
printk(KERN_ERR "%s: failed to allocate memory for device\n",
MMTIMER_NAME);
- return -1;
+ goto out4;
}
for (i=0; i< NUM_COMPARATORS; i++) {
mmtimer_t * base = timers[node] + i;
@@ -739,6 +741,17 @@ static int __init mmtimer_init(void)
sn_rtc_cycles_per_second/(unsigned long)1E6);
return 0;
+
+out4:
+ for_each_online_node(node) {
+ kfree(timers[node]);
+ }
+out3:
+ misc_deregister(&mmtimer_miscdev);
+out2:
+ free_irq(SGI_MMTIMER_VECTOR, NULL);
+out1:
+ return -1;
}
module_init(mmtimer_init);
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 2d025a9fd14..8b316953173 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -498,9 +498,12 @@ static void __exit moxa_exit(void)
printk("Couldn't unregister MOXA Intellio family serial driver\n");
put_tty_driver(moxaDriver);
- for (i = 0; i < MAX_BOARDS; i++)
+ for (i = 0; i < MAX_BOARDS; i++) {
+ if (moxaBaseAddr[i])
+ iounmap(moxaBaseAddr[i]);
if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI)
pci_dev_put(moxa_boards[i].pciInfo.pdev);
+ }
if (verbose)
printk("Done\n");
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 1bd12296dca..74d21c1c104 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -75,8 +75,10 @@
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-#ifdef CONFIG_HDLC_MODULE
-#define CONFIG_HDLC 1
+#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_CS_MODULE))
+#define SYNCLINK_GENERIC_HDLC 1
+#else
+#define SYNCLINK_GENERIC_HDLC 0
#endif
#define GET_USER(error,value,addr) error = get_user(value,addr)
@@ -235,7 +237,7 @@ typedef struct _mgslpc_info {
int dosyncppp;
spinlock_t netlock;
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
struct net_device *netdev;
#endif
@@ -392,7 +394,7 @@ static void tx_timeout(unsigned long context);
static int ioctl_common(MGSLPC_INFO *info, unsigned int cmd, unsigned long arg);
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
#define dev_to_port(D) (dev_to_hdlc(D)->priv)
static void hdlcdev_tx_done(MGSLPC_INFO *info);
static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size);
@@ -1053,7 +1055,7 @@ static void tx_done(MGSLPC_INFO *info)
info->drop_rts_on_tx_done = 0;
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)
hdlcdev_tx_done(info);
else
@@ -1164,7 +1166,7 @@ static void dcd_change(MGSLPC_INFO *info)
}
else
info->input_signal_events.dcd_down++;
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount) {
if (info->serial_signals & SerialSignal_DCD)
netif_carrier_on(info->netdev);
@@ -2953,7 +2955,7 @@ static void mgslpc_add_device(MGSLPC_INFO *info)
printk( "SyncLink PC Card %s:IO=%04X IRQ=%d\n",
info->device_name, info->io_base, info->irq_level);
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
hdlcdev_init(info);
#endif
}
@@ -2969,7 +2971,7 @@ static void mgslpc_remove_device(MGSLPC_INFO *remove_info)
last->next_device = info->next_device;
else
mgslpc_device_list = info->next_device;
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
hdlcdev_exit(info);
#endif
release_resources(info);
@@ -3901,7 +3903,7 @@ static int rx_get_frame(MGSLPC_INFO *info)
return_frame = 1;
}
framesize = 0;
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
{
struct net_device_stats *stats = hdlc_stats(info->netdev);
stats->rx_errors++;
@@ -3935,7 +3937,7 @@ static int rx_get_frame(MGSLPC_INFO *info)
++framesize;
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)
hdlcdev_rx(info, buf->data, framesize);
else
@@ -4091,7 +4093,7 @@ static void tx_timeout(unsigned long context)
spin_unlock_irqrestore(&info->lock,flags);
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)
hdlcdev_tx_done(info);
else
@@ -4099,7 +4101,7 @@ static void tx_timeout(unsigned long context)
bh_transmit(info);
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
/**
* called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 7ac68cb3bed..e79b2ede851 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -1026,6 +1026,7 @@ static int __init rio_init(void)
found++;
} else {
iounmap(p->RIOHosts[p->RIONumHosts].Caddr);
+ p->RIOHosts[p->RIONumHosts].Caddr = NULL;
}
}
@@ -1078,6 +1079,7 @@ static int __init rio_init(void)
found++;
} else {
iounmap(p->RIOHosts[p->RIONumHosts].Caddr);
+ p->RIOHosts[p->RIONumHosts].Caddr = NULL;
}
#else
printk(KERN_ERR "Found an older RIO PCI card, but the driver is not " "compiled to support it.\n");
@@ -1117,8 +1119,10 @@ static int __init rio_init(void)
}
}
- if (!okboard)
+ if (!okboard) {
iounmap(hp->Caddr);
+ hp->Caddr = NULL;
+ }
}
}
@@ -1188,6 +1192,8 @@ static void __exit rio_exit(void)
}
/* It is safe/allowed to del_timer a non-active timer */
del_timer(&hp->timer);
+ if (hp->Caddr)
+ iounmap(hp->Caddr);
if (hp->Type == RIO_PCI)
pci_dev_put(hp->pdev);
}
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 722dd3e7418..0a77bfcd5b5 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -82,11 +82,6 @@
static struct riscom_board * IRQ_to_board[16];
static struct tty_driver *riscom_driver;
-static unsigned long baud_table[] = {
- 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 57600, 76800, 0,
-};
-
static struct riscom_board rc_board[RC_NBOARD] = {
{
.base = RC_IOBASE1,
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 147c30da81e..645187b9141 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -101,8 +101,10 @@
#include <linux/hdlc.h>
#include <linux/dma-mapping.h>
-#ifdef CONFIG_HDLC_MODULE
-#define CONFIG_HDLC 1
+#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_MODULE))
+#define SYNCLINK_GENERIC_HDLC 1
+#else
+#define SYNCLINK_GENERIC_HDLC 0
#endif
#define GET_USER(error,value,addr) error = get_user(value,addr)
@@ -320,7 +322,7 @@ struct mgsl_struct {
int dosyncppp;
spinlock_t netlock;
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
struct net_device *netdev;
#endif
};
@@ -728,7 +730,7 @@ static void usc_loopmode_send_done( struct mgsl_struct * info );
static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg);
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
#define dev_to_port(D) (dev_to_hdlc(D)->priv)
static void hdlcdev_tx_done(struct mgsl_struct *info);
static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size);
@@ -1277,7 +1279,7 @@ static void mgsl_isr_transmit_status( struct mgsl_struct *info )
info->drop_rts_on_tx_done = 0;
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)
hdlcdev_tx_done(info);
else
@@ -1342,7 +1344,7 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info )
info->input_signal_events.dcd_up++;
} else
info->input_signal_events.dcd_down++;
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount) {
if (status & MISCSTATUS_DCD)
netif_carrier_on(info->netdev);
@@ -4313,7 +4315,7 @@ static void mgsl_add_device( struct mgsl_struct *info )
info->max_frame_size );
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
hdlcdev_init(info);
#endif
@@ -4471,7 +4473,7 @@ static void synclink_cleanup(void)
info = mgsl_device_list;
while(info) {
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
hdlcdev_exit(info);
#endif
mgsl_release_resources(info);
@@ -6645,7 +6647,7 @@ static int mgsl_get_rx_frame(struct mgsl_struct *info)
return_frame = 1;
}
framesize = 0;
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
{
struct net_device_stats *stats = hdlc_stats(info->netdev);
stats->rx_errors++;
@@ -6721,7 +6723,7 @@ static int mgsl_get_rx_frame(struct mgsl_struct *info)
*ptmp);
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)
hdlcdev_rx(info,info->intermediate_rxbuffer,framesize);
else
@@ -7625,7 +7627,7 @@ static void mgsl_tx_timeout(unsigned long context)
spin_unlock_irqrestore(&info->irq_spinlock,flags);
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)
hdlcdev_tx_done(info);
else
@@ -7701,7 +7703,7 @@ static int usc_loopmode_active( struct mgsl_struct * info)
return usc_InReg( info, CCSR ) & BIT7 ? 1 : 0 ;
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
/**
* called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 07f34d43dc7..e4730a7312b 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -83,8 +83,10 @@
#include "linux/synclink.h"
-#ifdef CONFIG_HDLC_MODULE
-#define CONFIG_HDLC 1
+#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_GT_MODULE))
+#define SYNCLINK_GENERIC_HDLC 1
+#else
+#define SYNCLINK_GENERIC_HDLC 0
#endif
/*
@@ -171,7 +173,7 @@ static void set_break(struct tty_struct *tty, int break_state);
/*
* generic HDLC support and callbacks
*/
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
#define dev_to_port(D) (dev_to_hdlc(D)->priv)
static void hdlcdev_tx_done(struct slgt_info *info);
static void hdlcdev_rx(struct slgt_info *info, char *buf, int size);
@@ -359,7 +361,7 @@ struct slgt_info {
int netcount;
int dosyncppp;
spinlock_t netlock;
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
struct net_device *netdev;
#endif
@@ -1354,7 +1356,7 @@ static void set_break(struct tty_struct *tty, int break_state)
spin_unlock_irqrestore(&info->lock,flags);
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
/**
* called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
@@ -2002,7 +2004,7 @@ static void dcd_change(struct slgt_info *info)
} else {
info->input_signal_events.dcd_down++;
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount) {
if (info->signals & SerialSignal_DCD)
netif_carrier_on(info->netdev);
@@ -2180,7 +2182,7 @@ static void isr_txeom(struct slgt_info *info, unsigned short status)
set_signals(info);
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)
hdlcdev_tx_done(info);
else
@@ -3306,7 +3308,7 @@ static void add_device(struct slgt_info *info)
devstr, info->device_name, info->phys_reg_addr,
info->irq_level, info->max_frame_size);
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
hdlcdev_init(info);
#endif
}
@@ -3488,7 +3490,7 @@ static void slgt_cleanup(void)
/* release devices */
info = slgt_device_list;
while(info) {
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
hdlcdev_exit(info);
#endif
free_dma_bufs(info);
@@ -3522,6 +3524,7 @@ static int __init slgt_init(void)
if (!slgt_device_list) {
printk("%s no devices found\n",driver_name);
+ pci_unregister_driver(&pci_driver);
return -ENODEV;
}
@@ -4433,7 +4436,7 @@ check_again:
framesize = 0;
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (framesize == 0) {
struct net_device_stats *stats = hdlc_stats(info->netdev);
stats->rx_errors++;
@@ -4476,7 +4479,7 @@ check_again:
framesize++;
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)
hdlcdev_rx(info,info->tmp_rbuf, framesize);
else
@@ -4779,7 +4782,7 @@ static void tx_timeout(unsigned long context)
info->tx_count = 0;
spin_unlock_irqrestore(&info->lock,flags);
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)
hdlcdev_tx_done(info);
else
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 13a57245cf2..20a96ef250b 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -67,8 +67,10 @@
#include <linux/workqueue.h>
#include <linux/hdlc.h>
-#ifdef CONFIG_HDLC_MODULE
-#define CONFIG_HDLC 1
+#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINKMP_MODULE))
+#define SYNCLINK_GENERIC_HDLC 1
+#else
+#define SYNCLINK_GENERIC_HDLC 0
#endif
#define GET_USER(error,value,addr) error = get_user(value,addr)
@@ -280,7 +282,7 @@ typedef struct _synclinkmp_info {
int dosyncppp;
spinlock_t netlock;
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
struct net_device *netdev;
#endif
@@ -536,7 +538,7 @@ static void throttle(struct tty_struct * tty);
static void unthrottle(struct tty_struct * tty);
static void set_break(struct tty_struct *tty, int break_state);
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
#define dev_to_port(D) (dev_to_hdlc(D)->priv)
static void hdlcdev_tx_done(SLMP_INFO *info);
static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size);
@@ -1607,7 +1609,7 @@ static void set_break(struct tty_struct *tty, int break_state)
spin_unlock_irqrestore(&info->lock,flags);
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
/**
* called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
@@ -2339,7 +2341,7 @@ static void isr_txeom(SLMP_INFO * info, unsigned char status)
set_signals(info);
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)
hdlcdev_tx_done(info);
else
@@ -2523,7 +2525,7 @@ void isr_io_pin( SLMP_INFO *info, u16 status )
info->input_signal_events.dcd_up++;
} else
info->input_signal_events.dcd_down++;
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount) {
if (status & SerialSignal_DCD)
netif_carrier_on(info->netdev);
@@ -3783,7 +3785,7 @@ void add_device(SLMP_INFO *info)
info->irq_level,
info->max_frame_size );
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
hdlcdev_init(info);
#endif
}
@@ -3977,7 +3979,7 @@ static void synclinkmp_cleanup(void)
/* release devices */
info = synclinkmp_device_list;
while(info) {
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
hdlcdev_exit(info);
#endif
free_dma_bufs(info);
@@ -4979,7 +4981,7 @@ CheckAgain:
info->icount.rxcrc++;
framesize = 0;
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
{
struct net_device_stats *stats = hdlc_stats(info->netdev);
stats->rx_errors++;
@@ -5020,7 +5022,7 @@ CheckAgain:
index = 0;
}
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)
hdlcdev_rx(info,info->tmp_rx_buf,framesize);
else
@@ -5531,7 +5533,7 @@ void tx_timeout(unsigned long context)
spin_unlock_irqrestore(&info->lock,flags);
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)
hdlcdev_tx_done(info);
else
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index c64f5bcff94..05810c8d20b 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -182,6 +182,18 @@ static struct sysrq_key_op sysrq_showstate_op = {
.enable_mask = SYSRQ_ENABLE_DUMP,
};
+static void sysrq_handle_showstate_blocked(int key, struct tty_struct *tty)
+{
+ show_state_filter(TASK_UNINTERRUPTIBLE);
+}
+static struct sysrq_key_op sysrq_showstate_blocked_op = {
+ .handler = sysrq_handle_showstate_blocked,
+ .help_msg = "showBlockedTasks",
+ .action_msg = "Show Blocked State",
+ .enable_mask = SYSRQ_ENABLE_DUMP,
+};
+
+
static void sysrq_handle_showmem(int key, struct tty_struct *tty)
{
show_mem();
@@ -304,7 +316,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
/* May be assigned at init time by SMP VOYAGER */
NULL, /* v */
NULL, /* w */
- NULL, /* x */
+ &sysrq_showstate_blocked_op, /* x */
NULL, /* y */
NULL /* z */
};
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c
index dd36fd04a84..07067c31c4e 100644
--- a/drivers/char/toshiba.c
+++ b/drivers/char/toshiba.c
@@ -249,6 +249,7 @@ int tosh_smm(SMMRegisters *regs)
return eax;
}
+EXPORT_SYMBOL(tosh_smm);
static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 774fa861169..33e1f66e39c 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -1155,6 +1155,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) {
list_del(&chip->list);
+ misc_deregister(&chip->vendor.miscdev);
put_device(dev);
clear_bit(chip->dev_num, dev_mask);
kfree(chip);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 75ff0286e1a..a8239dac994 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -152,7 +152,7 @@ static void gotoxy(struct vc_data *vc, int new_x, int new_y);
static void save_cur(struct vc_data *vc);
static void reset_terminal(struct vc_data *vc, int do_clear);
static void con_flush_chars(struct tty_struct *tty);
-static void set_vesa_blanking(char __user *p);
+static int set_vesa_blanking(char __user *p);
static void set_cursor(struct vc_data *vc);
static void hide_cursor(struct vc_data *vc);
static void console_callback(struct work_struct *ignored);
@@ -2369,7 +2369,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
ret = __put_user(data, p);
break;
case TIOCL_SETVESABLANK:
- set_vesa_blanking(p);
+ ret = set_vesa_blanking(p);
break;
case TIOCL_GETKMSGREDIRECT:
data = kmsg_redirect;
@@ -3313,11 +3313,15 @@ postcore_initcall(vtconsole_class_init);
* Screen blanking
*/
-static void set_vesa_blanking(char __user *p)
+static int set_vesa_blanking(char __user *p)
{
- unsigned int mode;
- get_user(mode, p + 1);
- vesa_blank_mode = (mode < 4) ? mode : 0;
+ unsigned int mode;
+
+ if (get_user(mode, p + 1))
+ return -EFAULT;
+
+ vesa_blank_mode = (mode < 4) ? mode : 0;
+ return 0;
}
void do_blank_screen(int entering_gfx)
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
index e275dd4a705..61138726b50 100644
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/char/watchdog/pcwd_usb.c
@@ -634,7 +634,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ? le16_to_cpu(endpoint->wMaxPacketSize) : 8);
/* set up the memory buffer's */
- if (!(usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, SLAB_ATOMIC, &usb_pcwd->intr_dma))) {
+ if (!(usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, GFP_ATOMIC, &usb_pcwd->intr_dma))) {
printk(KERN_ERR PFX "Out of memory\n");
goto error;
}
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 7a7c6e6dfe4..47ab42db122 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1537,7 +1537,6 @@ int cpufreq_update_policy(unsigned int cpu)
}
EXPORT_SYMBOL(cpufreq_update_policy);
-#ifdef CONFIG_HOTPLUG_CPU
static int cpufreq_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
@@ -1577,7 +1576,6 @@ static struct notifier_block __cpuinitdata cpufreq_cpu_notifier =
{
.notifier_call = cpufreq_cpu_callback,
};
-#endif /* CONFIG_HOTPLUG_CPU */
/*********************************************************************
* REGISTER / UNREGISTER CPUFREQ DRIVER *
diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioatdma.c
index 0358419a0e4..8e872610461 100644
--- a/drivers/dma/ioatdma.c
+++ b/drivers/dma/ioatdma.c
@@ -636,10 +636,10 @@ static int ioat_self_test(struct ioat_device *device)
dma_cookie_t cookie;
int err = 0;
- src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, SLAB_KERNEL);
+ src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL);
if (!src)
return -ENOMEM;
- dest = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, SLAB_KERNEL);
+ dest = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL);
if (!dest) {
kfree(src);
return -ENOMEM;
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 75e9e38330f..1b4fc922180 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -28,6 +28,7 @@
#include <linux/sysdev.h>
#include <linux/ctype.h>
#include <linux/kthread.h>
+#include <linux/freezer.h>
#include <asm/uaccess.h>
#include <asm/page.h>
#include <asm/edac.h>
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 0c68d0f0d8e..e23bc0d6215 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -389,14 +389,6 @@ config BLK_DEV_RZ1000
Linux. This may slow disk throughput by a few percent, but at least
things will operate 100% reliably.
-config BLK_DEV_SL82C105
- tristate "Winbond SL82c105 support"
- depends on PCI && (PPC || ARM) && BLK_DEV_IDEPCI
- help
- If you have a Winbond SL82c105 IDE controller, say Y here to enable
- special configuration for this chip. This is common on various CHRP
- motherboards, but could be used elsewhere. If in doubt, say Y.
-
config BLK_DEV_IDEDMA_PCI
bool "Generic PCI bus-master DMA support"
depends on PCI && BLK_DEV_IDEPCI
@@ -712,6 +704,14 @@ config BLK_DEV_SIS5513
Please read the comments at the top of <file:drivers/ide/pci/sis5513.c>.
+config BLK_DEV_SL82C105
+ tristate "Winbond SL82c105 support"
+ depends on (PPC || ARM)
+ help
+ If you have a Winbond SL82c105 IDE controller, say Y here to enable
+ special configuration for this chip. This is common on various CHRP
+ motherboards, but could be used elsewhere. If in doubt, say Y.
+
config BLK_DEV_SLC90E66
tristate "SLC90E66 chipset support"
help
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 287a6620115..16890769dca 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -973,8 +973,8 @@ ide_settings_t *ide_find_setting_by_name (ide_drive_t *drive, char *name)
* @drive: drive
*
* Automatically remove all the driver specific settings for this
- * drive. This function may sleep and must not be called from IRQ
- * context. The caller must hold ide_setting_sem.
+ * drive. This function may not be called from IRQ context. The
+ * caller must hold ide_setting_sem.
*/
static void auto_remove_settings (ide_drive_t *drive)
@@ -1874,11 +1874,22 @@ void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver)
{
unsigned long flags;
- down(&ide_setting_sem);
- spin_lock_irqsave(&ide_lock, flags);
#ifdef CONFIG_PROC_FS
ide_remove_proc_entries(drive->proc, driver->proc);
#endif
+ down(&ide_setting_sem);
+ spin_lock_irqsave(&ide_lock, flags);
+ /*
+ * ide_setting_sem protects the settings list
+ * ide_lock protects the use of settings
+ *
+ * so we need to hold both, ide_settings_sem because we want to
+ * modify the settings list, and ide_lock because we cannot take
+ * a setting out that is being used.
+ *
+ * OTOH both ide_{read,write}_setting are only ever used under
+ * ide_setting_sem.
+ */
auto_remove_settings(drive);
spin_unlock_irqrestore(&ide_lock, flags);
up(&ide_setting_sem);
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index eb7ab112c05..61f1a9665a7 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -282,11 +282,11 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
* Find the ISA bridge to see how good the IDE is.
*/
via_config = via_config_find(&isa);
- if (!via_config->id) {
- printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
- pci_dev_put(isa);
- return -ENODEV;
- }
+
+ /* We checked this earlier so if it fails here deeep badness
+ is involved */
+
+ BUG_ON(!via_config->id);
/*
* Setup or disable Clk66 if appropriate
@@ -494,6 +494,17 @@ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
+ struct pci_dev *isa = NULL;
+ struct via_isa_bridge *via_config;
+ /*
+ * Find the ISA bridge and check we know what it is.
+ */
+ via_config = via_config_find(&isa);
+ pci_dev_put(isa);
+ if (!via_config->id) {
+ printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
+ return -ENODEV;
+ }
return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]);
}
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index 31e5cc49d61..27d6c642415 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -133,7 +133,7 @@ struct eth1394_node_info {
#define ETH1394_DRIVER_NAME "eth1394"
static const char driver_name[] = ETH1394_DRIVER_NAME;
-static kmem_cache_t *packet_task_cache;
+static struct kmem_cache *packet_task_cache;
static struct hpsb_highlevel eth1394_highlevel;
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c
index 8f4378a1631..b935e08695a 100644
--- a/drivers/ieee1394/hosts.c
+++ b/drivers/ieee1394/hosts.c
@@ -123,7 +123,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
int i;
int hostnum = 0;
- h = kzalloc(sizeof(*h) + extra, SLAB_KERNEL);
+ h = kzalloc(sizeof(*h) + extra, GFP_KERNEL);
if (!h)
return NULL;
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 8e7b83f8448..e829c9336b3 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/moduleparam.h>
+#include <linux/freezer.h>
#include <asm/atomic.h>
#include "csr.h"
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index 6e8ea9110c4..eae97d8dcf0 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -1225,7 +1225,7 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso)
int ctx;
int ret = -ENOMEM;
- recv = kmalloc(sizeof(*recv), SLAB_KERNEL);
+ recv = kmalloc(sizeof(*recv), GFP_KERNEL);
if (!recv)
return -ENOMEM;
@@ -1918,7 +1918,7 @@ static int ohci_iso_xmit_init(struct hpsb_iso *iso)
int ctx;
int ret = -ENOMEM;
- xmit = kmalloc(sizeof(*xmit), SLAB_KERNEL);
+ xmit = kmalloc(sizeof(*xmit), GFP_KERNEL);
if (!xmit)
return -ENOMEM;
@@ -3021,7 +3021,7 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
return -ENOMEM;
}
- d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, SLAB_KERNEL, d->prg_bus+i);
+ d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i);
OHCI_DMA_ALLOC("pool dma_rcv prg[%d]", i);
if (d->prg_cpu[i] != NULL) {
@@ -3117,7 +3117,7 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
OHCI_DMA_ALLOC("dma_rcv prg pool");
for (i = 0; i < d->num_desc; i++) {
- d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, SLAB_KERNEL, d->prg_bus+i);
+ d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i);
OHCI_DMA_ALLOC("pool dma_trm prg[%d]", i);
if (d->prg_cpu[i] != NULL) {
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
index 0a7412e27eb..9cab1d66147 100644
--- a/drivers/ieee1394/pcilynx.c
+++ b/drivers/ieee1394/pcilynx.c
@@ -1428,7 +1428,7 @@ static int __devinit add_card(struct pci_dev *dev,
struct i2c_algo_bit_data i2c_adapter_data;
error = -ENOMEM;
- i2c_ad = kmalloc(sizeof(*i2c_ad), SLAB_KERNEL);
+ i2c_ad = kmalloc(sizeof(*i2c_ad), GFP_KERNEL);
if (!i2c_ad) FAIL("failed to allocate I2C adapter memory");
memcpy(i2c_ad, &bit_ops, sizeof(struct i2c_adapter));
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 5ec4f5eb6b1..bf71e069eaf 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -112,7 +112,7 @@ static struct pending_request *__alloc_pending_request(gfp_t flags)
static inline struct pending_request *alloc_pending_request(void)
{
- return __alloc_pending_request(SLAB_KERNEL);
+ return __alloc_pending_request(GFP_KERNEL);
}
static void free_pending_request(struct pending_request *req)
@@ -259,7 +259,7 @@ static void host_reset(struct hpsb_host *host)
if (hi != NULL) {
list_for_each_entry(fi, &hi->file_info_list, list) {
if (fi->notification == RAW1394_NOTIFY_ON) {
- req = __alloc_pending_request(SLAB_ATOMIC);
+ req = __alloc_pending_request(GFP_ATOMIC);
if (req != NULL) {
req->file_info = fi;
@@ -306,13 +306,13 @@ static void iso_receive(struct hpsb_host *host, int channel, quadlet_t * data,
if (!(fi->listen_channels & (1ULL << channel)))
continue;
- req = __alloc_pending_request(SLAB_ATOMIC);
+ req = __alloc_pending_request(GFP_ATOMIC);
if (!req)
break;
if (!ibs) {
ibs = kmalloc(sizeof(*ibs) + length,
- SLAB_ATOMIC);
+ GFP_ATOMIC);
if (!ibs) {
kfree(req);
break;
@@ -367,13 +367,13 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
if (!fi->fcp_buffer)
continue;
- req = __alloc_pending_request(SLAB_ATOMIC);
+ req = __alloc_pending_request(GFP_ATOMIC);
if (!req)
break;
if (!ibs) {
ibs = kmalloc(sizeof(*ibs) + length,
- SLAB_ATOMIC);
+ GFP_ATOMIC);
if (!ibs) {
kfree(req);
break;
@@ -593,7 +593,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
switch (req->req.type) {
case RAW1394_REQ_LIST_CARDS:
spin_lock_irqsave(&host_info_lock, flags);
- khl = kmalloc(sizeof(*khl) * host_count, SLAB_ATOMIC);
+ khl = kmalloc(sizeof(*khl) * host_count, GFP_ATOMIC);
if (khl) {
req->req.misc = host_count;
@@ -1045,7 +1045,7 @@ static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
}
if (arm_addr->notification_options & ARM_READ) {
DBGMSG("arm_read -> entering notification-section");
- req = __alloc_pending_request(SLAB_ATOMIC);
+ req = __alloc_pending_request(GFP_ATOMIC);
if (!req) {
DBGMSG("arm_read -> rcode_conflict_error");
spin_unlock_irqrestore(&host_info_lock, irqflags);
@@ -1064,7 +1064,7 @@ static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
sizeof(struct arm_response) +
sizeof(struct arm_request_response);
}
- req->data = kmalloc(size, SLAB_ATOMIC);
+ req->data = kmalloc(size, GFP_ATOMIC);
if (!(req->data)) {
free_pending_request(req);
DBGMSG("arm_read -> rcode_conflict_error");
@@ -1198,7 +1198,7 @@ static int arm_write(struct hpsb_host *host, int nodeid, int destid,
}
if (arm_addr->notification_options & ARM_WRITE) {
DBGMSG("arm_write -> entering notification-section");
- req = __alloc_pending_request(SLAB_ATOMIC);
+ req = __alloc_pending_request(GFP_ATOMIC);
if (!req) {
DBGMSG("arm_write -> rcode_conflict_error");
spin_unlock_irqrestore(&host_info_lock, irqflags);
@@ -1209,7 +1209,7 @@ static int arm_write(struct hpsb_host *host, int nodeid, int destid,
sizeof(struct arm_request) + sizeof(struct arm_response) +
(length) * sizeof(byte_t) +
sizeof(struct arm_request_response);
- req->data = kmalloc(size, SLAB_ATOMIC);
+ req->data = kmalloc(size, GFP_ATOMIC);
if (!(req->data)) {
free_pending_request(req);
DBGMSG("arm_write -> rcode_conflict_error");
@@ -1400,7 +1400,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
if (arm_addr->notification_options & ARM_LOCK) {
byte_t *buf1, *buf2;
DBGMSG("arm_lock -> entering notification-section");
- req = __alloc_pending_request(SLAB_ATOMIC);
+ req = __alloc_pending_request(GFP_ATOMIC);
if (!req) {
DBGMSG("arm_lock -> rcode_conflict_error");
spin_unlock_irqrestore(&host_info_lock, irqflags);
@@ -1408,7 +1408,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
The request may be retried */
}
size = sizeof(struct arm_request) + sizeof(struct arm_response) + 3 * sizeof(*store) + sizeof(struct arm_request_response); /* maximum */
- req->data = kmalloc(size, SLAB_ATOMIC);
+ req->data = kmalloc(size, GFP_ATOMIC);
if (!(req->data)) {
free_pending_request(req);
DBGMSG("arm_lock -> rcode_conflict_error");
@@ -1628,7 +1628,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
if (arm_addr->notification_options & ARM_LOCK) {
byte_t *buf1, *buf2;
DBGMSG("arm_lock64 -> entering notification-section");
- req = __alloc_pending_request(SLAB_ATOMIC);
+ req = __alloc_pending_request(GFP_ATOMIC);
if (!req) {
spin_unlock_irqrestore(&host_info_lock, irqflags);
DBGMSG("arm_lock64 -> rcode_conflict_error");
@@ -1636,7 +1636,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
The request may be retried */
}
size = sizeof(struct arm_request) + sizeof(struct arm_response) + 3 * sizeof(*store) + sizeof(struct arm_request_response); /* maximum */
- req->data = kmalloc(size, SLAB_ATOMIC);
+ req->data = kmalloc(size, GFP_ATOMIC);
if (!(req->data)) {
free_pending_request(req);
spin_unlock_irqrestore(&host_info_lock, irqflags);
@@ -1737,7 +1737,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
return (-EINVAL);
}
/* addr-list-entry for fileinfo */
- addr = kmalloc(sizeof(*addr), SLAB_KERNEL);
+ addr = kmalloc(sizeof(*addr), GFP_KERNEL);
if (!addr) {
req->req.length = 0;
return (-ENOMEM);
@@ -2103,7 +2103,7 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req)
static int get_config_rom(struct file_info *fi, struct pending_request *req)
{
int ret = sizeof(struct raw1394_request);
- quadlet_t *data = kmalloc(req->req.length, SLAB_KERNEL);
+ quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL);
int status;
if (!data)
@@ -2133,7 +2133,7 @@ static int get_config_rom(struct file_info *fi, struct pending_request *req)
static int update_config_rom(struct file_info *fi, struct pending_request *req)
{
int ret = sizeof(struct raw1394_request);
- quadlet_t *data = kmalloc(req->req.length, SLAB_KERNEL);
+ quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL);
if (!data)
return -ENOMEM;
if (copy_from_user(data, int2ptr(req->req.sendb), req->req.length)) {
@@ -2443,7 +2443,7 @@ static void queue_rawiso_event(struct file_info *fi)
/* only one ISO activity event may be in the queue */
if (!__rawiso_event_in_queue(fi)) {
struct pending_request *req =
- __alloc_pending_request(SLAB_ATOMIC);
+ __alloc_pending_request(GFP_ATOMIC);
if (req) {
req->file_info = fi;
@@ -2779,7 +2779,7 @@ static int raw1394_open(struct inode *inode, struct file *file)
{
struct file_info *fi;
- fi = kzalloc(sizeof(*fi), SLAB_KERNEL);
+ fi = kzalloc(sizeof(*fi), GFP_KERNEL);
if (!fi)
return -ENOMEM;
diff --git a/drivers/infiniband/hw/amso1100/c2_vq.c b/drivers/infiniband/hw/amso1100/c2_vq.c
index 40caeb5f41b..36620a22413 100644
--- a/drivers/infiniband/hw/amso1100/c2_vq.c
+++ b/drivers/infiniband/hw/amso1100/c2_vq.c
@@ -164,7 +164,7 @@ void vq_req_put(struct c2_dev *c2dev, struct c2_vq_req *r)
*/
void *vq_repbuf_alloc(struct c2_dev *c2dev)
{
- return kmem_cache_alloc(c2dev->host_msg_cache, SLAB_ATOMIC);
+ return kmem_cache_alloc(c2dev->host_msg_cache, GFP_ATOMIC);
}
/*
diff --git a/drivers/infiniband/hw/ehca/ehca_av.c b/drivers/infiniband/hw/ehca/ehca_av.c
index 214e2fdddee..0d6e2c4bb24 100644
--- a/drivers/infiniband/hw/ehca/ehca_av.c
+++ b/drivers/infiniband/hw/ehca/ehca_av.c
@@ -57,7 +57,7 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
struct ehca_shca *shca = container_of(pd->device, struct ehca_shca,
ib_device);
- av = kmem_cache_alloc(av_cache, SLAB_KERNEL);
+ av = kmem_cache_alloc(av_cache, GFP_KERNEL);
if (!av) {
ehca_err(pd->device, "Out of memory pd=%p ah_attr=%p",
pd, ah_attr);
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index 458fe19648a..93995b658d9 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -134,7 +134,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe,
if (cqe >= 0xFFFFFFFF - 64 - additional_cqe)
return ERR_PTR(-EINVAL);
- my_cq = kmem_cache_alloc(cq_cache, SLAB_KERNEL);
+ my_cq = kmem_cache_alloc(cq_cache, GFP_KERNEL);
if (!my_cq) {
ehca_err(device, "Out of memory for ehca_cq struct device=%p",
device);
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 3d1c1c53503..cc47e4c13a1 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -108,7 +108,7 @@ static struct kmem_cache *ctblk_cache = NULL;
void *ehca_alloc_fw_ctrlblock(void)
{
- void *ret = kmem_cache_zalloc(ctblk_cache, SLAB_KERNEL);
+ void *ret = kmem_cache_zalloc(ctblk_cache, GFP_KERNEL);
if (!ret)
ehca_gen_err("Out of memory for ctblk");
return ret;
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index abce676c0ae..0a5e2214cc5 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -53,7 +53,7 @@ static struct ehca_mr *ehca_mr_new(void)
{
struct ehca_mr *me;
- me = kmem_cache_alloc(mr_cache, SLAB_KERNEL);
+ me = kmem_cache_alloc(mr_cache, GFP_KERNEL);
if (me) {
memset(me, 0, sizeof(struct ehca_mr));
spin_lock_init(&me->mrlock);
@@ -72,7 +72,7 @@ static struct ehca_mw *ehca_mw_new(void)
{
struct ehca_mw *me;
- me = kmem_cache_alloc(mw_cache, SLAB_KERNEL);
+ me = kmem_cache_alloc(mw_cache, GFP_KERNEL);
if (me) {
memset(me, 0, sizeof(struct ehca_mw));
spin_lock_init(&me->mwlock);
diff --git a/drivers/infiniband/hw/ehca/ehca_pd.c b/drivers/infiniband/hw/ehca/ehca_pd.c
index 2c3cdc6f7b3..d5345e5b3cd 100644
--- a/drivers/infiniband/hw/ehca/ehca_pd.c
+++ b/drivers/infiniband/hw/ehca/ehca_pd.c
@@ -50,7 +50,7 @@ struct ib_pd *ehca_alloc_pd(struct ib_device *device,
{
struct ehca_pd *pd;
- pd = kmem_cache_alloc(pd_cache, SLAB_KERNEL);
+ pd = kmem_cache_alloc(pd_cache, GFP_KERNEL);
if (!pd) {
ehca_err(device, "device=%p context=%p out of memory",
device, context);
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 8682aa50c70..c6c9cef203e 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -450,7 +450,7 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd,
if (pd->uobject && udata)
context = pd->uobject->context;
- my_qp = kmem_cache_alloc(qp_cache, SLAB_KERNEL);
+ my_qp = kmem_cache_alloc(qp_cache, GFP_KERNEL);
if (!my_qp) {
ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd);
return ERR_PTR(-ENOMEM);
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index 57cdc1bc5f5..27caf3b0648 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -189,7 +189,7 @@ int mthca_create_ah(struct mthca_dev *dev,
on_hca_fail:
if (ah->type == MTHCA_AH_PCI_POOL) {
ah->av = pci_pool_alloc(dev->av_table.pool,
- SLAB_ATOMIC, &ah->avdma);
+ GFP_ATOMIC, &ah->avdma);
if (!ah->av)
return -ENOMEM;
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index a0af97efe6a..79dfb4b25c9 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -23,6 +23,7 @@
#include <linux/kthread.h>
#include <linux/sched.h> /* HZ */
#include <linux/mutex.h>
+#include <linux/freezer.h>
/*#include <asm/io.h>*/
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c
index ab4da79ee56..31d5a13bfd6 100644
--- a/drivers/input/misc/hp_sdc_rtc.c
+++ b/drivers/input/misc/hp_sdc_rtc.c
@@ -695,7 +695,9 @@ static int __init hp_sdc_rtc_init(void)
if ((ret = hp_sdc_request_timer_irq(&hp_sdc_rtc_isr)))
return ret;
- misc_register(&hp_sdc_rtc_dev);
+ if (misc_register(&hp_sdc_rtc_dev) != 0)
+ printk(KERN_INFO "Could not register misc. dev for i8042 rtc\n");
+
create_proc_read_entry ("driver/rtc", 0, NULL,
hp_sdc_rtc_read_proc, NULL);
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 211943f85cb..5f1d4032fd5 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -35,6 +35,7 @@
#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
+#include <linux/freezer.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Serio abstraction core");
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index f56d6a0f062..0517c7387d6 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -189,7 +189,7 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
{
struct spi_device *spi = to_spi_device(dev);
struct ads7846 *ts = dev_get_drvdata(dev);
- struct ser_req *req = kzalloc(sizeof *req, SLAB_KERNEL);
+ struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL);
int status;
int sample;
int i;
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 0c937325a1b..63b629b1cdb 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -572,7 +572,7 @@ static int atread_submit(struct cardstate *cs, int timeout)
ucs->rcvbuf, ucs->rcvbuf_size,
read_ctrl_callback, cs->inbuf);
- if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) {
+ if ((ret = usb_submit_urb(ucs->urb_cmd_in, GFP_ATOMIC)) != 0) {
update_basstate(ucs, 0, BS_ATRDPEND);
dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n",
get_usb_rcmsg(ret));
@@ -747,7 +747,7 @@ static void read_int_callback(struct urb *urb)
check_pending(ucs);
resubmit:
- rc = usb_submit_urb(urb, SLAB_ATOMIC);
+ rc = usb_submit_urb(urb, GFP_ATOMIC);
if (unlikely(rc != 0 && rc != -ENODEV)) {
dev_err(cs->dev, "could not resubmit interrupt URB: %s\n",
get_usb_rcmsg(rc));
@@ -807,7 +807,7 @@ static void read_iso_callback(struct urb *urb)
urb->number_of_packets = BAS_NUMFRAMES;
gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit",
__func__);
- rc = usb_submit_urb(urb, SLAB_ATOMIC);
+ rc = usb_submit_urb(urb, GFP_ATOMIC);
if (unlikely(rc != 0 && rc != -ENODEV)) {
dev_err(bcs->cs->dev,
"could not resubmit isochronous read "
@@ -900,7 +900,7 @@ static int starturbs(struct bc_state *bcs)
}
dump_urb(DEBUG_ISO, "Initial isoc read", urb);
- if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0)
+ if ((rc = usb_submit_urb(urb, GFP_ATOMIC)) != 0)
goto error;
}
@@ -935,7 +935,7 @@ static int starturbs(struct bc_state *bcs)
/* submit two URBs, keep third one */
for (k = 0; k < 2; ++k) {
dump_urb(DEBUG_ISO, "Initial isoc write", urb);
- rc = usb_submit_urb(ubc->isoouturbs[k].urb, SLAB_ATOMIC);
+ rc = usb_submit_urb(ubc->isoouturbs[k].urb, GFP_ATOMIC);
if (rc != 0)
goto error;
}
@@ -1042,7 +1042,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
return 0; /* no data to send */
urb->number_of_packets = nframe;
- rc = usb_submit_urb(urb, SLAB_ATOMIC);
+ rc = usb_submit_urb(urb, GFP_ATOMIC);
if (unlikely(rc)) {
if (rc == -ENODEV)
/* device removed - give up silently */
@@ -1341,7 +1341,7 @@ static void read_iso_tasklet(unsigned long data)
urb->dev = bcs->cs->hw.bas->udev;
urb->transfer_flags = URB_ISO_ASAP;
urb->number_of_packets = BAS_NUMFRAMES;
- rc = usb_submit_urb(urb, SLAB_ATOMIC);
+ rc = usb_submit_urb(urb, GFP_ATOMIC);
if (unlikely(rc != 0 && rc != -ENODEV)) {
dev_err(cs->dev,
"could not resubmit isochronous read URB: %s\n",
@@ -1458,7 +1458,7 @@ static void write_ctrl_callback(struct urb *urb)
ucs->retry_ctrl);
/* urb->dev is clobbered by USB subsystem */
urb->dev = ucs->udev;
- rc = usb_submit_urb(urb, SLAB_ATOMIC);
+ rc = usb_submit_urb(urb, GFP_ATOMIC);
if (unlikely(rc)) {
dev_err(&ucs->interface->dev,
"could not resubmit request 0x%02x: %s\n",
@@ -1517,7 +1517,7 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout)
(unsigned char*) &ucs->dr_ctrl, NULL, 0,
write_ctrl_callback, ucs);
ucs->retry_ctrl = 0;
- ret = usb_submit_urb(ucs->urb_ctrl, SLAB_ATOMIC);
+ ret = usb_submit_urb(ucs->urb_ctrl, GFP_ATOMIC);
if (unlikely(ret)) {
dev_err(bcs->cs->dev, "could not submit request 0x%02x: %s\n",
req, get_usb_rcmsg(ret));
@@ -1763,7 +1763,7 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len)
usb_sndctrlpipe(ucs->udev, 0),
(unsigned char*) &ucs->dr_cmd_out, buf, len,
write_command_callback, cs);
- rc = usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC);
+ rc = usb_submit_urb(ucs->urb_cmd_out, GFP_ATOMIC);
if (unlikely(rc)) {
update_basstate(ucs, 0, BS_ATWRPEND);
dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n",
@@ -2218,21 +2218,21 @@ static int gigaset_probe(struct usb_interface *interface,
* - three for the different uses of the default control pipe
* - three for each isochronous pipe
*/
- if (!(ucs->urb_int_in = usb_alloc_urb(0, SLAB_KERNEL)) ||
- !(ucs->urb_cmd_in = usb_alloc_urb(0, SLAB_KERNEL)) ||
- !(ucs->urb_cmd_out = usb_alloc_urb(0, SLAB_KERNEL)) ||
- !(ucs->urb_ctrl = usb_alloc_urb(0, SLAB_KERNEL)))
+ if (!(ucs->urb_int_in = usb_alloc_urb(0, GFP_KERNEL)) ||
+ !(ucs->urb_cmd_in = usb_alloc_urb(0, GFP_KERNEL)) ||
+ !(ucs->urb_cmd_out = usb_alloc_urb(0, GFP_KERNEL)) ||
+ !(ucs->urb_ctrl = usb_alloc_urb(0, GFP_KERNEL)))
goto allocerr;
for (j = 0; j < 2; ++j) {
ubc = cs->bcs[j].hw.bas;
for (i = 0; i < BAS_OUTURBS; ++i)
if (!(ubc->isoouturbs[i].urb =
- usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL)))
+ usb_alloc_urb(BAS_NUMFRAMES, GFP_KERNEL)))
goto allocerr;
for (i = 0; i < BAS_INURBS; ++i)
if (!(ubc->isoinurbs[i] =
- usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL)))
+ usb_alloc_urb(BAS_NUMFRAMES, GFP_KERNEL)))
goto allocerr;
}
@@ -2246,7 +2246,7 @@ static int gigaset_probe(struct usb_interface *interface,
(endpoint->bEndpointAddress) & 0x0f),
ucs->int_in_buf, 3, read_int_callback, cs,
endpoint->bInterval);
- if ((rc = usb_submit_urb(ucs->urb_int_in, SLAB_KERNEL)) != 0) {
+ if ((rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL)) != 0) {
dev_err(cs->dev, "could not submit interrupt URB: %s\n",
get_usb_rcmsg(rc));
goto error;
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index 5ebf49ac9b2..04f2ad7ba8b 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -410,7 +410,7 @@ static void gigaset_read_int_callback(struct urb *urb)
if (resubmit) {
spin_lock_irqsave(&cs->lock, flags);
- r = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV;
+ r = cs->connected ? usb_submit_urb(urb, GFP_ATOMIC) : -ENODEV;
spin_unlock_irqrestore(&cs->lock, flags);
if (r)
dev_err(cs->dev, "error %d when resubmitting urb.\n",
@@ -486,7 +486,7 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
atomic_set(&ucs->busy, 1);
spin_lock_irqsave(&cs->lock, flags);
- status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC) : -ENODEV;
+ status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) : -ENODEV;
spin_unlock_irqrestore(&cs->lock, flags);
if (status) {
@@ -664,7 +664,7 @@ static int write_modem(struct cardstate *cs)
ucs->bulk_out_endpointAddr & 0x0f),
ucs->bulk_out_buffer, count,
gigaset_write_bulk_callback, cs);
- ret = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC);
+ ret = usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC);
} else {
ret = -ENODEV;
}
@@ -763,7 +763,7 @@ static int gigaset_probe(struct usb_interface *interface,
goto error;
}
- ucs->bulk_out_urb = usb_alloc_urb(0, SLAB_KERNEL);
+ ucs->bulk_out_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!ucs->bulk_out_urb) {
dev_err(cs->dev, "Couldn't allocate bulk_out_urb\n");
retval = -ENOMEM;
@@ -774,7 +774,7 @@ static int gigaset_probe(struct usb_interface *interface,
atomic_set(&ucs->busy, 0);
- ucs->read_urb = usb_alloc_urb(0, SLAB_KERNEL);
+ ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!ucs->read_urb) {
dev_err(cs->dev, "No free urbs available\n");
retval = -ENOMEM;
@@ -797,7 +797,7 @@ static int gigaset_probe(struct usb_interface *interface,
gigaset_read_int_callback,
cs->inbuf + 0, endpoint->bInterval);
- retval = usb_submit_urb(ucs->read_urb, SLAB_KERNEL);
+ retval = usb_submit_urb(ucs->read_urb, GFP_KERNEL);
if (retval) {
dev_err(cs->dev, "Could not submit URB (error %d)\n", -retval);
goto error;
diff --git a/drivers/isdn/hisax/isdnhdlc.h b/drivers/isdn/hisax/isdnhdlc.h
index 269315988dc..5655b5f9c48 100644
--- a/drivers/isdn/hisax/isdnhdlc.h
+++ b/drivers/isdn/hisax/isdnhdlc.h
@@ -41,10 +41,10 @@ struct isdnhdlc_vars {
unsigned char shift_reg;
unsigned char ffvalue;
- int data_received:1; // set if transferring data
- int dchannel:1; // set if D channel (send idle instead of flags)
- int do_adapt56:1; // set if 56K adaptation
- int do_closing:1; // set if in closing phase (need to send CRC + flag
+ unsigned int data_received:1; // set if transferring data
+ unsigned int dchannel:1; // set if D channel (send idle instead of flags)
+ unsigned int do_adapt56:1; // set if 56K adaptation
+ unsigned int do_closing:1; // set if in closing phase (need to send CRC + flag
};
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 9c39b98d5a5..176142c6149 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -76,6 +76,12 @@ config LEDS_NET48XX
This option enables support for the Soekris net4801 and net4826 error
LED.
+config LEDS_WRAP
+ tristate "LED Support for the WRAP series LEDs"
+ depends on LEDS_CLASS && SCx200_GPIO
+ help
+ This option enables support for the PCEngines WRAP programmable LEDs.
+
comment "LED Triggers"
config LEDS_TRIGGERS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 6aa2aed7539..500de3dc962 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o
obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o
obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
+obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o
# LED Triggers
obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
diff --git a/drivers/leds/leds-wrap.c b/drivers/leds/leds-wrap.c
new file mode 100644
index 00000000000..27fb2d8e991
--- /dev/null
+++ b/drivers/leds/leds-wrap.c
@@ -0,0 +1,142 @@
+/*
+ * LEDs driver for PCEngines WRAP
+ *
+ * Copyright (C) 2006 Kristian Kielhofner <kris@krisk.org>
+ *
+ * Based on leds-net48xx.c
+ *
+ * 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/platform_device.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <asm/io.h>
+#include <linux/scx200_gpio.h>
+
+#define DRVNAME "wrap-led"
+#define WRAP_ERROR_LED_GPIO 3
+#define WRAP_EXTRA_LED_GPIO 18
+
+static struct platform_device *pdev;
+
+static void wrap_error_led_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ if (value)
+ scx200_gpio_set_low(WRAP_ERROR_LED_GPIO);
+ else
+ scx200_gpio_set_high(WRAP_ERROR_LED_GPIO);
+}
+
+static void wrap_extra_led_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ if (value)
+ scx200_gpio_set_low(WRAP_EXTRA_LED_GPIO);
+ else
+ scx200_gpio_set_high(WRAP_EXTRA_LED_GPIO);
+}
+
+static struct led_classdev wrap_error_led = {
+ .name = "wrap:error",
+ .brightness_set = wrap_error_led_set,
+};
+
+static struct led_classdev wrap_extra_led = {
+ .name = "wrap:extra",
+ .brightness_set = wrap_extra_led_set,
+};
+
+#ifdef CONFIG_PM
+static int wrap_led_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ led_classdev_suspend(&wrap_error_led);
+ led_classdev_suspend(&wrap_extra_led);
+ return 0;
+}
+
+static int wrap_led_resume(struct platform_device *dev)
+{
+ led_classdev_resume(&wrap_error_led);
+ led_classdev_resume(&wrap_extra_led);
+ return 0;
+}
+#else
+#define wrap_led_suspend NULL
+#define wrap_led_resume NULL
+#endif
+
+static int wrap_led_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = led_classdev_register(&pdev->dev, &wrap_error_led);
+ if (ret == 0) {
+ ret = led_classdev_register(&pdev->dev, &wrap_extra_led);
+ if (ret < 0)
+ led_classdev_unregister(&wrap_error_led);
+ }
+ return ret;
+}
+
+static int wrap_led_remove(struct platform_device *pdev)
+{
+ led_classdev_unregister(&wrap_error_led);
+ led_classdev_unregister(&wrap_extra_led);
+ return 0;
+}
+
+static struct platform_driver wrap_led_driver = {
+ .probe = wrap_led_probe,
+ .remove = wrap_led_remove,
+ .suspend = wrap_led_suspend,
+ .resume = wrap_led_resume,
+ .driver = {
+ .name = DRVNAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init wrap_led_init(void)
+{
+ int ret;
+
+ if (!scx200_gpio_present()) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ ret = platform_driver_register(&wrap_led_driver);
+ if (ret < 0)
+ goto out;
+
+ pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
+ platform_driver_unregister(&wrap_led_driver);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void __exit wrap_led_exit(void)
+{
+ platform_device_unregister(pdev);
+ platform_driver_unregister(&wrap_led_driver);
+}
+
+module_init(wrap_led_init);
+module_exit(wrap_led_exit);
+
+MODULE_AUTHOR("Kristian Kielhofner <kris@krisk.org>");
+MODULE_DESCRIPTION("PCEngines WRAP LED driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/macintosh/apm_emu.c b/drivers/macintosh/apm_emu.c
index 1293876a2eb..8862a83b8d8 100644
--- a/drivers/macintosh/apm_emu.c
+++ b/drivers/macintosh/apm_emu.c
@@ -529,7 +529,8 @@ static int __init apm_emu_init(void)
if (apm_proc)
apm_proc->owner = THIS_MODULE;
- misc_register(&apm_device);
+ if (misc_register(&apm_device) != 0)
+ printk(KERN_INFO "Could not create misc. device for apm\n");
pmu_register_sleep_notifier(&apm_sleep_notifier);
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 13b953ae8eb..3d3bf1643e7 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -24,6 +24,7 @@
#include <linux/suspend.h>
#include <linux/kthread.h>
#include <linux/moduleparam.h>
+#include <linux/freezer.h>
#include <asm/prom.h>
#include <asm/machdep.h>
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index e63ea1c1f3c..c8558d4ed50 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -42,7 +42,7 @@
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/sysdev.h>
-#include <linux/suspend.h>
+#include <linux/freezer.h>
#include <linux/syscalls.h>
#include <linux/cpu.h>
#include <asm/prom.h>
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index ab3faa702d5..e947af982f9 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -34,6 +34,7 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
+#include <linux/freezer.h>
#include <asm/prom.h>
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 0d8686505e5..a1086ee8ccc 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -105,7 +105,7 @@ struct crypt_config {
#define MIN_POOL_PAGES 32
#define MIN_BIO_PAGES 8
-static kmem_cache_t *_crypt_io_pool;
+static struct kmem_cache *_crypt_io_pool;
/*
* Different IV generation algorithms:
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index e77ee6fd104..cf8bf052138 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -101,7 +101,7 @@ typedef int (*action_fn) (struct pgpath *pgpath);
#define MIN_IOS 256 /* Mempool size */
-static kmem_cache_t *_mpio_cache;
+static struct kmem_cache *_mpio_cache;
struct workqueue_struct *kmultipathd;
static void process_queued_ios(struct work_struct *work);
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 91c7aa1fed0..b0ce2ce8227 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -88,8 +88,8 @@ struct pending_exception {
* Hash table mapping origin volumes to lists of snapshots and
* a lock to protect it
*/
-static kmem_cache_t *exception_cache;
-static kmem_cache_t *pending_cache;
+static struct kmem_cache *exception_cache;
+static struct kmem_cache *pending_cache;
static mempool_t *pending_pool;
/*
@@ -228,7 +228,7 @@ static int init_exception_table(struct exception_table *et, uint32_t size)
return 0;
}
-static void exit_exception_table(struct exception_table *et, kmem_cache_t *mem)
+static void exit_exception_table(struct exception_table *et, struct kmem_cache *mem)
{
struct list_head *slot;
struct exception *ex, *next;
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index fc4f743f3b5..7ec1b112a6d 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -121,8 +121,8 @@ struct mapped_device {
};
#define MIN_IOS 256
-static kmem_cache_t *_io_cache;
-static kmem_cache_t *_tio_cache;
+static struct kmem_cache *_io_cache;
+static struct kmem_cache *_tio_cache;
static int __init local_init(void)
{
diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c
index b3c01496c73..b46f6c575f7 100644
--- a/drivers/md/kcopyd.c
+++ b/drivers/md/kcopyd.c
@@ -203,7 +203,7 @@ struct kcopyd_job {
/* FIXME: this should scale with the number of pages */
#define MIN_JOBS 512
-static kmem_cache_t *_job_cache;
+static struct kmem_cache *_job_cache;
static mempool_t *_job_pool;
/*
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 8cbf9c9df1c..6c4345bde07 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -39,10 +39,10 @@
#include <linux/raid/bitmap.h>
#include <linux/sysctl.h>
#include <linux/buffer_head.h> /* for invalidate_bdev */
-#include <linux/suspend.h>
#include <linux/poll.h>
#include <linux/mutex.h>
#include <linux/ctype.h>
+#include <linux/freezer.h>
#include <linux/init.h>
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 69c3e201fa3..52914d5cec7 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -348,7 +348,7 @@ static int grow_one_stripe(raid5_conf_t *conf)
static int grow_stripes(raid5_conf_t *conf, int num)
{
- kmem_cache_t *sc;
+ struct kmem_cache *sc;
int devs = conf->raid_disks;
sprintf(conf->cache_name[0], "raid5/%s", mdname(conf->mddev));
@@ -397,7 +397,7 @@ static int resize_stripes(raid5_conf_t *conf, int newsize)
LIST_HEAD(newstripes);
struct disk_info *ndisks;
int err = 0;
- kmem_cache_t *sc;
+ struct kmem_cache *sc;
int i;
if (newsize <= conf->pool_size)
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 206c13e47a0..9123147e376 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -287,7 +287,7 @@ static int cinergyt2_alloc_stream_urbs (struct cinergyt2 *cinergyt2)
int i;
cinergyt2->streambuf = usb_buffer_alloc(cinergyt2->udev, STREAM_URB_COUNT*STREAM_BUF_SIZE,
- SLAB_KERNEL, &cinergyt2->streambuf_dmahandle);
+ GFP_KERNEL, &cinergyt2->streambuf_dmahandle);
if (!cinergyt2->streambuf) {
dprintk(1, "failed to alloc consistent stream memory area, bailing out!\n");
return -ENOMEM;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index a2ab2eebfc6..e85972222ab 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -34,7 +34,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/list.h>
-#include <linux/suspend.h>
+#include <linux/freezer.h>
#include <linux/jiffies.h>
#include <asm/processor.h>
diff --git a/drivers/media/dvb/dvb-usb/usb-urb.c b/drivers/media/dvb/dvb-usb/usb-urb.c
index 78035ee824c..397f51a7b2a 100644
--- a/drivers/media/dvb/dvb-usb/usb-urb.c
+++ b/drivers/media/dvb/dvb-usb/usb-urb.c
@@ -116,7 +116,7 @@ static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num,
for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
deb_mem("allocating buffer %d\n",stream->buf_num);
if (( stream->buf_list[stream->buf_num] =
- usb_buffer_alloc(stream->udev, size, SLAB_ATOMIC,
+ usb_buffer_alloc(stream->udev, size, GFP_ATOMIC,
&stream->dma_addr[stream->buf_num]) ) == NULL) {
deb_mem("not enough memory for urb-buffer allocation.\n");
usb_free_stream_buffers(stream);
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
index f3bc82e44a2..1aeacb1c4af 100644
--- a/drivers/media/dvb/frontends/l64781.c
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -36,7 +36,7 @@ struct l64781_state {
struct dvb_frontend frontend;
/* private demodulator data */
- int first:1;
+ unsigned int first:1;
};
#define dprintk(args...) \
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 8135f3e76ae..10b121ada83 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1244,7 +1244,7 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec)
return -ENOMEM;
}
dec->irq_buffer = usb_buffer_alloc(dec->udev,IRQ_PACKET_SIZE,
- SLAB_ATOMIC, &dec->irq_dma_handle);
+ GFP_ATOMIC, &dec->irq_dma_handle);
if(!dec->irq_buffer) {
return -ENOMEM;
}
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 6d96b17a7f8..920b63f8cf0 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -173,38 +173,6 @@ config RADIO_MAESTRO
To compile this driver as a module, choose M here: the
module will be called radio-maestro.
-config RADIO_MIROPCM20
- tristate "miroSOUND PCM20 radio"
- depends on ISA && VIDEO_V4L1 && SOUND_ACI_MIXER
- ---help---
- Choose Y here if you have this FM radio card. You also need to say Y
- to "ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20 radio)" (in "Sound")
- for this to work.
-
- In order to control your radio card, you will need to use programs
- that are compatible with the Video For Linux API. Information on
- this API and pointers to "v4l" programs may be found at
- <file:Documentation/video4linux/API.html>.
-
- To compile this driver as a module, choose M here: the
- module will be called miropcm20.
-
-config RADIO_MIROPCM20_RDS
- tristate "miroSOUND PCM20 radio RDS user interface (EXPERIMENTAL)"
- depends on RADIO_MIROPCM20 && EXPERIMENTAL
- ---help---
- Choose Y here if you want to see RDS/RBDS information like
- RadioText, Programme Service name, Clock Time and date, Programme
- Type and Traffic Announcement/Programme identification.
-
- It's not possible to read the raw RDS packets from the device, so
- the driver cant provide an V4L interface for this. But the
- availability of RDS is reported over V4L by the basic driver
- already. Here RDS can be read from files in /dev/v4l/rds.
-
- To compile this driver as a module, choose M here: the
- module will be called miropcm20-rds.
-
config RADIO_SF16FMI
tristate "SF16FMI Radio"
depends on ISA && VIDEO_V4L2
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index cf43df3fe70..e1b56dc13c3 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -56,7 +56,7 @@
#include <media/tvaudio.h>
#include <media/msp3400.h>
#include <linux/kthread.h>
-#include <linux/suspend.h>
+#include <linux/freezer.h>
#include "msp3400-driver.h"
/* ---------------------------------------------------------------------- */
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index fcaef4bf828..d506dfaa45a 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -29,6 +29,7 @@
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/kthread.h>
+#include <linux/freezer.h>
#include <media/tvaudio.h>
#include <media/v4l2-common.h>
diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c
index f53edf1923b..fcc5467e763 100644
--- a/drivers/media/video/video-buf-dvb.c
+++ b/drivers/media/video/video-buf-dvb.c
@@ -20,7 +20,7 @@
#include <linux/fs.h>
#include <linux/kthread.h>
#include <linux/file.h>
-#include <linux/suspend.h>
+#include <linux/freezer.h>
#include <media/video-buf.h>
#include <media/video-buf-dvb.h>
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 3c8dc72dc8e..9986de5cb3d 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -36,6 +36,7 @@
#include <media/v4l2-common.h>
#include <linux/kthread.h>
#include <linux/highmem.h>
+#include <linux/freezer.h>
/* Wake up at about 30 fps */
#define WAKE_NUMERATOR 30
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 051b7c5b8f0..6e068cf1049 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -347,7 +347,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
* @irq: irq number (not used)
* @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
@@ -387,14 +387,16 @@ mpt_interrupt(int irq, void *bus_id)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * mpt_base_reply - MPT base driver's callback routine; all base driver
- * "internal" request/reply processing is routed here.
- * Currently used for EventNotification and EventAck handling.
+/**
+ * mpt_base_reply - MPT base driver's callback routine
* @ioc: Pointer to MPT_ADAPTER structure
* @mf: Pointer to original MPT request frame
* @reply: Pointer to MPT reply frame (NULL if TurboReply)
*
+ * MPT base driver's callback routine; all base driver
+ * "internal" request/reply processing is routed here.
+ * Currently used for EventNotification and EventAck handling.
+ *
* Returns 1 indicating original alloc'd request frame ptr
* should be freed, or 0 if it shouldn't.
*/
@@ -530,7 +532,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
* @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
*
* This routine is called by a protocol-specific driver (SCSI host,
- * LAN, SCSI target) to register it's reply callback routine. Each
+ * LAN, SCSI target) to register its reply callback routine. Each
* protocol-specific driver must do this before it will be able to
* use any IOC resources, such as obtaining request frames.
*
@@ -572,7 +574,7 @@ mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
* mpt_deregister - Deregister a protocol drivers resources.
* @cb_idx: previously registered callback handle
*
- * Each protocol-specific driver should call this routine when it's
+ * Each protocol-specific driver should call this routine when its
* module is unloaded.
*/
void
@@ -617,7 +619,7 @@ mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
*
* Each protocol-specific driver should call this routine
* when it does not (or can no longer) handle events,
- * or when it's module is unloaded.
+ * or when its module is unloaded.
*/
void
mpt_event_deregister(int cb_idx)
@@ -656,7 +658,7 @@ mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
*
* Each protocol-specific driver should call this routine
* when it does not (or can no longer) handle IOC reset handling,
- * or when it's module is unloaded.
+ * or when its module is unloaded.
*/
void
mpt_reset_deregister(int cb_idx)
@@ -670,6 +672,8 @@ mpt_reset_deregister(int cb_idx)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_device_driver_register - Register device driver hooks
+ * @dd_cbfunc: driver callbacks struct
+ * @cb_idx: MPT protocol driver index
*/
int
mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
@@ -696,6 +700,7 @@ mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_device_driver_deregister - DeRegister device driver hooks
+ * @cb_idx: MPT protocol driver index
*/
void
mpt_device_driver_deregister(int cb_idx)
@@ -887,8 +892,7 @@ mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mpt_send_handshake_request - Send MPT request via doorbell
- * handshake method.
+ * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
* @handle: Handle of registered MPT protocol driver
* @ioc: Pointer to MPT adapter structure
* @reqBytes: Size of the request in bytes
@@ -981,10 +985,13 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req,
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mpt_host_page_access_control - provides mechanism for the host
- * driver to control the IOC's Host Page Buffer access.
+ * mpt_host_page_access_control - control the IOC's Host Page Buffer access
* @ioc: Pointer to MPT adapter structure
* @access_control_value: define bits below
+ * @sleepFlag: Specifies whether the process can sleep
+ *
+ * Provides mechanism for the host driver to control the IOC's
+ * Host Page Buffer access.
*
* Access Control Value - bits[15:12]
* 0h Reserved
@@ -1022,10 +1029,10 @@ mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int slee
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_host_page_alloc - allocate system memory for the fw
- * If we already allocated memory in past, then resend the same pointer.
- * ioc@: Pointer to pointer to IOC adapter
- * ioc_init@: Pointer to ioc init config page
+ * @ioc: Pointer to pointer to IOC adapter
+ * @ioc_init: Pointer to ioc init config page
*
+ * If we already allocated memory in past, then resend the same pointer.
* Returns 0 for success, non-zero for failure.
*/
static int
@@ -1091,12 +1098,15 @@ return 0;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
- * the associated MPT adapter structure.
+ * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
* @iocid: IOC unique identifier (integer)
* @iocpp: Pointer to pointer to IOC adapter
*
- * Returns iocid and sets iocpp.
+ * Given a unique IOC identifier, set pointer to the associated MPT
+ * adapter structure.
+ *
+ * Returns iocid and sets iocpp if iocid is found.
+ * Returns -1 if iocid is not found.
*/
int
mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
@@ -1115,9 +1125,10 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_attach - Install a PCI intelligent MPT adapter.
* @pdev: Pointer to pci_dev structure
+ * @id: PCI device ID information
*
* This routine performs all the steps necessary to bring the IOC of
* a MPT adapter to a OPERATIONAL state. This includes registering
@@ -1417,10 +1428,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_detach - Remove a PCI intelligent MPT adapter.
* @pdev: Pointer to pci_dev structure
- *
*/
void
@@ -1466,10 +1476,10 @@ mpt_detach(struct pci_dev *pdev)
*/
#ifdef CONFIG_PM
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_suspend - Fusion MPT base driver suspend routine.
- *
- *
+ * @pdev: Pointer to pci_dev structure
+ * @state: new state to enter
*/
int
mpt_suspend(struct pci_dev *pdev, pm_message_t state)
@@ -1505,10 +1515,9 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_resume - Fusion MPT base driver resume routine.
- *
- *
+ * @pdev: Pointer to pci_dev structure
*/
int
mpt_resume(struct pci_dev *pdev)
@@ -1566,7 +1575,7 @@ mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_do_ioc_recovery - Initialize or recover MPT adapter.
* @ioc: Pointer to MPT adapter structure
* @reason: Event word / reason
@@ -1892,13 +1901,15 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * mpt_detect_bound_ports - Search for PCI bus/dev_function
- * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
- * 929X, 1030 or 1035.
+/**
+ * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
* @ioc: Pointer to MPT adapter structure
* @pdev: Pointer to (struct pci_dev) structure
*
+ * Search for PCI bus/dev_function which matches
+ * PCI bus/dev_function (+/-1) for newly discovered 929,
+ * 929X, 1030 or 1035.
+ *
* If match on PCI dev_function +/-1 is found, bind the two MPT adapters
* using alt_ioc pointer fields in their %MPT_ADAPTER structures.
*/
@@ -1945,9 +1956,9 @@ mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_adapter_disable - Disable misbehaving MPT adapter.
- * @this: Pointer to MPT adapter structure
+ * @ioc: Pointer to MPT adapter structure
*/
static void
mpt_adapter_disable(MPT_ADAPTER *ioc)
@@ -2046,9 +2057,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * mpt_adapter_dispose - Free all resources associated with a MPT
- * adapter.
+/**
+ * mpt_adapter_dispose - Free all resources associated with an MPT adapter
* @ioc: Pointer to MPT adapter structure
*
* This routine unregisters h/w resources and frees all alloc'd memory
@@ -2099,8 +2109,8 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * MptDisplayIocCapabilities - Disply IOC's capacilities.
+/**
+ * MptDisplayIocCapabilities - Disply IOC's capabilities.
* @ioc: Pointer to MPT adapter structure
*/
static void
@@ -2142,7 +2152,7 @@ MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* MakeIocReady - Get IOC to a READY state, using KickStart if needed.
* @ioc: Pointer to MPT_ADAPTER structure
* @force: Force hard KickStart of IOC
@@ -2279,7 +2289,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_GetIocState - Get the current state of a MPT adapter.
* @ioc: Pointer to MPT_ADAPTER structure
* @cooked: Request raw or cooked IOC state
@@ -2304,7 +2314,7 @@ mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* GetIocFacts - Send IOCFacts request to MPT adapter.
* @ioc: Pointer to MPT_ADAPTER structure
* @sleepFlag: Specifies whether the process can sleep
@@ -2478,7 +2488,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* GetPortFacts - Send PortFacts request to MPT adapter.
* @ioc: Pointer to MPT_ADAPTER structure
* @portnum: Port number
@@ -2545,7 +2555,7 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* SendIocInit - Send IOCInit request to MPT adapter.
* @ioc: Pointer to MPT_ADAPTER structure
* @sleepFlag: Specifies whether the process can sleep
@@ -2630,7 +2640,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
}
/* No need to byte swap the multibyte fields in the reply
- * since we don't even look at it's contents.
+ * since we don't even look at its contents.
*/
dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
@@ -2672,7 +2682,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* SendPortEnable - Send PortEnable request to MPT adapter port.
* @ioc: Pointer to MPT_ADAPTER structure
* @portnum: Port number to enable
@@ -2723,9 +2733,13 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
return rc;
}
-/*
- * ioc: Pointer to MPT_ADAPTER structure
- * size - total FW bytes
+/**
+ * mpt_alloc_fw_memory - allocate firmware memory
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * @size: total FW bytes
+ *
+ * If memory has already been allocated, the same (cached) value
+ * is returned.
*/
void
mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
@@ -2742,9 +2756,12 @@ mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
ioc->alloc_total += size;
}
}
-/*
- * If alt_img is NULL, delete from ioc structure.
- * Else, delete a secondary image in same format.
+/**
+ * mpt_free_fw_memory - free firmware memory
+ * @ioc: Pointer to MPT_ADAPTER structure
+ *
+ * If alt_img is NULL, delete from ioc structure.
+ * Else, delete a secondary image in same format.
*/
void
mpt_free_fw_memory(MPT_ADAPTER *ioc)
@@ -2763,7 +2780,7 @@ mpt_free_fw_memory(MPT_ADAPTER *ioc)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
* @ioc: Pointer to MPT_ADAPTER structure
* @sleepFlag: Specifies whether the process can sleep
@@ -2865,10 +2882,10 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_downloadboot - DownloadBoot code
* @ioc: Pointer to MPT_ADAPTER structure
- * @flag: Specify which part of IOC memory is to be uploaded.
+ * @pFwHeader: Pointer to firmware header info
* @sleepFlag: Specifies whether the process can sleep
*
* FwDownloadBoot requires Programmed IO access.
@@ -3071,7 +3088,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* KickStart - Perform hard reset of MPT adapter.
* @ioc: Pointer to MPT_ADAPTER structure
* @force: Force hard reset
@@ -3145,12 +3162,12 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_diag_reset - Perform hard reset of the adapter.
* @ioc: Pointer to MPT_ADAPTER structure
* @ignore: Set if to honor and clear to ignore
* the reset history bit
- * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
+ * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
* else set to NO_SLEEP (use mdelay instead)
*
* This routine places the adapter in diagnostic mode via the
@@ -3436,11 +3453,12 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* SendIocReset - Send IOCReset request to MPT adapter.
* @ioc: Pointer to MPT_ADAPTER structure
* @reset_type: reset type, expected values are
* %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
+ * @sleepFlag: Specifies whether the process can sleep
*
* Send IOCReset request to the MPT adapter.
*
@@ -3494,11 +3512,12 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * initChainBuffers - Allocate memory for and initialize
- * chain buffers, chain buffer control arrays and spinlock.
- * @hd: Pointer to MPT_SCSI_HOST structure
- * @init: If set, initialize the spin lock.
+/**
+ * initChainBuffers - Allocate memory for and initialize chain buffers
+ * @ioc: Pointer to MPT_ADAPTER structure
+ *
+ * Allocates memory for and initializes chain buffers,
+ * chain buffer control arrays and spinlock.
*/
static int
initChainBuffers(MPT_ADAPTER *ioc)
@@ -3594,7 +3613,7 @@ initChainBuffers(MPT_ADAPTER *ioc)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* PrimeIocFifos - Initialize IOC request and reply FIFOs.
* @ioc: Pointer to MPT_ADAPTER structure
*
@@ -3891,15 +3910,15 @@ mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
- * in it's IntStatus register.
+/**
+ * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
* @ioc: Pointer to MPT_ADAPTER structure
* @howlong: How long to wait (in seconds)
* @sleepFlag: Specifies whether the process can sleep
*
* This routine waits (up to ~2 seconds max) for IOC doorbell
- * handshake ACKnowledge.
+ * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
+ * bit in its IntStatus register being clear.
*
* Returns a negative value on failure, else wait loop count.
*/
@@ -3942,14 +3961,14 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
- * in it's IntStatus register.
+/**
+ * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
* @ioc: Pointer to MPT_ADAPTER structure
* @howlong: How long to wait (in seconds)
* @sleepFlag: Specifies whether the process can sleep
*
- * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
+ * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
+ * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
*
* Returns a negative value on failure, else wait loop count.
*/
@@ -3991,8 +4010,8 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
+/**
+ * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
* @ioc: Pointer to MPT_ADAPTER structure
* @howlong: How long to wait (in seconds)
* @sleepFlag: Specifies whether the process can sleep
@@ -4077,7 +4096,7 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* GetLanConfigPages - Fetch LANConfig pages.
* @ioc: Pointer to MPT_ADAPTER structure
*
@@ -4188,12 +4207,9 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
+/**
+ * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
* @ioc: Pointer to MPT_ADAPTER structure
- * @sas_address: 64bit SAS Address for operation.
- * @target_id: specified target for operation
- * @bus: specified bus for operation
* @persist_opcode: see below
*
* MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
@@ -4202,7 +4218,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
*
* NOTE: Don't use not this function during interrupt time.
*
- * Returns: 0 for success, non-zero error
+ * Returns 0 for success, non-zero error
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -4399,7 +4415,7 @@ mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* GetIoUnitPage2 - Retrieve BIOS version and boot order information.
* @ioc: Pointer to MPT_ADAPTER structure
*
@@ -4457,7 +4473,8 @@ GetIoUnitPage2(MPT_ADAPTER *ioc)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
+/**
+ * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
* @ioc: Pointer to a Adapter Strucutre
* @portnum: IOC port number
*
@@ -4644,7 +4661,8 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* mpt_readScsiDevicePageHeaders - save version and length of SDP1
+/**
+ * mpt_readScsiDevicePageHeaders - save version and length of SDP1
* @ioc: Pointer to a Adapter Strucutre
* @portnum: IOC port number
*
@@ -4996,9 +5014,8 @@ mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * SendEventNotification - Send EventNotification (on or off) request
- * to MPT adapter.
+/**
+ * SendEventNotification - Send EventNotification (on or off) request to adapter
* @ioc: Pointer to MPT_ADAPTER structure
* @EvSwitch: Event switch flags
*/
@@ -5062,8 +5079,8 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_config - Generic function to issue config message
- * @ioc - Pointer to an adapter structure
- * @cfg - Pointer to a configuration structure. Struct contains
+ * @ioc: Pointer to an adapter structure
+ * @pCfg: Pointer to a configuration structure. Struct contains
* action, page address, direction, physical address
* and pointer to a configuration page header
* Page header is updated.
@@ -5188,8 +5205,8 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * mpt_timer_expired - Call back for timer process.
+/**
+ * mpt_timer_expired - Callback for timer process.
* Used only internal config functionality.
* @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
*/
@@ -5214,12 +5231,12 @@ mpt_timer_expired(unsigned long data)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_ioc_reset - Base cleanup for hard reset
* @ioc: Pointer to the adapter structure
* @reset_phase: Indicates pre- or post-reset functionality
*
- * Remark: Free's resources with internally generated commands.
+ * Remark: Frees resources with internally generated commands.
*/
static int
mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
@@ -5271,7 +5288,7 @@ mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
* procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
*
* Returns 0 for success, non-zero for failure.
@@ -5297,7 +5314,7 @@ procmpt_create(void)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
*
* Returns 0 for success, non-zero for failure.
@@ -5311,16 +5328,16 @@ procmpt_destroy(void)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * procmpt_summary_read - Handle read request from /proc/mpt/summary
- * or from /proc/mpt/iocN/summary.
+/**
+ * procmpt_summary_read - Handle read request of a summary file
* @buf: Pointer to area to write information
* @start: Pointer to start pointer
* @offset: Offset to start writing
- * @request:
+ * @request: Amount of read data requested
* @eof: Pointer to EOF integer
* @data: Pointer
*
+ * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
* Returns number of characters written to process performing the read.
*/
static int
@@ -5355,12 +5372,12 @@ procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eo
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* procmpt_version_read - Handle read request from /proc/mpt/version.
* @buf: Pointer to area to write information
* @start: Pointer to start pointer
* @offset: Offset to start writing
- * @request:
+ * @request: Amount of read data requested
* @eof: Pointer to EOF integer
* @data: Pointer
*
@@ -5411,12 +5428,12 @@ procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eo
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
* @buf: Pointer to area to write information
* @start: Pointer to start pointer
* @offset: Offset to start writing
- * @request:
+ * @request: Amount of read data requested
* @eof: Pointer to EOF integer
* @data: Pointer
*
@@ -5577,16 +5594,17 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int sh
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
- * Management call based on input arg values. If TaskMgmt fails,
- * return associated SCSI request.
+ * mpt_HardResetHandler - Generic reset handler
* @ioc: Pointer to MPT_ADAPTER structure
* @sleepFlag: Indicates if sleep or schedule must be called.
*
+ * Issues SCSI Task Management call based on input arg values.
+ * If TaskMgmt fails, returns associated SCSI request.
+ *
* Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
* or a non-interrupt thread. In the former, must not call schedule().
*
- * Remark: A return of -1 is a FATAL error case, as it means a
+ * Note: A return of -1 is a FATAL error case, as it means a
* FW reload/initialization failed.
*
* Returns 0 for SUCCESS or -1 if FAILED.
@@ -5935,13 +5953,14 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * ProcessEventNotification - Route a received EventNotificationReply to
- * all currently regeistered event handlers.
+/**
+ * ProcessEventNotification - Route EventNotificationReply to all event handlers
* @ioc: Pointer to MPT_ADAPTER structure
* @pEventReply: Pointer to EventNotification reply frame
* @evHandlers: Pointer to integer, number of event handlers
*
+ * Routes a received EventNotificationReply to all currently registered
+ * event handlers.
* Returns sum of event handlers return values.
*/
static int
@@ -6056,7 +6075,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_fc_log_info - Log information returned from Fibre Channel IOC.
* @ioc: Pointer to MPT_ADAPTER structure
* @log_info: U32 LogInfo reply word from the IOC
@@ -6077,7 +6096,7 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
* @ioc: Pointer to MPT_ADAPTER structure
* @mr: Pointer to MPT reply frame
@@ -6200,7 +6219,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
};
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_sas_log_info - Log information returned from SAS IOC.
* @ioc: Pointer to MPT_ADAPTER structure
* @log_info: U32 LogInfo reply word from the IOC
@@ -6255,7 +6274,7 @@ union loginfo_type {
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
* @ioc: Pointer to MPT_ADAPTER structure
* @ioc_status: U32 IOCStatus word from IOC
@@ -6416,7 +6435,7 @@ EXPORT_SYMBOL(mpt_free_fw_memory);
EXPORT_SYMBOL(mptbase_sas_persist_operation);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* fusion_init - Fusion MPT base driver initialization routine.
*
* Returns 0 for success, non-zero for failure.
@@ -6456,7 +6475,7 @@ fusion_init(void)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* fusion_exit - Perform driver unload cleanup.
*
* This routine frees all resources associated with each MPT adapter
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index ef2b55e1991..ca2f9107f14 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -1395,8 +1395,7 @@ mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mptfc_init - Register MPT adapter(s) as SCSI host(s) with
- * linux scsi mid-layer.
+ * mptfc_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer.
*
* Returns 0 for success, non-zero for failure.
*/
@@ -1440,7 +1439,7 @@ mptfc_init(void)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mptfc_remove - Removed fc infrastructure for devices
+ * mptfc_remove - Remove fc infrastructure for devices
* @pdev: Pointer to pci_dev structure
*
*/
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 30524dc54b1..2c72c36b817 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1230,15 +1230,15 @@ mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mptscsih_proc_info - Return information about MPT adapter
+ * @host: scsi host struct
+ * @buffer: if write, user data; if read, buffer for user
+ * @start: returns the buffer address
+ * @offset: if write, 0; if read, the current offset into the buffer from
+ * the previous read.
+ * @length: if write, return length;
+ * @func: write = 1; read = 0
*
* (linux scsi_host_template.info routine)
- *
- * buffer: if write, user data; if read, buffer for user
- * length: if write, return length;
- * offset: if write, 0; if read, the current offset into the buffer from
- * the previous read.
- * hostno: scsi host number
- * func: if write = 1; if read = 0
*/
int
mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
@@ -1902,8 +1902,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mptscsih_host_reset - Perform a SCSI host adapter RESET!
- * new_eh variant
+ * mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
* @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
*
* (linux scsi_host_template.eh_host_reset_handler routine)
@@ -1949,8 +1948,7 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mptscsih_tm_pending_wait - wait for pending task management request to
- * complete.
+ * mptscsih_tm_pending_wait - wait for pending task management request to complete
* @hd: Pointer to MPT host structure.
*
* Returns {SUCCESS,FAILED}.
@@ -1982,6 +1980,7 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
/**
* mptscsih_tm_wait_for_completion - wait for completion of TM task
* @hd: Pointer to MPT host structure.
+ * @timeout: timeout in seconds
*
* Returns {SUCCESS,FAILED}.
*/
@@ -3429,8 +3428,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
/**
* mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
* @hd: Pointer to a SCSI HOST structure
- * @vtarget: per device private data
- * @lun: lun
+ * @vdevice: virtual target device
*
* Uses the ISR, but with special processing.
* MUST be single-threaded.
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index f422c0d0621..36641da5928 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -1100,8 +1100,7 @@ static struct pci_driver mptspi_driver = {
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mptspi_init - Register MPT adapter(s) as SCSI host(s) with
- * linux scsi mid-layer.
+ * mptspi_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer.
*
* Returns 0 for success, non-zero for failure.
*/
@@ -1135,7 +1134,6 @@ mptspi_init(void)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mptspi_exit - Unregisters MPT adapter(s)
- *
*/
static void __exit
mptspi_exit(void)
diff --git a/drivers/message/i2o/bus-osm.c b/drivers/message/i2o/bus-osm.c
index d96c687aee9..c463dc2efc0 100644
--- a/drivers/message/i2o/bus-osm.c
+++ b/drivers/message/i2o/bus-osm.c
@@ -56,6 +56,9 @@ static int i2o_bus_scan(struct i2o_device *dev)
/**
* i2o_bus_store_scan - Scan the I2O Bus Adapter
* @d: device which should be scanned
+ * @attr: device_attribute
+ * @buf: output buffer
+ * @count: buffer size
*
* Returns count.
*/
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
index ee183053fa2..b9df143e4ff 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/message/i2o/device.c
@@ -54,8 +54,8 @@ static inline int i2o_device_issue_claim(struct i2o_device *dev, u32 cmd,
* @dev: I2O device to claim
* @drv: I2O driver which wants to claim the device
*
- * Do the leg work to assign a device to a given OSM. If the claim succeed
- * the owner of the rimary. If the attempt fails a negative errno code
+ * Do the leg work to assign a device to a given OSM. If the claim succeeds,
+ * the owner is the primary. If the attempt fails a negative errno code
* is returned. On success zero is returned.
*/
int i2o_device_claim(struct i2o_device *dev)
@@ -208,24 +208,23 @@ static struct i2o_device *i2o_device_alloc(void)
/**
* i2o_device_add - allocate a new I2O device and add it to the IOP
- * @iop: I2O controller where the device is on
+ * @c: I2O controller that the device is on
* @entry: LCT entry of the I2O device
*
* Allocate a new I2O device and initialize it with the LCT entry. The
* device is appended to the device list of the controller.
*
- * Returns a pointer to the I2O device on success or negative error code
- * on failure.
+ * Returns zero on success, or a -ve errno.
*/
-static struct i2o_device *i2o_device_add(struct i2o_controller *c,
- i2o_lct_entry * entry)
+static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry)
{
struct i2o_device *i2o_dev, *tmp;
+ int rc;
i2o_dev = i2o_device_alloc();
if (IS_ERR(i2o_dev)) {
printk(KERN_ERR "i2o: unable to allocate i2o device\n");
- return i2o_dev;
+ return PTR_ERR(i2o_dev);
}
i2o_dev->lct_data = *entry;
@@ -236,7 +235,9 @@ static struct i2o_device *i2o_device_add(struct i2o_controller *c,
i2o_dev->iop = c;
i2o_dev->device.parent = &c->device;
- device_register(&i2o_dev->device);
+ rc = device_register(&i2o_dev->device);
+ if (rc)
+ goto err;
list_add_tail(&i2o_dev->list, &c->devices);
@@ -270,12 +271,16 @@ static struct i2o_device *i2o_device_add(struct i2o_controller *c,
pr_debug("i2o: device %s added\n", i2o_dev->device.bus_id);
- return i2o_dev;
+ return 0;
+
+err:
+ kfree(i2o_dev);
+ return rc;
}
/**
* i2o_device_remove - remove an I2O device from the I2O core
- * @dev: I2O device which should be released
+ * @i2o_dev: I2O device which should be released
*
* Is used on I2O controller removal or LCT modification, when the device
* is removed from the system. Note that the device could still hang
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
index 7fc7399bd2e..9104b65ff70 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/message/i2o/driver.c
@@ -34,9 +34,7 @@ static spinlock_t i2o_drivers_lock;
static struct i2o_driver **i2o_drivers;
/**
- * i2o_bus_match - Tell if a I2O device class id match the class ids of
- * the I2O driver (OSM)
- *
+ * i2o_bus_match - Tell if I2O device class id matches the class ids of the I2O driver (OSM)
* @dev: device which should be verified
* @drv: the driver to match against
*
@@ -248,7 +246,7 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m)
/**
* i2o_driver_notify_controller_add_all - Send notify of added controller
- * to all I2O drivers
+ * @c: newly added controller
*
* Send notifications to all registered drivers that a new controller was
* added.
@@ -267,8 +265,8 @@ void i2o_driver_notify_controller_add_all(struct i2o_controller *c)
}
/**
- * i2o_driver_notify_controller_remove_all - Send notify of removed
- * controller to all I2O drivers
+ * i2o_driver_notify_controller_remove_all - Send notify of removed controller
+ * @c: controller that is being removed
*
* Send notifications to all registered drivers that a controller was
* removed.
@@ -287,8 +285,8 @@ void i2o_driver_notify_controller_remove_all(struct i2o_controller *c)
}
/**
- * i2o_driver_notify_device_add_all - Send notify of added device to all
- * I2O drivers
+ * i2o_driver_notify_device_add_all - Send notify of added device
+ * @i2o_dev: newly added I2O device
*
* Send notifications to all registered drivers that a device was added.
*/
@@ -306,8 +304,8 @@ void i2o_driver_notify_device_add_all(struct i2o_device *i2o_dev)
}
/**
- * i2o_driver_notify_device_remove_all - Send notify of removed device to
- * all I2O drivers
+ * i2o_driver_notify_device_remove_all - Send notify of removed device
+ * @i2o_dev: device that is being removed
*
* Send notifications to all registered drivers that a device was removed.
*/
@@ -362,7 +360,7 @@ int __init i2o_driver_init(void)
/**
* i2o_driver_exit - clean up I2O drivers (OSMs)
*
- * Unregisters the I2O bus and free driver array.
+ * Unregisters the I2O bus and frees driver array.
*/
void __exit i2o_driver_exit(void)
{
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index 9e529d8dd5c..902753b2c66 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -94,8 +94,8 @@ static struct i2o_exec_wait *i2o_exec_wait_alloc(void)
};
/**
- * i2o_exec_wait_free - Free a i2o_exec_wait struct
- * @i2o_exec_wait: I2O wait data which should be cleaned up
+ * i2o_exec_wait_free - Free an i2o_exec_wait struct
+ * @wait: I2O wait data which should be cleaned up
*/
static void i2o_exec_wait_free(struct i2o_exec_wait *wait)
{
@@ -105,7 +105,7 @@ static void i2o_exec_wait_free(struct i2o_exec_wait *wait)
/**
* i2o_msg_post_wait_mem - Post and wait a message with DMA buffers
* @c: controller
- * @m: message to post
+ * @msg: message to post
* @timeout: time in seconds to wait
* @dma: i2o_dma struct of the DMA buffer to free on failure
*
@@ -269,6 +269,7 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
/**
* i2o_exec_show_vendor_id - Displays Vendor ID of controller
* @d: device of which the Vendor ID should be displayed
+ * @attr: device_attribute to display
* @buf: buffer into which the Vendor ID should be printed
*
* Returns number of bytes printed into buffer.
@@ -290,6 +291,7 @@ static ssize_t i2o_exec_show_vendor_id(struct device *d,
/**
* i2o_exec_show_product_id - Displays Product ID of controller
* @d: device of which the Product ID should be displayed
+ * @attr: device_attribute to display
* @buf: buffer into which the Product ID should be printed
*
* Returns number of bytes printed into buffer.
@@ -365,7 +367,7 @@ static int i2o_exec_remove(struct device *dev)
/**
* i2o_exec_lct_modified - Called on LCT NOTIFY reply
- * @c: I2O controller on which the LCT has modified
+ * @work: work struct for a specific controller
*
* This function handles asynchronus LCT NOTIFY replies. It parses the
* new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 70ae0025332..da9859f2caf 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -259,7 +259,7 @@ static int i2o_block_device_unlock(struct i2o_device *dev, u32 media_id)
/**
* i2o_block_device_power - Power management for device dev
* @dev: I2O device which should receive the power management request
- * @operation: Operation which should be send
+ * @op: Operation to send
*
* Send a power management request to the device dev.
*
@@ -315,7 +315,7 @@ static inline struct i2o_block_request *i2o_block_request_alloc(void)
* i2o_block_request_free - Frees a I2O block request
* @ireq: I2O block request which should be freed
*
- * Fres the allocated memory (give it back to the request mempool).
+ * Frees the allocated memory (give it back to the request mempool).
*/
static inline void i2o_block_request_free(struct i2o_block_request *ireq)
{
@@ -326,6 +326,7 @@ static inline void i2o_block_request_free(struct i2o_block_request *ireq)
* i2o_block_sglist_alloc - Allocate the SG list and map it
* @c: I2O controller to which the request belongs
* @ireq: I2O block request
+ * @mptr: message body pointer
*
* Builds the SG list and map it to be accessable by the controller.
*
@@ -490,7 +491,7 @@ static void i2o_block_end_request(struct request *req, int uptodate,
* i2o_block_reply - Block OSM reply handler.
* @c: I2O controller from which the message arrives
* @m: message id of reply
- * qmsg: the actuall I2O message reply
+ * @msg: the actual I2O message reply
*
* This function gets all the message replies.
*
@@ -602,6 +603,8 @@ static void i2o_block_biosparam(unsigned long capacity, unsigned short *cyls,
/**
* i2o_block_open - Open the block device
+ * @inode: inode for block device being opened
+ * @file: file to open
*
* Power up the device, mount and lock the media. This function is called,
* if the block device is opened for access.
@@ -629,6 +632,8 @@ static int i2o_block_open(struct inode *inode, struct file *file)
/**
* i2o_block_release - Release the I2O block device
+ * @inode: inode for block device being released
+ * @file: file to close
*
* Unlock and unmount the media, and power down the device. Gets called if
* the block device is closed.
@@ -675,6 +680,8 @@ static int i2o_block_getgeo(struct block_device *bdev, struct hd_geometry *geo)
/**
* i2o_block_ioctl - Issue device specific ioctl calls.
+ * @inode: inode for block device ioctl
+ * @file: file for ioctl
* @cmd: ioctl command
* @arg: arg
*
@@ -902,7 +909,7 @@ static int i2o_block_transfer(struct request *req)
/**
* i2o_block_request_fn - request queue handling function
- * q: request queue from which the request could be fetched
+ * @q: request queue from which the request could be fetched
*
* Takes the next request from the queue, transfers it and if no error
* occurs dequeue it from the queue. On arrival of the reply the message
diff --git a/drivers/message/i2o/i2o_block.h b/drivers/message/i2o/i2o_block.h
index d9fdc95b440..67f921b4419 100644
--- a/drivers/message/i2o/i2o_block.h
+++ b/drivers/message/i2o/i2o_block.h
@@ -64,7 +64,7 @@
/* I2O Block OSM mempool struct */
struct i2o_block_mempool {
- kmem_cache_t *slab;
+ struct kmem_cache *slab;
mempool_t *pool;
};
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 7d23e082bf2..1de30d71167 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -265,7 +265,11 @@ static int i2o_cfg_swdl(unsigned long arg)
return -ENOMEM;
}
- __copy_from_user(buffer.virt, kxfer.buf, fragsize);
+ if (__copy_from_user(buffer.virt, kxfer.buf, fragsize)) {
+ i2o_msg_nop(c, msg);
+ i2o_dma_free(&c->pdev->dev, &buffer);
+ return -EFAULT;
+ }
msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_7);
msg->u.head[1] =
@@ -516,7 +520,6 @@ static int i2o_cfg_evt_get(unsigned long arg, struct file *fp)
return 0;
}
-#ifdef CONFIG_I2O_EXT_ADAPTEC
#ifdef CONFIG_COMPAT
static int i2o_cfg_passthru32(struct file *file, unsigned cmnd,
unsigned long arg)
@@ -759,6 +762,7 @@ static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd,
#endif
+#ifdef CONFIG_I2O_EXT_ADAPTEC
static int i2o_cfg_passthru(unsigned long arg)
{
struct i2o_cmd_passthru __user *cmd =
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
index 3d2e76eea93..a61cb17c5c1 100644
--- a/drivers/message/i2o/i2o_proc.c
+++ b/drivers/message/i2o/i2o_proc.c
@@ -163,7 +163,7 @@ static int print_serial_number(struct seq_file *seq, u8 * serialno, int max_len)
* i2o_get_class_name - do i2o class name lookup
* @class: class number
*
- * Return a descriptive string for an i2o class
+ * Return a descriptive string for an i2o class.
*/
static const char *i2o_get_class_name(int class)
{
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
index 6ebf38213f9..1045c8a518b 100644
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/message/i2o/i2o_scsi.c
@@ -220,7 +220,7 @@ static int i2o_scsi_probe(struct device *dev)
u32 id = -1;
u64 lun = -1;
int channel = -1;
- int i;
+ int i, rc;
i2o_shost = i2o_scsi_get_host(c);
if (!i2o_shost)
@@ -304,14 +304,20 @@ static int i2o_scsi_probe(struct device *dev)
return PTR_ERR(scsi_dev);
}
- sysfs_create_link(&i2o_dev->device.kobj, &scsi_dev->sdev_gendev.kobj,
- "scsi");
+ rc = sysfs_create_link(&i2o_dev->device.kobj,
+ &scsi_dev->sdev_gendev.kobj, "scsi");
+ if (rc)
+ goto err;
osm_info("device added (TID: %03x) channel: %d, id: %d, lun: %ld\n",
i2o_dev->lct_data.tid, channel, le32_to_cpu(id),
(long unsigned int)le64_to_cpu(lun));
return 0;
+
+err:
+ scsi_remove_device(scsi_dev);
+ return rc;
};
static const char *i2o_scsi_info(struct Scsi_Host *SChost)
@@ -405,8 +411,7 @@ static void i2o_scsi_notify_device_add(struct i2o_device *i2o_dev)
};
/**
- * i2o_scsi_notify_device_remove - Retrieve notifications of removed
- * devices
+ * i2o_scsi_notify_device_remove - Retrieve notifications of removed devices
* @i2o_dev: the I2O device which was removed
*
* If a I2O device is removed, we catch the notification to remove the
@@ -426,8 +431,7 @@ static void i2o_scsi_notify_device_remove(struct i2o_device *i2o_dev)
};
/**
- * i2o_scsi_notify_controller_add - Retrieve notifications of added
- * controllers
+ * i2o_scsi_notify_controller_add - Retrieve notifications of added controllers
* @c: the controller which was added
*
* If a I2O controller is added, we catch the notification to add a
@@ -457,8 +461,7 @@ static void i2o_scsi_notify_controller_add(struct i2o_controller *c)
};
/**
- * i2o_scsi_notify_controller_remove - Retrieve notifications of removed
- * controllers
+ * i2o_scsi_notify_controller_remove - Retrieve notifications of removed controllers
* @c: the controller which was removed
*
* If a I2O controller is removed, we catch the notification to remove the
@@ -745,7 +748,7 @@ static int i2o_scsi_abort(struct scsi_cmnd *SCpnt)
* @capacity: size in sectors
* @ip: geometry array
*
- * This is anyones guess quite frankly. We use the same rules everyone
+ * This is anyone's guess quite frankly. We use the same rules everyone
* else appears to and hope. It seems to work.
*/
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
index 8287f95c8c4..3661e6e065d 100644
--- a/drivers/message/i2o/pci.c
+++ b/drivers/message/i2o/pci.c
@@ -259,6 +259,7 @@ static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id)
/**
* i2o_pci_irq_enable - Allocate interrupt for I2O controller
+ * @c: i2o_controller that the request is for
*
* Allocate an interrupt for the I2O controller, and activate interrupts
* on the I2O controller.
@@ -305,7 +306,7 @@ static void i2o_pci_irq_disable(struct i2o_controller *c)
/**
* i2o_pci_probe - Probe the PCI device for an I2O controller
- * @dev: PCI device to test
+ * @pdev: PCI device to test
* @id: id which matched with the PCI device id table
*
* Probe the PCI device for any device which is a memory of the
@@ -447,7 +448,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
/**
* i2o_pci_remove - Removes a I2O controller from the system
- * pdev: I2O controller which should be removed
+ * @pdev: I2O controller which should be removed
*
* Reset the I2O controller, disable interrupts and remove all allocated
* resources.
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index 82938ad6ddb..ce1a4810821 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -28,7 +28,7 @@
#include <linux/string.h>
#include <linux/input.h>
#include <linux/device.h>
-#include <linux/suspend.h>
+#include <linux/freezer.h>
#include <linux/slab.h>
#include <linux/kthread.h>
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
index ee326136d03..d61df5c3ac3 100644
--- a/drivers/misc/tifm_core.c
+++ b/drivers/misc/tifm_core.c
@@ -219,8 +219,9 @@ static int tifm_device_remove(struct device *dev)
struct tifm_driver *drv = fm_dev->drv;
if (drv) {
- if (drv->remove) drv->remove(fm_dev);
- fm_dev->drv = 0;
+ if (drv->remove)
+ drv->remove(fm_dev);
+ fm_dev->drv = NULL;
}
put_device(dev);
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index ef4a731ca5c..334e078ffaf 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -451,7 +451,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
return -ENODEV;
}
- flash = kzalloc(sizeof *flash, SLAB_KERNEL);
+ flash = kzalloc(sizeof *flash, GFP_KERNEL);
if (!flash)
return -ENOMEM;
diff --git a/drivers/net/de600.c b/drivers/net/de600.c
index 690bb40b353..8396e411f1c 100644
--- a/drivers/net/de600.c
+++ b/drivers/net/de600.c
@@ -43,7 +43,6 @@ static const char version[] = "de600.c: $Revision: 1.41-2.5 $, Bjorn Ekwall (bj
* modify the following "#define": (see <asm/io.h> for more info)
#define REALLY_SLOW_IO
*/
-#define SLOW_IO_BY_JUMPING /* Looks "better" than dummy write to port 0x80 :-) */
/* use 0 for production, 1 for verification, >2 for debug */
#ifdef DE600_DEBUG
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index 3b4c4787593..c14a74634fd 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -50,6 +50,7 @@
#include <linux/usb.h>
#include <linux/crc32.h>
#include <linux/kthread.h>
+#include <linux/freezer.h>
#include <net/irda/irda.h>
#include <net/irda/irlap.h>
#include <net/irda/irda_device.h>
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
index f4d815bca64..ea392f2a5aa 100644
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -119,14 +119,14 @@
#define DEB(x,y) if (i596_debug & (x)) { y; }
-#define CHECK_WBACK(addr,len) \
- do { dma_cache_sync((void *)addr, len, DMA_TO_DEVICE); } while (0)
+#define CHECK_WBACK(priv, addr,len) \
+ do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_TO_DEVICE); } while (0)
-#define CHECK_INV(addr,len) \
- do { dma_cache_sync((void *)addr, len, DMA_FROM_DEVICE); } while(0)
+#define CHECK_INV(priv, addr,len) \
+ do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_FROM_DEVICE); } while(0)
-#define CHECK_WBACK_INV(addr,len) \
- do { dma_cache_sync((void *)addr, len, DMA_BIDIRECTIONAL); } while (0)
+#define CHECK_WBACK_INV(priv, addr,len) \
+ do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_BIDIRECTIONAL); } while (0)
#define PA_I82596_RESET 0 /* Offsets relative to LASI-LAN-Addr.*/
@@ -449,10 +449,10 @@ static inline void MPU_PORT(struct net_device *dev, int c, dma_addr_t x)
static inline int wait_istat(struct net_device *dev, struct i596_private *lp, int delcnt, char *str)
{
- CHECK_INV(&(lp->iscp), sizeof(struct i596_iscp));
+ CHECK_INV(lp, &(lp->iscp), sizeof(struct i596_iscp));
while (--delcnt && lp->iscp.stat) {
udelay(10);
- CHECK_INV(&(lp->iscp), sizeof(struct i596_iscp));
+ CHECK_INV(lp, &(lp->iscp), sizeof(struct i596_iscp));
}
if (!delcnt) {
printk("%s: %s, iscp.stat %04x, didn't clear\n",
@@ -466,10 +466,10 @@ static inline int wait_istat(struct net_device *dev, struct i596_private *lp, in
static inline int wait_cmd(struct net_device *dev, struct i596_private *lp, int delcnt, char *str)
{
- CHECK_INV(&(lp->scb), sizeof(struct i596_scb));
+ CHECK_INV(lp, &(lp->scb), sizeof(struct i596_scb));
while (--delcnt && lp->scb.command) {
udelay(10);
- CHECK_INV(&(lp->scb), sizeof(struct i596_scb));
+ CHECK_INV(lp, &(lp->scb), sizeof(struct i596_scb));
}
if (!delcnt) {
printk("%s: %s, status %4.4x, cmd %4.4x.\n",
@@ -522,7 +522,7 @@ static void i596_display_data(struct net_device *dev)
rbd, rbd->count, rbd->b_next, rbd->b_data, rbd->size);
rbd = rbd->v_next;
} while (rbd != lp->rbd_head);
- CHECK_INV(lp, sizeof(struct i596_private));
+ CHECK_INV(lp, lp, sizeof(struct i596_private));
}
@@ -592,7 +592,7 @@ static inline void init_rx_bufs(struct net_device *dev)
rfd->b_next = WSWAPrfd(virt_to_dma(lp,lp->rfds));
rfd->cmd = CMD_EOL|CMD_FLEX;
- CHECK_WBACK_INV(lp, sizeof(struct i596_private));
+ CHECK_WBACK_INV(lp, lp, sizeof(struct i596_private));
}
static inline void remove_rx_bufs(struct net_device *dev)
@@ -629,7 +629,7 @@ static void rebuild_rx_bufs(struct net_device *dev)
lp->rbd_head = lp->rbds;
lp->rfds[0].rbd = WSWAPrbd(virt_to_dma(lp,lp->rbds));
- CHECK_WBACK_INV(lp, sizeof(struct i596_private));
+ CHECK_WBACK_INV(lp, lp, sizeof(struct i596_private));
}
@@ -663,8 +663,8 @@ static int init_i596_mem(struct net_device *dev)
DEB(DEB_INIT, printk("%s: starting i82596.\n", dev->name));
- CHECK_WBACK(&(lp->scp), sizeof(struct i596_scp));
- CHECK_WBACK(&(lp->iscp), sizeof(struct i596_iscp));
+ CHECK_WBACK(lp, &(lp->scp), sizeof(struct i596_scp));
+ CHECK_WBACK(lp, &(lp->iscp), sizeof(struct i596_iscp));
MPU_PORT(dev, PORT_ALTSCP, virt_to_dma(lp,&lp->scp));
@@ -678,25 +678,25 @@ static int init_i596_mem(struct net_device *dev)
rebuild_rx_bufs(dev);
lp->scb.command = 0;
- CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb));
+ CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
enable_irq(dev->irq); /* enable IRQs from LAN */
DEB(DEB_INIT, printk("%s: queuing CmdConfigure\n", dev->name));
memcpy(lp->cf_cmd.i596_config, init_setup, 14);
lp->cf_cmd.cmd.command = CmdConfigure;
- CHECK_WBACK(&(lp->cf_cmd), sizeof(struct cf_cmd));
+ CHECK_WBACK(lp, &(lp->cf_cmd), sizeof(struct cf_cmd));
i596_add_cmd(dev, &lp->cf_cmd.cmd);
DEB(DEB_INIT, printk("%s: queuing CmdSASetup\n", dev->name));
memcpy(lp->sa_cmd.eth_addr, dev->dev_addr, 6);
lp->sa_cmd.cmd.command = CmdSASetup;
- CHECK_WBACK(&(lp->sa_cmd), sizeof(struct sa_cmd));
+ CHECK_WBACK(lp, &(lp->sa_cmd), sizeof(struct sa_cmd));
i596_add_cmd(dev, &lp->sa_cmd.cmd);
DEB(DEB_INIT, printk("%s: queuing CmdTDR\n", dev->name));
lp->tdr_cmd.cmd.command = CmdTDR;
- CHECK_WBACK(&(lp->tdr_cmd), sizeof(struct tdr_cmd));
+ CHECK_WBACK(lp, &(lp->tdr_cmd), sizeof(struct tdr_cmd));
i596_add_cmd(dev, &lp->tdr_cmd.cmd);
spin_lock_irqsave (&lp->lock, flags);
@@ -708,7 +708,7 @@ static int init_i596_mem(struct net_device *dev)
DEB(DEB_INIT, printk("%s: Issuing RX_START\n", dev->name));
lp->scb.command = RX_START;
lp->scb.rfd = WSWAPrfd(virt_to_dma(lp,lp->rfds));
- CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb));
+ CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
CA(dev);
@@ -740,13 +740,13 @@ static inline int i596_rx(struct net_device *dev)
rfd = lp->rfd_head; /* Ref next frame to check */
- CHECK_INV(rfd, sizeof(struct i596_rfd));
+ CHECK_INV(lp, rfd, sizeof(struct i596_rfd));
while ((rfd->stat) & STAT_C) { /* Loop while complete frames */
if (rfd->rbd == I596_NULL)
rbd = NULL;
else if (rfd->rbd == lp->rbd_head->b_addr) {
rbd = lp->rbd_head;
- CHECK_INV(rbd, sizeof(struct i596_rbd));
+ CHECK_INV(lp, rbd, sizeof(struct i596_rbd));
}
else {
printk("%s: rbd chain broken!\n", dev->name);
@@ -790,7 +790,7 @@ static inline int i596_rx(struct net_device *dev)
dma_addr = dma_map_single(lp->dev, newskb->data, PKT_BUF_SZ, DMA_FROM_DEVICE);
rbd->v_data = newskb->data;
rbd->b_data = WSWAPchar(dma_addr);
- CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd));
+ CHECK_WBACK_INV(lp, rbd, sizeof(struct i596_rbd));
}
else
skb = dev_alloc_skb(pkt_len + 2);
@@ -842,7 +842,7 @@ memory_squeeze:
if (rbd != NULL && (rbd->count & 0x4000)) {
rbd->count = 0;
lp->rbd_head = rbd->v_next;
- CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd));
+ CHECK_WBACK_INV(lp, rbd, sizeof(struct i596_rbd));
}
/* Tidy the frame descriptor, marking it as end of list */
@@ -860,10 +860,10 @@ memory_squeeze:
lp->scb.rfd = rfd->b_next;
lp->rfd_head = rfd->v_next;
- CHECK_WBACK_INV(rfd->v_prev, sizeof(struct i596_rfd));
- CHECK_WBACK_INV(rfd, sizeof(struct i596_rfd));
+ CHECK_WBACK_INV(lp, rfd->v_prev, sizeof(struct i596_rfd));
+ CHECK_WBACK_INV(lp, rfd, sizeof(struct i596_rfd));
rfd = lp->rfd_head;
- CHECK_INV(rfd, sizeof(struct i596_rfd));
+ CHECK_INV(lp, rfd, sizeof(struct i596_rfd));
}
DEB(DEB_RXFRAME, printk("frames %d\n", frames));
@@ -902,12 +902,12 @@ static inline void i596_cleanup_cmd(struct net_device *dev, struct i596_private
ptr->v_next = NULL;
ptr->b_next = I596_NULL;
}
- CHECK_WBACK_INV(ptr, sizeof(struct i596_cmd));
+ CHECK_WBACK_INV(lp, ptr, sizeof(struct i596_cmd));
}
wait_cmd(dev, lp, 100, "i596_cleanup_cmd timed out");
lp->scb.cmd = I596_NULL;
- CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb));
+ CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
}
@@ -925,7 +925,7 @@ static inline void i596_reset(struct net_device *dev, struct i596_private *lp)
/* FIXME: this command might cause an lpmc */
lp->scb.command = CUC_ABORT | RX_ABORT;
- CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb));
+ CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
CA(dev);
/* wait for shutdown */
@@ -951,20 +951,20 @@ static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd)
cmd->command |= (CMD_EOL | CMD_INTR);
cmd->v_next = NULL;
cmd->b_next = I596_NULL;
- CHECK_WBACK(cmd, sizeof(struct i596_cmd));
+ CHECK_WBACK(lp, cmd, sizeof(struct i596_cmd));
spin_lock_irqsave (&lp->lock, flags);
if (lp->cmd_head != NULL) {
lp->cmd_tail->v_next = cmd;
lp->cmd_tail->b_next = WSWAPcmd(virt_to_dma(lp,&cmd->status));
- CHECK_WBACK(lp->cmd_tail, sizeof(struct i596_cmd));
+ CHECK_WBACK(lp, lp->cmd_tail, sizeof(struct i596_cmd));
} else {
lp->cmd_head = cmd;
wait_cmd(dev, lp, 100, "i596_add_cmd timed out");
lp->scb.cmd = WSWAPcmd(virt_to_dma(lp,&cmd->status));
lp->scb.command = CUC_START;
- CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb));
+ CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
CA(dev);
}
lp->cmd_tail = cmd;
@@ -998,12 +998,12 @@ static int i596_test(struct net_device *dev)
data = virt_to_dma(lp,tint);
tint[1] = -1;
- CHECK_WBACK(tint,PAGE_SIZE);
+ CHECK_WBACK(lp, tint, PAGE_SIZE);
MPU_PORT(dev, 1, data);
for(data = 1000000; data; data--) {
- CHECK_INV(tint,PAGE_SIZE);
+ CHECK_INV(lp, tint, PAGE_SIZE);
if(tint[1] != -1)
break;
@@ -1061,7 +1061,7 @@ static void i596_tx_timeout (struct net_device *dev)
/* Issue a channel attention signal */
DEB(DEB_ERRORS, printk("Kicking board.\n"));
lp->scb.command = CUC_START | RX_START;
- CHECK_WBACK_INV(&(lp->scb), sizeof(struct i596_scb));
+ CHECK_WBACK_INV(lp, &(lp->scb), sizeof(struct i596_scb));
CA (dev);
lp->last_restart = lp->stats.tx_packets;
}
@@ -1118,8 +1118,8 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
tbd->data = WSWAPchar(tx_cmd->dma_addr);
DEB(DEB_TXADDR,print_eth(skb->data, "tx-queued"));
- CHECK_WBACK_INV(tx_cmd, sizeof(struct tx_cmd));
- CHECK_WBACK_INV(tbd, sizeof(struct i596_tbd));
+ CHECK_WBACK_INV(lp, tx_cmd, sizeof(struct tx_cmd));
+ CHECK_WBACK_INV(lp, tbd, sizeof(struct i596_tbd));
i596_add_cmd(dev, &tx_cmd->cmd);
lp->stats.tx_packets++;
@@ -1228,7 +1228,7 @@ static int __devinit i82596_probe(struct net_device *dev,
lp->dma_addr = dma_addr;
lp->dev = gen_dev;
- CHECK_WBACK_INV(dev->mem_start, sizeof(struct i596_private));
+ CHECK_WBACK_INV(lp, dev->mem_start, sizeof(struct i596_private));
i = register_netdev(dev);
if (i) {
@@ -1295,7 +1295,7 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id)
DEB(DEB_INTS, printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700));
while (lp->cmd_head != NULL) {
- CHECK_INV(lp->cmd_head, sizeof(struct i596_cmd));
+ CHECK_INV(lp, lp->cmd_head, sizeof(struct i596_cmd));
if (!(lp->cmd_head->status & STAT_C))
break;
@@ -1358,7 +1358,7 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id)
}
ptr->v_next = NULL;
ptr->b_next = I596_NULL;
- CHECK_WBACK(ptr, sizeof(struct i596_cmd));
+ CHECK_WBACK(lp, ptr, sizeof(struct i596_cmd));
lp->last_cmd = jiffies;
}
@@ -1372,13 +1372,13 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id)
ptr->command &= 0x1fff;
ptr = ptr->v_next;
- CHECK_WBACK_INV(prev, sizeof(struct i596_cmd));
+ CHECK_WBACK_INV(lp, prev, sizeof(struct i596_cmd));
}
if ((lp->cmd_head != NULL))
ack_cmd |= CUC_START;
lp->scb.cmd = WSWAPcmd(virt_to_dma(lp,&lp->cmd_head->status));
- CHECK_WBACK_INV(&lp->scb, sizeof(struct i596_scb));
+ CHECK_WBACK_INV(lp, &lp->scb, sizeof(struct i596_scb));
}
if ((status & 0x1000) || (status & 0x4000)) {
if ((status & 0x4000))
@@ -1397,7 +1397,7 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id)
}
wait_cmd(dev, lp, 100, "i596 interrupt, timeout");
lp->scb.command = ack_cmd;
- CHECK_WBACK(&lp->scb, sizeof(struct i596_scb));
+ CHECK_WBACK(lp, &lp->scb, sizeof(struct i596_scb));
/* DANGER: I suspect that some kind of interrupt
acknowledgement aside from acking the 82596 might be needed
@@ -1426,7 +1426,7 @@ static int i596_close(struct net_device *dev)
wait_cmd(dev, lp, 100, "close1 timed out");
lp->scb.command = CUC_ABORT | RX_ABORT;
- CHECK_WBACK(&lp->scb, sizeof(struct i596_scb));
+ CHECK_WBACK(lp, &lp->scb, sizeof(struct i596_scb));
CA(dev);
@@ -1486,7 +1486,7 @@ static void set_multicast_list(struct net_device *dev)
dev->name);
else {
lp->cf_cmd.cmd.command = CmdConfigure;
- CHECK_WBACK_INV(&lp->cf_cmd, sizeof(struct cf_cmd));
+ CHECK_WBACK_INV(lp, &lp->cf_cmd, sizeof(struct cf_cmd));
i596_add_cmd(dev, &lp->cf_cmd.cmd);
}
}
@@ -1514,7 +1514,7 @@ static void set_multicast_list(struct net_device *dev)
DEB(DEB_MULTI, printk("%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n",
dev->name, cp[0],cp[1],cp[2],cp[3],cp[4],cp[5]));
}
- CHECK_WBACK_INV(&lp->mc_cmd, sizeof(struct mc_cmd));
+ CHECK_WBACK_INV(lp, &lp->mc_cmd, sizeof(struct mc_cmd));
i596_add_cmd(dev, &cmd->cmd);
}
}
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index efcdaf1c5f7..44a22701da9 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -49,6 +49,7 @@
#include <asm/uaccess.h>
#include <net/ieee80211.h>
#include <linux/kthread.h>
+#include <linux/freezer.h>
#include "airo.h"
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 39c96641bc7..b61c17b3e29 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -1975,7 +1975,7 @@ static int __devinit parport_ECPPS2_supported(struct parport *pb){return 0;}
/* --- IRQ detection -------------------------------------- */
/* Only if supports ECP mode */
-static int __devinit programmable_irq_support(struct parport *pb)
+static int programmable_irq_support(struct parport *pb)
{
int irq, intrLine;
unsigned char oecr = inb (ECONTROL (pb));
@@ -1992,7 +1992,7 @@ static int __devinit programmable_irq_support(struct parport *pb)
return irq;
}
-static int __devinit irq_probe_ECP(struct parport *pb)
+static int irq_probe_ECP(struct parport *pb)
{
int i;
unsigned long irqs;
@@ -2020,7 +2020,7 @@ static int __devinit irq_probe_ECP(struct parport *pb)
* This detection seems that only works in National Semiconductors
* This doesn't work in SMC, LGS, and Winbond
*/
-static int __devinit irq_probe_EPP(struct parport *pb)
+static int irq_probe_EPP(struct parport *pb)
{
#ifndef ADVANCED_DETECT
return PARPORT_IRQ_NONE;
@@ -2059,7 +2059,7 @@ static int __devinit irq_probe_EPP(struct parport *pb)
#endif /* Advanced detection */
}
-static int __devinit irq_probe_SPP(struct parport *pb)
+static int irq_probe_SPP(struct parport *pb)
{
/* Don't even try to do this. */
return PARPORT_IRQ_NONE;
@@ -2747,6 +2747,7 @@ enum parport_pc_pci_cards {
titan_1284p2,
avlab_1p,
avlab_2p,
+ oxsemi_952,
oxsemi_954,
oxsemi_840,
aks_0100,
@@ -2822,6 +2823,7 @@ static struct parport_pc_pci {
/* avlab_2p */ { 2, { { 0, 1}, { 2, 3 },} },
/* The Oxford Semi cards are unusual: 954 doesn't support ECP,
* and 840 locks up if you write 1 to bit 2! */
+ /* oxsemi_952 */ { 1, { { 0, 1 }, } },
/* oxsemi_954 */ { 1, { { 0, -1 }, } },
/* oxsemi_840 */ { 1, { { 0, -1 }, } },
/* aks_0100 */ { 1, { { 0, -1 }, } },
@@ -2895,6 +2897,8 @@ static const struct pci_device_id parport_pc_pci_tbl[] = {
/* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
{ 0x14db, 0x2120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1p}, /* AFAVLAB_TK9902 */
{ 0x14db, 0x2121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2p},
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952PP,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_952 },
{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954PP,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_954 },
{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_12PCI840,
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 9fc9a34ef24..9168401401b 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -26,7 +26,7 @@
static DEFINE_SPINLOCK(msi_lock);
static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
-static kmem_cache_t* msi_cachep;
+static struct kmem_cache* msi_cachep;
static int pci_msi_enable = 1;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 0eeac60042b..6a3c1e72890 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -873,6 +873,7 @@ void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
dev->dev.release = pci_release_dev;
pci_dev_get(dev);
+ set_dev_node(&dev->dev, pcibus_to_node(bus));
dev->dev.dma_mask = &dev->dma_mask;
dev->dev.coherent_dma_mask = 0xffffffffull;
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index f9cd831a3f3..606a4674033 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -29,6 +29,7 @@
#include <linux/pci.h>
#include <linux/device.h>
#include <linux/kthread.h>
+#include <linux/freezer.h>
#include <asm/system.h>
#include <asm/irq.h>
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index 227600cd636..91c047a7e63 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -164,9 +164,17 @@ static DEVICE_ATTR(card_id,S_IRUGO,pnp_show_card_ids,NULL);
static int pnp_interface_attach_card(struct pnp_card *card)
{
- device_create_file(&card->dev,&dev_attr_name);
- device_create_file(&card->dev,&dev_attr_card_id);
+ int rc = device_create_file(&card->dev,&dev_attr_name);
+ if (rc) return rc;
+
+ rc = device_create_file(&card->dev,&dev_attr_card_id);
+ if (rc) goto err_name;
+
return 0;
+
+err_name:
+ device_remove_file(&card->dev,&dev_attr_name);
+ return rc;
}
/**
@@ -306,16 +314,20 @@ found:
down_write(&dev->dev.bus->subsys.rwsem);
dev->card_link = clink;
dev->dev.driver = &drv->link.driver;
- if (pnp_bus_type.probe(&dev->dev)) {
- dev->dev.driver = NULL;
- dev->card_link = NULL;
- up_write(&dev->dev.bus->subsys.rwsem);
- return NULL;
- }
- device_bind_driver(&dev->dev);
+ if (pnp_bus_type.probe(&dev->dev))
+ goto err_out;
+ if (device_bind_driver(&dev->dev))
+ goto err_out;
+
up_write(&dev->dev.bus->subsys.rwsem);
return dev;
+
+err_out:
+ dev->dev.driver = NULL;
+ dev->card_link = NULL;
+ up_write(&dev->dev.bus->subsys.rwsem);
+ return NULL;
}
/**
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 9d8b415eca7..ac9fcd499f3 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -461,8 +461,19 @@ static DEVICE_ATTR(id,S_IRUGO,pnp_show_current_ids,NULL);
int pnp_interface_attach_device(struct pnp_dev *dev)
{
- device_create_file(&dev->dev,&dev_attr_options);
- device_create_file(&dev->dev,&dev_attr_resources);
- device_create_file(&dev->dev,&dev_attr_id);
+ int rc = device_create_file(&dev->dev,&dev_attr_options);
+ if (rc) goto err;
+ rc = device_create_file(&dev->dev,&dev_attr_resources);
+ if (rc) goto err_opt;
+ rc = device_create_file(&dev->dev,&dev_attr_id);
+ if (rc) goto err_res;
+
return 0;
+
+err_res:
+ device_remove_file(&dev->dev,&dev_attr_resources);
+err_opt:
+ device_remove_file(&dev->dev,&dev_attr_options);
+err:
+ return rc;
}
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 81a6c83d89a..33adeba1a31 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -61,6 +61,7 @@
#include <linux/dmi.h>
#include <linux/delay.h>
#include <linux/acpi.h>
+#include <linux/freezer.h>
#include <asm/page.h>
#include <asm/desc.h>
@@ -530,7 +531,8 @@ static int __init pnpbios_init(void)
if (check_legacy_ioport(PNPBIOS_BASE))
return -ENODEV;
#endif
- if (pnpbios_disabled || dmi_check_system(pnpbios_dmi_table)) {
+ if (pnpbios_disabled || dmi_check_system(pnpbios_dmi_table) ||
+ paravirt_enabled()) {
printk(KERN_INFO "PnPBIOS: Disabled\n");
return -ENODEV;
}
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index fc766a7a611..2a63ab2b47f 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -154,15 +154,23 @@ config RTC_DRV_DS1672
will be called rtc-ds1672.
config RTC_DRV_DS1742
- tristate "Dallas DS1742"
+ tristate "Dallas DS1742/1743"
depends on RTC_CLASS
help
If you say yes here you get support for the
- Dallas DS1742 timekeeping chip.
+ Dallas DS1742/1743 timekeeping chip.
This driver can also be built as a module. If so, the module
will be called rtc-ds1742.
+config RTC_DRV_OMAP
+ tristate "TI OMAP1"
+ depends on RTC_CLASS && ( \
+ ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 )
+ help
+ Say "yes" here to support the real time clock on TI OMAP1 chips.
+ This driver can also be built as a module called rtc-omap.
+
config RTC_DRV_PCF8563
tristate "Philips PCF8563/Epson RTC8564"
depends on RTC_CLASS && I2C
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 3ba5ff6e680..bd4c45d333f 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o
obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
+obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c
index 67e816a9a39..dfef1637bfb 100644
--- a/drivers/rtc/rtc-ds1672.c
+++ b/drivers/rtc/rtc-ds1672.c
@@ -237,17 +237,22 @@ static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind)
/* read control register */
err = ds1672_get_control(client, &control);
if (err)
- goto exit_detach;
+ goto exit_devreg;
if (control & DS1672_REG_CONTROL_EOSC)
dev_warn(&client->dev, "Oscillator not enabled. "
"Set time to enable.\n");
/* Register sysfs hooks */
- device_create_file(&client->dev, &dev_attr_control);
+ err = device_create_file(&client->dev, &dev_attr_control);
+ if (err)
+ goto exit_devreg;
return 0;
+exit_devreg:
+ rtc_device_unregister(rtc);
+
exit_detach:
i2c_detach_client(client);
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
index 6273a3d240a..17633bfa848 100644
--- a/drivers/rtc/rtc-ds1742.c
+++ b/drivers/rtc/rtc-ds1742.c
@@ -6,6 +6,10 @@
* 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.
+ *
+ * Copyright (C) 2006 Torsten Ertbjerg Rasmussen <tr@newtec.dk>
+ * - nvram size determined from resource
+ * - this ds1742 driver now supports ds1743.
*/
#include <linux/bcd.h>
@@ -17,20 +21,19 @@
#include <linux/platform_device.h>
#include <linux/io.h>
-#define DRV_VERSION "0.2"
+#define DRV_VERSION "0.3"
-#define RTC_REG_SIZE 0x800
-#define RTC_OFFSET 0x7f8
+#define RTC_SIZE 8
-#define RTC_CONTROL (RTC_OFFSET + 0)
-#define RTC_CENTURY (RTC_OFFSET + 0)
-#define RTC_SECONDS (RTC_OFFSET + 1)
-#define RTC_MINUTES (RTC_OFFSET + 2)
-#define RTC_HOURS (RTC_OFFSET + 3)
-#define RTC_DAY (RTC_OFFSET + 4)
-#define RTC_DATE (RTC_OFFSET + 5)
-#define RTC_MONTH (RTC_OFFSET + 6)
-#define RTC_YEAR (RTC_OFFSET + 7)
+#define RTC_CONTROL 0
+#define RTC_CENTURY 0
+#define RTC_SECONDS 1
+#define RTC_MINUTES 2
+#define RTC_HOURS 3
+#define RTC_DAY 4
+#define RTC_DATE 5
+#define RTC_MONTH 6
+#define RTC_YEAR 7
#define RTC_CENTURY_MASK 0x3f
#define RTC_SECONDS_MASK 0x7f
@@ -48,7 +51,10 @@
struct rtc_plat_data {
struct rtc_device *rtc;
- void __iomem *ioaddr;
+ void __iomem *ioaddr_nvram;
+ void __iomem *ioaddr_rtc;
+ size_t size_nvram;
+ size_t size;
unsigned long baseaddr;
unsigned long last_jiffies;
};
@@ -57,7 +63,7 @@ static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
- void __iomem *ioaddr = pdata->ioaddr;
+ void __iomem *ioaddr = pdata->ioaddr_rtc;
u8 century;
century = BIN2BCD((tm->tm_year + 1900) / 100);
@@ -82,7 +88,7 @@ static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
- void __iomem *ioaddr = pdata->ioaddr;
+ void __iomem *ioaddr = pdata->ioaddr_rtc;
unsigned int year, month, day, hour, minute, second, week;
unsigned int century;
@@ -127,10 +133,10 @@ static ssize_t ds1742_nvram_read(struct kobject *kobj, char *buf,
struct platform_device *pdev =
to_platform_device(container_of(kobj, struct device, kobj));
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
- void __iomem *ioaddr = pdata->ioaddr;
+ void __iomem *ioaddr = pdata->ioaddr_nvram;
ssize_t count;
- for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--)
+ for (count = 0; size > 0 && pos < pdata->size_nvram; count++, size--)
*buf++ = readb(ioaddr + pos++);
return count;
}
@@ -141,10 +147,10 @@ static ssize_t ds1742_nvram_write(struct kobject *kobj, char *buf,
struct platform_device *pdev =
to_platform_device(container_of(kobj, struct device, kobj));
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
- void __iomem *ioaddr = pdata->ioaddr;
+ void __iomem *ioaddr = pdata->ioaddr_nvram;
ssize_t count;
- for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--)
+ for (count = 0; size > 0 && pos < pdata->size_nvram; count++, size--)
writeb(*buf++, ioaddr + pos++);
return count;
}
@@ -155,7 +161,6 @@ static struct bin_attribute ds1742_nvram_attr = {
.mode = S_IRUGO | S_IWUGO,
.owner = THIS_MODULE,
},
- .size = RTC_OFFSET,
.read = ds1742_nvram_read,
.write = ds1742_nvram_write,
};
@@ -175,19 +180,23 @@ static int __init ds1742_rtc_probe(struct platform_device *pdev)
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
- if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) {
+ pdata->size = res->end - res->start + 1;
+ if (!request_mem_region(res->start, pdata->size, pdev->name)) {
ret = -EBUSY;
goto out;
}
pdata->baseaddr = res->start;
- ioaddr = ioremap(pdata->baseaddr, RTC_REG_SIZE);
+ ioaddr = ioremap(pdata->baseaddr, pdata->size);
if (!ioaddr) {
ret = -ENOMEM;
goto out;
}
- pdata->ioaddr = ioaddr;
+ pdata->ioaddr_nvram = ioaddr;
+ pdata->size_nvram = pdata->size - RTC_SIZE;
+ pdata->ioaddr_rtc = ioaddr + pdata->size_nvram;
/* turn RTC on if it was not on */
+ ioaddr = pdata->ioaddr_rtc;
sec = readb(ioaddr + RTC_SECONDS);
if (sec & RTC_STOP) {
sec &= RTC_SECONDS_MASK;
@@ -208,6 +217,8 @@ static int __init ds1742_rtc_probe(struct platform_device *pdev)
pdata->rtc = rtc;
pdata->last_jiffies = jiffies;
platform_set_drvdata(pdev, pdata);
+ ds1742_nvram_attr.size = max(ds1742_nvram_attr.size,
+ pdata->size_nvram);
ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1742_nvram_attr);
if (ret)
goto out;
@@ -215,10 +226,10 @@ static int __init ds1742_rtc_probe(struct platform_device *pdev)
out:
if (pdata->rtc)
rtc_device_unregister(pdata->rtc);
- if (ioaddr)
- iounmap(ioaddr);
+ if (pdata->ioaddr_nvram)
+ iounmap(pdata->ioaddr_nvram);
if (pdata->baseaddr)
- release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
+ release_mem_region(pdata->baseaddr, pdata->size);
kfree(pdata);
return ret;
}
@@ -229,8 +240,8 @@ static int __devexit ds1742_rtc_remove(struct platform_device *pdev)
sysfs_remove_bin_file(&pdev->dev.kobj, &ds1742_nvram_attr);
rtc_device_unregister(pdata->rtc);
- iounmap(pdata->ioaddr);
- release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
+ iounmap(pdata->ioaddr_nvram);
+ release_mem_region(pdata->baseaddr, pdata->size);
kfree(pdata);
return 0;
}
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
new file mode 100644
index 00000000000..eac5fb1fc02
--- /dev/null
+++ b/drivers/rtc/rtc-omap.c
@@ -0,0 +1,572 @@
+/*
+ * TI OMAP1 Real Time Clock interface for Linux
+ *
+ * Copyright (C) 2003 MontaVista Software, Inc.
+ * Author: George G. Davis <gdavis@mvista.com> or <source@mvista.com>
+ *
+ * Copyright (C) 2006 David Brownell (new RTC framework)
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+#include <asm/mach/time.h>
+
+
+/* The OMAP1 RTC is a year/month/day/hours/minutes/seconds BCD clock
+ * with century-range alarm matching, driven by the 32kHz clock.
+ *
+ * The main user-visible ways it differs from PC RTCs are by omitting
+ * "don't care" alarm fields and sub-second periodic IRQs, and having
+ * an autoadjust mechanism to calibrate to the true oscillator rate.
+ *
+ * Board-specific wiring options include using split power mode with
+ * RTC_OFF_NOFF used as the reset signal (so the RTC won't be reset),
+ * and wiring RTC_WAKE_INT (so the RTC alarm can wake the system from
+ * low power modes). See the BOARD-SPECIFIC CUSTOMIZATION comment.
+ */
+
+#define OMAP_RTC_BASE 0xfffb4800
+
+/* RTC registers */
+#define OMAP_RTC_SECONDS_REG 0x00
+#define OMAP_RTC_MINUTES_REG 0x04
+#define OMAP_RTC_HOURS_REG 0x08
+#define OMAP_RTC_DAYS_REG 0x0C
+#define OMAP_RTC_MONTHS_REG 0x10
+#define OMAP_RTC_YEARS_REG 0x14
+#define OMAP_RTC_WEEKS_REG 0x18
+
+#define OMAP_RTC_ALARM_SECONDS_REG 0x20
+#define OMAP_RTC_ALARM_MINUTES_REG 0x24
+#define OMAP_RTC_ALARM_HOURS_REG 0x28
+#define OMAP_RTC_ALARM_DAYS_REG 0x2c
+#define OMAP_RTC_ALARM_MONTHS_REG 0x30
+#define OMAP_RTC_ALARM_YEARS_REG 0x34
+
+#define OMAP_RTC_CTRL_REG 0x40
+#define OMAP_RTC_STATUS_REG 0x44
+#define OMAP_RTC_INTERRUPTS_REG 0x48
+
+#define OMAP_RTC_COMP_LSB_REG 0x4c
+#define OMAP_RTC_COMP_MSB_REG 0x50
+#define OMAP_RTC_OSC_REG 0x54
+
+/* OMAP_RTC_CTRL_REG bit fields: */
+#define OMAP_RTC_CTRL_SPLIT (1<<7)
+#define OMAP_RTC_CTRL_DISABLE (1<<6)
+#define OMAP_RTC_CTRL_SET_32_COUNTER (1<<5)
+#define OMAP_RTC_CTRL_TEST (1<<4)
+#define OMAP_RTC_CTRL_MODE_12_24 (1<<3)
+#define OMAP_RTC_CTRL_AUTO_COMP (1<<2)
+#define OMAP_RTC_CTRL_ROUND_30S (1<<1)
+#define OMAP_RTC_CTRL_STOP (1<<0)
+
+/* OMAP_RTC_STATUS_REG bit fields: */
+#define OMAP_RTC_STATUS_POWER_UP (1<<7)
+#define OMAP_RTC_STATUS_ALARM (1<<6)
+#define OMAP_RTC_STATUS_1D_EVENT (1<<5)
+#define OMAP_RTC_STATUS_1H_EVENT (1<<4)
+#define OMAP_RTC_STATUS_1M_EVENT (1<<3)
+#define OMAP_RTC_STATUS_1S_EVENT (1<<2)
+#define OMAP_RTC_STATUS_RUN (1<<1)
+#define OMAP_RTC_STATUS_BUSY (1<<0)
+
+/* OMAP_RTC_INTERRUPTS_REG bit fields: */
+#define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3)
+#define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2)
+
+
+#define rtc_read(addr) omap_readb(OMAP_RTC_BASE + (addr))
+#define rtc_write(val, addr) omap_writeb(val, OMAP_RTC_BASE + (addr))
+
+
+/* platform_bus isn't hotpluggable, so for static linkage it'd be safe
+ * to get rid of probe() and remove() code ... too bad the driver struct
+ * remembers probe(), that's about 25% of the runtime footprint!!
+ */
+#ifndef MODULE
+#undef __devexit
+#undef __devexit_p
+#define __devexit __exit
+#define __devexit_p __exit_p
+#endif
+
+
+/* we rely on the rtc framework to handle locking (rtc->ops_lock),
+ * so the only other requirement is that register accesses which
+ * require BUSY to be clear are made with IRQs locally disabled
+ */
+static void rtc_wait_not_busy(void)
+{
+ int count = 0;
+ u8 status;
+
+ /* BUSY may stay active for 1/32768 second (~30 usec) */
+ for (count = 0; count < 50; count++) {
+ status = rtc_read(OMAP_RTC_STATUS_REG);
+ if ((status & (u8)OMAP_RTC_STATUS_BUSY) == 0)
+ break;
+ udelay(1);
+ }
+ /* now we have ~15 usec to read/write various registers */
+}
+
+static irqreturn_t rtc_irq(int irq, void *class_dev)
+{
+ unsigned long events = 0;
+ u8 irq_data;
+
+ irq_data = rtc_read(OMAP_RTC_STATUS_REG);
+
+ /* alarm irq? */
+ if (irq_data & OMAP_RTC_STATUS_ALARM) {
+ rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG);
+ events |= RTC_IRQF | RTC_AF;
+ }
+
+ /* 1/sec periodic/update irq? */
+ if (irq_data & OMAP_RTC_STATUS_1S_EVENT)
+ events |= RTC_IRQF | RTC_UF;
+
+ rtc_update_irq(class_dev, 1, events);
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_RTC_INTF_DEV
+
+static int
+omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+ u8 reg;
+
+ switch (cmd) {
+ case RTC_AIE_OFF:
+ case RTC_AIE_ON:
+ case RTC_UIE_OFF:
+ case RTC_UIE_ON:
+ break;
+ default:
+ return -ENOIOCTLCMD;
+ }
+
+ local_irq_disable();
+ rtc_wait_not_busy();
+ reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
+ switch (cmd) {
+ /* AIE = Alarm Interrupt Enable */
+ case RTC_AIE_OFF:
+ reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
+ break;
+ case RTC_AIE_ON:
+ reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
+ break;
+ /* UIE = Update Interrupt Enable (1/second) */
+ case RTC_UIE_OFF:
+ reg &= ~OMAP_RTC_INTERRUPTS_IT_TIMER;
+ break;
+ case RTC_UIE_ON:
+ reg |= OMAP_RTC_INTERRUPTS_IT_TIMER;
+ break;
+ }
+ rtc_wait_not_busy();
+ rtc_write(reg, OMAP_RTC_INTERRUPTS_REG);
+ local_irq_enable();
+
+ return 0;
+}
+
+#else
+#define omap_rtc_ioctl NULL
+#endif
+
+/* this hardware doesn't support "don't care" alarm fields */
+static int tm2bcd(struct rtc_time *tm)
+{
+ if (rtc_valid_tm(tm) != 0)
+ return -EINVAL;
+
+ tm->tm_sec = BIN2BCD(tm->tm_sec);
+ tm->tm_min = BIN2BCD(tm->tm_min);
+ tm->tm_hour = BIN2BCD(tm->tm_hour);
+ tm->tm_mday = BIN2BCD(tm->tm_mday);
+
+ tm->tm_mon = BIN2BCD(tm->tm_mon + 1);
+
+ /* epoch == 1900 */
+ if (tm->tm_year < 100 || tm->tm_year > 199)
+ return -EINVAL;
+ tm->tm_year = BIN2BCD(tm->tm_year - 100);
+
+ return 0;
+}
+
+static void bcd2tm(struct rtc_time *tm)
+{
+ tm->tm_sec = BCD2BIN(tm->tm_sec);
+ tm->tm_min = BCD2BIN(tm->tm_min);
+ tm->tm_hour = BCD2BIN(tm->tm_hour);
+ tm->tm_mday = BCD2BIN(tm->tm_mday);
+ tm->tm_mon = BCD2BIN(tm->tm_mon) - 1;
+ /* epoch == 1900 */
+ tm->tm_year = BCD2BIN(tm->tm_year) + 100;
+}
+
+
+static int omap_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ /* we don't report wday/yday/isdst ... */
+ local_irq_disable();
+ rtc_wait_not_busy();
+
+ tm->tm_sec = rtc_read(OMAP_RTC_SECONDS_REG);
+ tm->tm_min = rtc_read(OMAP_RTC_MINUTES_REG);
+ tm->tm_hour = rtc_read(OMAP_RTC_HOURS_REG);
+ tm->tm_mday = rtc_read(OMAP_RTC_DAYS_REG);
+ tm->tm_mon = rtc_read(OMAP_RTC_MONTHS_REG);
+ tm->tm_year = rtc_read(OMAP_RTC_YEARS_REG);
+
+ local_irq_enable();
+
+ bcd2tm(tm);
+ return 0;
+}
+
+static int omap_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ if (tm2bcd(tm) < 0)
+ return -EINVAL;
+ local_irq_disable();
+ rtc_wait_not_busy();
+
+ rtc_write(tm->tm_year, OMAP_RTC_YEARS_REG);
+ rtc_write(tm->tm_mon, OMAP_RTC_MONTHS_REG);
+ rtc_write(tm->tm_mday, OMAP_RTC_DAYS_REG);
+ rtc_write(tm->tm_hour, OMAP_RTC_HOURS_REG);
+ rtc_write(tm->tm_min, OMAP_RTC_MINUTES_REG);
+ rtc_write(tm->tm_sec, OMAP_RTC_SECONDS_REG);
+
+ local_irq_enable();
+
+ return 0;
+}
+
+static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+ local_irq_disable();
+ rtc_wait_not_busy();
+
+ alm->time.tm_sec = rtc_read(OMAP_RTC_ALARM_SECONDS_REG);
+ alm->time.tm_min = rtc_read(OMAP_RTC_ALARM_MINUTES_REG);
+ alm->time.tm_hour = rtc_read(OMAP_RTC_ALARM_HOURS_REG);
+ alm->time.tm_mday = rtc_read(OMAP_RTC_ALARM_DAYS_REG);
+ alm->time.tm_mon = rtc_read(OMAP_RTC_ALARM_MONTHS_REG);
+ alm->time.tm_year = rtc_read(OMAP_RTC_ALARM_YEARS_REG);
+
+ local_irq_enable();
+
+ bcd2tm(&alm->time);
+ alm->pending = !!(rtc_read(OMAP_RTC_INTERRUPTS_REG)
+ & OMAP_RTC_INTERRUPTS_IT_ALARM);
+ alm->enabled = alm->pending && device_may_wakeup(dev);
+
+ return 0;
+}
+
+static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+ u8 reg;
+
+ /* Much userspace code uses RTC_ALM_SET, thus "don't care" for
+ * day/month/year specifies alarms up to 24 hours in the future.
+ * So we need to handle that ... but let's ignore the "don't care"
+ * values for hours/minutes/seconds.
+ */
+ if (alm->time.tm_mday <= 0
+ && alm->time.tm_mon < 0
+ && alm->time.tm_year < 0) {
+ struct rtc_time tm;
+ unsigned long now, then;
+
+ omap_rtc_read_time(dev, &tm);
+ rtc_tm_to_time(&tm, &now);
+
+ alm->time.tm_mday = tm.tm_mday;
+ alm->time.tm_mon = tm.tm_mon;
+ alm->time.tm_year = tm.tm_year;
+ rtc_tm_to_time(&alm->time, &then);
+
+ /* sometimes the alarm wraps into tomorrow */
+ if (then < now) {
+ rtc_time_to_tm(now + 24 * 60 * 60, &tm);
+ alm->time.tm_mday = tm.tm_mday;
+ alm->time.tm_mon = tm.tm_mon;
+ alm->time.tm_year = tm.tm_year;
+ }
+ }
+
+ if (tm2bcd(&alm->time) < 0)
+ return -EINVAL;
+
+ local_irq_disable();
+ rtc_wait_not_busy();
+
+ rtc_write(alm->time.tm_year, OMAP_RTC_ALARM_YEARS_REG);
+ rtc_write(alm->time.tm_mon, OMAP_RTC_ALARM_MONTHS_REG);
+ rtc_write(alm->time.tm_mday, OMAP_RTC_ALARM_DAYS_REG);
+ rtc_write(alm->time.tm_hour, OMAP_RTC_ALARM_HOURS_REG);
+ rtc_write(alm->time.tm_min, OMAP_RTC_ALARM_MINUTES_REG);
+ rtc_write(alm->time.tm_sec, OMAP_RTC_ALARM_SECONDS_REG);
+
+ reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
+ if (alm->enabled)
+ reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
+ else
+ reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
+ rtc_write(reg, OMAP_RTC_INTERRUPTS_REG);
+
+ local_irq_enable();
+
+ return 0;
+}
+
+static struct rtc_class_ops omap_rtc_ops = {
+ .ioctl = omap_rtc_ioctl,
+ .read_time = omap_rtc_read_time,
+ .set_time = omap_rtc_set_time,
+ .read_alarm = omap_rtc_read_alarm,
+ .set_alarm = omap_rtc_set_alarm,
+};
+
+static int omap_rtc_alarm;
+static int omap_rtc_timer;
+
+static int __devinit omap_rtc_probe(struct platform_device *pdev)
+{
+ struct resource *res, *mem;
+ struct rtc_device *rtc;
+ u8 reg, new_ctrl;
+
+ omap_rtc_timer = platform_get_irq(pdev, 0);
+ if (omap_rtc_timer <= 0) {
+ pr_debug("%s: no update irq?\n", pdev->name);
+ return -ENOENT;
+ }
+
+ omap_rtc_alarm = platform_get_irq(pdev, 1);
+ if (omap_rtc_alarm <= 0) {
+ pr_debug("%s: no alarm irq?\n", pdev->name);
+ return -ENOENT;
+ }
+
+ /* NOTE: using static mapping for RTC registers */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res && res->start != OMAP_RTC_BASE) {
+ pr_debug("%s: RTC registers at %08x, expected %08x\n",
+ pdev->name, (unsigned) res->start, OMAP_RTC_BASE);
+ return -ENOENT;
+ }
+
+ if (res)
+ mem = request_mem_region(res->start,
+ res->end - res->start + 1,
+ pdev->name);
+ else
+ mem = NULL;
+ if (!mem) {
+ pr_debug("%s: RTC registers at %08x are not free\n",
+ pdev->name, OMAP_RTC_BASE);
+ return -EBUSY;
+ }
+
+ rtc = rtc_device_register(pdev->name, &pdev->dev,
+ &omap_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc)) {
+ pr_debug("%s: can't register RTC device, err %ld\n",
+ pdev->name, PTR_ERR(rtc));
+ goto fail;
+ }
+ platform_set_drvdata(pdev, rtc);
+ class_set_devdata(&rtc->class_dev, mem);
+
+ /* clear pending irqs, and set 1/second periodic,
+ * which we'll use instead of update irqs
+ */
+ rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
+
+ /* clear old status */
+ reg = rtc_read(OMAP_RTC_STATUS_REG);
+ if (reg & (u8) OMAP_RTC_STATUS_POWER_UP) {
+ pr_info("%s: RTC power up reset detected\n",
+ pdev->name);
+ rtc_write(OMAP_RTC_STATUS_POWER_UP, OMAP_RTC_STATUS_REG);
+ }
+ if (reg & (u8) OMAP_RTC_STATUS_ALARM)
+ rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG);
+
+ /* handle periodic and alarm irqs */
+ if (request_irq(omap_rtc_timer, rtc_irq, SA_INTERRUPT,
+ rtc->class_dev.class_id, &rtc->class_dev)) {
+ pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
+ pdev->name, omap_rtc_timer);
+ goto fail0;
+ }
+ if (request_irq(omap_rtc_alarm, rtc_irq, SA_INTERRUPT,
+ rtc->class_dev.class_id, &rtc->class_dev)) {
+ pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
+ pdev->name, omap_rtc_alarm);
+ goto fail1;
+ }
+
+ /* On boards with split power, RTC_ON_NOFF won't reset the RTC */
+ reg = rtc_read(OMAP_RTC_CTRL_REG);
+ if (reg & (u8) OMAP_RTC_CTRL_STOP)
+ pr_info("%s: already running\n", pdev->name);
+
+ /* force to 24 hour mode */
+ new_ctrl = reg & ~(OMAP_RTC_CTRL_SPLIT|OMAP_RTC_CTRL_AUTO_COMP);
+ new_ctrl |= OMAP_RTC_CTRL_STOP;
+
+ /* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE:
+ *
+ * - Boards wired so that RTC_WAKE_INT does something, and muxed
+ * right (W13_1610_RTC_WAKE_INT is the default after chip reset),
+ * should initialize the device wakeup flag appropriately.
+ *
+ * - Boards wired so RTC_ON_nOFF is used as the reset signal,
+ * rather than nPWRON_RESET, should forcibly enable split
+ * power mode. (Some chip errata report that RTC_CTRL_SPLIT
+ * is write-only, and always reads as zero...)
+ */
+ device_init_wakeup(&pdev->dev, 0);
+
+ if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT)
+ pr_info("%s: split power mode\n", pdev->name);
+
+ if (reg != new_ctrl)
+ rtc_write(new_ctrl, OMAP_RTC_CTRL_REG);
+
+ return 0;
+
+fail1:
+ free_irq(omap_rtc_timer, NULL);
+fail0:
+ rtc_device_unregister(rtc);
+fail:
+ release_resource(mem);
+ return -EIO;
+}
+
+static int __devexit omap_rtc_remove(struct platform_device *pdev)
+{
+ struct rtc_device *rtc = platform_get_drvdata(pdev);;
+
+ device_init_wakeup(&pdev->dev, 0);
+
+ /* leave rtc running, but disable irqs */
+ rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
+
+ free_irq(omap_rtc_timer, rtc);
+ free_irq(omap_rtc_alarm, rtc);
+
+ release_resource(class_get_devdata(&rtc->class_dev));
+ rtc_device_unregister(rtc);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+static struct timespec rtc_delta;
+static u8 irqstat;
+
+static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct rtc_time rtc_tm;
+ struct timespec time;
+
+ time.tv_nsec = 0;
+ omap_rtc_read_time(NULL, &rtc_tm);
+ rtc_tm_to_time(&rtc_tm, &time.tv_sec);
+
+ save_time_delta(&rtc_delta, &time);
+ irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG);
+
+ /* FIXME the RTC alarm is not currently acting as a wakeup event
+ * source, and in fact this enable() call is just saving a flag
+ * that's never used...
+ */
+ if (device_may_wakeup(&pdev->dev))
+ enable_irq_wake(omap_rtc_alarm);
+ else
+ rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
+
+ return 0;
+}
+
+static int omap_rtc_resume(struct platform_device *pdev)
+{
+ struct rtc_time rtc_tm;
+ struct timespec time;
+
+ time.tv_nsec = 0;
+ omap_rtc_read_time(NULL, &rtc_tm);
+ rtc_tm_to_time(&rtc_tm, &time.tv_sec);
+
+ restore_time_delta(&rtc_delta, &time);
+ if (device_may_wakeup(&pdev->dev))
+ disable_irq_wake(omap_rtc_alarm);
+ else
+ rtc_write(irqstat, OMAP_RTC_INTERRUPTS_REG);
+ return 0;
+}
+
+#else
+#define omap_rtc_suspend NULL
+#define omap_rtc_resume NULL
+#endif
+
+static void omap_rtc_shutdown(struct platform_device *pdev)
+{
+ rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
+}
+
+MODULE_ALIAS("omap_rtc");
+static struct platform_driver omap_rtc_driver = {
+ .probe = omap_rtc_probe,
+ .remove = __devexit_p(omap_rtc_remove),
+ .suspend = omap_rtc_suspend,
+ .resume = omap_rtc_resume,
+ .shutdown = omap_rtc_shutdown,
+ .driver = {
+ .name = "omap_rtc",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init rtc_init(void)
+{
+ return platform_driver_register(&omap_rtc_driver);
+}
+module_init(rtc_init);
+
+static void __exit rtc_exit(void)
+{
+ platform_driver_unregister(&omap_rtc_driver);
+}
+module_exit(rtc_exit);
+
+MODULE_AUTHOR("George G. Davis (and others)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index a44fe4efa21..e2c7698fdba 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -13,7 +13,7 @@
#include <linux/rtc.h>
#include <linux/bcd.h>
-#define DRV_VERSION "0.2"
+#define DRV_VERSION "0.3"
/* Addresses to scan */
static unsigned short normal_i2c[] = { /* 0x32,*/ I2C_CLIENT_END };
@@ -39,6 +39,14 @@ static int rs5c372_attach(struct i2c_adapter *adapter);
static int rs5c372_detach(struct i2c_client *client);
static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind);
+struct rs5c372 {
+ u8 reg_addr;
+ u8 regs[17];
+ struct i2c_msg msg[1];
+ struct i2c_client client;
+ struct rtc_device *rtc;
+};
+
static struct i2c_driver rs5c372_driver = {
.driver = {
.name = "rs5c372",
@@ -49,18 +57,16 @@ static struct i2c_driver rs5c372_driver = {
static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm)
{
- unsigned char buf[7] = { RS5C372_REG_BASE };
- /* this implements the 1st reading method, according
- * to the datasheet. buf[0] is initialized with
- * address ptr and transmission format register.
+ struct rs5c372 *rs5c372 = i2c_get_clientdata(client);
+ u8 *buf = &(rs5c372->regs[1]);
+
+ /* this implements the 3rd reading method, according
+ * to the datasheet. rs5c372 defaults to internal
+ * address 0xF, so 0x0 is in regs[1]
*/
- struct i2c_msg msgs[] = {
- { client->addr, 0, 1, buf },
- { client->addr, I2C_M_RD, 7, buf },
- };
- if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
+ if ((i2c_transfer(client->adapter, rs5c372->msg, 1)) != 1) {
dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
return -EIO;
}
@@ -114,23 +120,14 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm)
static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim)
{
- unsigned char buf = RS5C372_REG_TRIM;
-
- struct i2c_msg msgs[] = {
- { client->addr, 0, 1, &buf },
- { client->addr, I2C_M_RD, 1, &buf },
- };
-
- if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
- dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
- return -EIO;
- }
+ struct rs5c372 *rs5c372 = i2c_get_clientdata(client);
+ u8 tmp = rs5c372->regs[RS5C372_REG_TRIM + 1];
if (osc)
- *osc = (buf & RS5C372_TRIM_XSL) ? 32000 : 32768;
+ *osc = (tmp & RS5C372_TRIM_XSL) ? 32000 : 32768;
if (trim) {
- *trim = buf & RS5C372_TRIM_MASK;
+ *trim = tmp & RS5C372_TRIM_MASK;
dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, *trim);
}
@@ -201,7 +198,7 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind)
{
int err = 0;
struct i2c_client *client;
- struct rtc_device *rtc;
+ struct rs5c372 *rs5c372;
dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
@@ -210,10 +207,11 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind)
goto exit;
}
- if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
+ if (!(rs5c372 = kzalloc(sizeof(struct rs5c372), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
+ client = &rs5c372->client;
/* I2C client */
client->addr = address;
@@ -222,32 +220,47 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind)
strlcpy(client->name, rs5c372_driver.driver.name, I2C_NAME_SIZE);
+ i2c_set_clientdata(client, rs5c372);
+
+ rs5c372->msg[0].addr = address;
+ rs5c372->msg[0].flags = I2C_M_RD;
+ rs5c372->msg[0].len = sizeof(rs5c372->regs);
+ rs5c372->msg[0].buf = rs5c372->regs;
+
/* Inform the i2c layer */
if ((err = i2c_attach_client(client)))
goto exit_kfree;
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
- rtc = rtc_device_register(rs5c372_driver.driver.name, &client->dev,
- &rs5c372_rtc_ops, THIS_MODULE);
+ rs5c372->rtc = rtc_device_register(rs5c372_driver.driver.name,
+ &client->dev, &rs5c372_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc)) {
- err = PTR_ERR(rtc);
+ if (IS_ERR(rs5c372->rtc)) {
+ err = PTR_ERR(rs5c372->rtc);
goto exit_detach;
}
- i2c_set_clientdata(client, rtc);
-
- device_create_file(&client->dev, &dev_attr_trim);
- device_create_file(&client->dev, &dev_attr_osc);
+ err = device_create_file(&client->dev, &dev_attr_trim);
+ if (err)
+ goto exit_devreg;
+ err = device_create_file(&client->dev, &dev_attr_osc);
+ if (err)
+ goto exit_trim;
return 0;
+exit_trim:
+ device_remove_file(&client->dev, &dev_attr_trim);
+
+exit_devreg:
+ rtc_device_unregister(rs5c372->rtc);
+
exit_detach:
i2c_detach_client(client);
exit_kfree:
- kfree(client);
+ kfree(rs5c372);
exit:
return err;
@@ -256,16 +269,15 @@ exit:
static int rs5c372_detach(struct i2c_client *client)
{
int err;
- struct rtc_device *rtc = i2c_get_clientdata(client);
+ struct rs5c372 *rs5c372 = i2c_get_clientdata(client);
- if (rtc)
- rtc_device_unregister(rtc);
+ if (rs5c372->rtc)
+ rtc_device_unregister(rs5c372->rtc);
if ((err = i2c_detach_client(client)))
return err;
- kfree(client);
-
+ kfree(rs5c372);
return 0;
}
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c
index 6ef9c62d503..f50a1b8e160 100644
--- a/drivers/rtc/rtc-test.c
+++ b/drivers/rtc/rtc-test.c
@@ -123,11 +123,18 @@ static int test_probe(struct platform_device *plat_dev)
err = PTR_ERR(rtc);
return err;
}
- device_create_file(&plat_dev->dev, &dev_attr_irq);
+
+ err = device_create_file(&plat_dev->dev, &dev_attr_irq);
+ if (err)
+ goto err;
platform_set_drvdata(plat_dev, rtc);
return 0;
+
+err:
+ rtc_device_unregister(rtc);
+ return err;
}
static int __devexit test_remove(struct platform_device *plat_dev)
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c
index 522c69753bb..9a67487d086 100644
--- a/drivers/rtc/rtc-x1205.c
+++ b/drivers/rtc/rtc-x1205.c
@@ -562,11 +562,19 @@ static int x1205_probe(struct i2c_adapter *adapter, int address, int kind)
else
dev_err(&client->dev, "couldn't read status\n");
- device_create_file(&client->dev, &dev_attr_atrim);
- device_create_file(&client->dev, &dev_attr_dtrim);
+ err = device_create_file(&client->dev, &dev_attr_atrim);
+ if (err) goto exit_devreg;
+ err = device_create_file(&client->dev, &dev_attr_dtrim);
+ if (err) goto exit_atrim;
return 0;
+exit_atrim:
+ device_remove_file(&client->dev, &dev_attr_atrim);
+
+exit_devreg:
+ rtc_device_unregister(rtc);
+
exit_detach:
i2c_detach_client(client);
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 17fdd8c9f74..cf28ccc5794 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -25,7 +25,7 @@
#include "dasd_int.h"
-kmem_cache_t *dasd_page_cache;
+struct kmem_cache *dasd_page_cache;
EXPORT_SYMBOL_GPL(dasd_page_cache);
/*
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 5ecea3e4fde..fdaa471e845 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1215,7 +1215,7 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req)
dst = page_address(bv->bv_page) + bv->bv_offset;
if (dasd_page_cache) {
char *copy = kmem_cache_alloc(dasd_page_cache,
- SLAB_DMA | __GFP_NOWARN);
+ GFP_DMA | __GFP_NOWARN);
if (copy && rq_data_dir(req) == WRITE)
memcpy(copy + bv->bv_offset, dst, bv->bv_len);
if (copy)
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 80926c54822..b857fd5893f 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -308,7 +308,7 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req)
dst = page_address(bv->bv_page) + bv->bv_offset;
if (dasd_page_cache) {
char *copy = kmem_cache_alloc(dasd_page_cache,
- SLAB_DMA | __GFP_NOWARN);
+ GFP_DMA | __GFP_NOWARN);
if (copy && rq_data_dir(req) == WRITE)
memcpy(copy + bv->bv_offset, dst, bv->bv_len);
if (copy)
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 9f52004f6fc..dc5dd509434 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -474,7 +474,7 @@ extern struct dasd_profile_info_t dasd_global_profile;
extern unsigned int dasd_profile_level;
extern struct block_device_operations dasd_device_operations;
-extern kmem_cache_t *dasd_page_cache;
+extern struct kmem_cache *dasd_page_cache;
struct dasd_ccw_req *
dasd_kmalloc_request(char *, int, int, struct dasd_device *);
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 74c0eac083e..32933ed54b8 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -1032,9 +1032,9 @@ struct zfcp_data {
wwn_t init_wwpn;
fcp_lun_t init_fcp_lun;
char *driver_version;
- kmem_cache_t *fsf_req_qtcb_cache;
- kmem_cache_t *sr_buffer_cache;
- kmem_cache_t *gid_pn_cache;
+ struct kmem_cache *fsf_req_qtcb_cache;
+ struct kmem_cache *sr_buffer_cache;
+ struct kmem_cache *gid_pn_cache;
};
/**
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 277826cdd0c..067f1519eb0 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -109,7 +109,7 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags)
ptr = kmalloc(size, GFP_ATOMIC);
else
ptr = kmem_cache_alloc(zfcp_data.fsf_req_qtcb_cache,
- SLAB_ATOMIC);
+ GFP_ATOMIC);
}
if (unlikely(!ptr))
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index 335a25540c0..68103e508db 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -313,7 +313,7 @@ NCR_700_detect(struct scsi_host_template *tpnt,
hostdata->status = memory + STATUS_OFFSET;
/* all of these offsets are L1_CACHE_BYTES separated. It is fatal
* if this isn't sufficient separation to avoid dma flushing issues */
- BUG_ON(!dma_is_consistent(pScript) && L1_CACHE_BYTES < dma_get_cache_alignment());
+ BUG_ON(!dma_is_consistent(hostdata->dev, pScript) && L1_CACHE_BYTES < dma_get_cache_alignment());
hostdata->slots = (struct NCR_700_command_slot *)(memory + SLOTS_OFFSET);
hostdata->dev = dev;
@@ -362,11 +362,11 @@ NCR_700_detect(struct scsi_host_template *tpnt,
for (j = 0; j < PATCHES; j++)
script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]);
/* now patch up fixed addresses. */
- script_patch_32(script, MessageLocation,
+ script_patch_32(hostdata->dev, script, MessageLocation,
pScript + MSGOUT_OFFSET);
- script_patch_32(script, StatusAddress,
+ script_patch_32(hostdata->dev, script, StatusAddress,
pScript + STATUS_OFFSET);
- script_patch_32(script, ReceiveMsgAddress,
+ script_patch_32(hostdata->dev, script, ReceiveMsgAddress,
pScript + MSGIN_OFFSET);
hostdata->script = script;
@@ -821,8 +821,9 @@ process_extended_message(struct Scsi_Host *host,
shost_printk(KERN_WARNING, host,
"Unexpected SDTR msg\n");
hostdata->msgout[0] = A_REJECT_MSG;
- dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE);
- script_patch_16(hostdata->script, MessageCount, 1);
+ dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
+ script_patch_16(hostdata->dev, hostdata->script,
+ MessageCount, 1);
/* SendMsgOut returns, so set up the return
* address */
resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
@@ -833,8 +834,9 @@ process_extended_message(struct Scsi_Host *host,
printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n",
host->host_no, pun, lun);
hostdata->msgout[0] = A_REJECT_MSG;
- dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE);
- script_patch_16(hostdata->script, MessageCount, 1);
+ dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
+ script_patch_16(hostdata->dev, hostdata->script, MessageCount,
+ 1);
resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
break;
@@ -847,8 +849,9 @@ process_extended_message(struct Scsi_Host *host,
printk("\n");
/* just reject it */
hostdata->msgout[0] = A_REJECT_MSG;
- dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE);
- script_patch_16(hostdata->script, MessageCount, 1);
+ dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
+ script_patch_16(hostdata->dev, hostdata->script, MessageCount,
+ 1);
/* SendMsgOut returns, so set up the return
* address */
resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
@@ -929,8 +932,9 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata
printk("\n");
/* just reject it */
hostdata->msgout[0] = A_REJECT_MSG;
- dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE);
- script_patch_16(hostdata->script, MessageCount, 1);
+ dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
+ script_patch_16(hostdata->dev, hostdata->script, MessageCount,
+ 1);
/* SendMsgOut returns, so set up the return
* address */
resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
@@ -939,7 +943,7 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata
}
NCR_700_writel(temp, host, TEMP_REG);
/* set us up to receive another message */
- dma_cache_sync(hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE);
+ dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE);
return resume_offset;
}
@@ -1019,9 +1023,9 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
slot->SG[1].ins = bS_to_host(SCRIPT_RETURN);
slot->SG[1].pAddr = 0;
slot->resume_offset = hostdata->pScript;
- dma_cache_sync(slot->SG, sizeof(slot->SG[0])*2, DMA_TO_DEVICE);
- dma_cache_sync(SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
-
+ dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG[0])*2, DMA_TO_DEVICE);
+ dma_cache_sync(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
+
/* queue the command for reissue */
slot->state = NCR_700_SLOT_QUEUED;
slot->flags = NCR_700_FLAG_AUTOSENSE;
@@ -1136,11 +1140,12 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
hostdata->cmd = slot->cmnd;
/* re-patch for this command */
- script_patch_32_abs(hostdata->script, CommandAddress,
- slot->pCmd);
- script_patch_16(hostdata->script,
+ script_patch_32_abs(hostdata->dev, hostdata->script,
+ CommandAddress, slot->pCmd);
+ script_patch_16(hostdata->dev, hostdata->script,
CommandCount, slot->cmnd->cmd_len);
- script_patch_32_abs(hostdata->script, SGScriptStartAddress,
+ script_patch_32_abs(hostdata->dev, hostdata->script,
+ SGScriptStartAddress,
to32bit(&slot->pSG[0].ins));
/* Note: setting SXFER only works if we're
@@ -1150,13 +1155,13 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
* should therefore always clear ACK */
NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device),
host, SXFER_REG);
- dma_cache_sync(hostdata->msgin,
+ dma_cache_sync(hostdata->dev, hostdata->msgin,
MSG_ARRAY_SIZE, DMA_FROM_DEVICE);
- dma_cache_sync(hostdata->msgout,
+ dma_cache_sync(hostdata->dev, hostdata->msgout,
MSG_ARRAY_SIZE, DMA_TO_DEVICE);
/* I'm just being paranoid here, the command should
* already have been flushed from the cache */
- dma_cache_sync(slot->cmnd->cmnd,
+ dma_cache_sync(hostdata->dev, slot->cmnd->cmnd,
slot->cmnd->cmd_len, DMA_TO_DEVICE);
@@ -1220,7 +1225,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
hostdata->reselection_id = reselection_id;
/* just in case we have a stale simple tag message, clear it */
hostdata->msgin[1] = 0;
- dma_cache_sync(hostdata->msgin,
+ dma_cache_sync(hostdata->dev, hostdata->msgin,
MSG_ARRAY_SIZE, DMA_BIDIRECTIONAL);
if(hostdata->tag_negotiated & (1<<reselection_id)) {
resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;
@@ -1336,7 +1341,7 @@ process_selection(struct Scsi_Host *host, __u32 dsp)
hostdata->cmd = NULL;
/* clear any stale simple tag message */
hostdata->msgin[1] = 0;
- dma_cache_sync(hostdata->msgin, MSG_ARRAY_SIZE,
+ dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE,
DMA_BIDIRECTIONAL);
if(id == 0xff) {
@@ -1433,29 +1438,30 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
}
- script_patch_16(hostdata->script, MessageCount, count);
+ script_patch_16(hostdata->dev, hostdata->script, MessageCount, count);
- script_patch_ID(hostdata->script,
+ script_patch_ID(hostdata->dev, hostdata->script,
Device_ID, 1<<scmd_id(SCp));
- script_patch_32_abs(hostdata->script, CommandAddress,
+ script_patch_32_abs(hostdata->dev, hostdata->script, CommandAddress,
slot->pCmd);
- script_patch_16(hostdata->script, CommandCount, SCp->cmd_len);
+ script_patch_16(hostdata->dev, hostdata->script, CommandCount,
+ SCp->cmd_len);
/* finally plumb the beginning of the SG list into the script
* */
- script_patch_32_abs(hostdata->script, SGScriptStartAddress,
- to32bit(&slot->pSG[0].ins));
+ script_patch_32_abs(hostdata->dev, hostdata->script,
+ SGScriptStartAddress, to32bit(&slot->pSG[0].ins));
NCR_700_clear_fifo(SCp->device->host);
if(slot->resume_offset == 0)
slot->resume_offset = hostdata->pScript;
/* now perform all the writebacks and invalidates */
- dma_cache_sync(hostdata->msgout, count, DMA_TO_DEVICE);
- dma_cache_sync(hostdata->msgin, MSG_ARRAY_SIZE,
+ dma_cache_sync(hostdata->dev, hostdata->msgout, count, DMA_TO_DEVICE);
+ dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE,
DMA_FROM_DEVICE);
- dma_cache_sync(SCp->cmnd, SCp->cmd_len, DMA_TO_DEVICE);
- dma_cache_sync(hostdata->status, 1, DMA_FROM_DEVICE);
+ dma_cache_sync(hostdata->dev, SCp->cmnd, SCp->cmd_len, DMA_TO_DEVICE);
+ dma_cache_sync(hostdata->dev, hostdata->status, 1, DMA_FROM_DEVICE);
/* set the synchronous period/offset */
NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
@@ -1631,7 +1637,7 @@ NCR_700_intr(int irq, void *dev_id)
slot->SG[i].ins = bS_to_host(SCRIPT_NOP);
slot->SG[i].pAddr = 0;
}
- dma_cache_sync(slot->SG, sizeof(slot->SG), DMA_TO_DEVICE);
+ dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG), DMA_TO_DEVICE);
/* and pretend we disconnected after
* the command phase */
resume_offset = hostdata->pScript + Ent_MsgInDuringData;
@@ -1897,9 +1903,9 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
}
slot->SG[i].ins = bS_to_host(SCRIPT_RETURN);
slot->SG[i].pAddr = 0;
- dma_cache_sync(slot->SG, sizeof(slot->SG), DMA_TO_DEVICE);
+ dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG), DMA_TO_DEVICE);
DEBUG((" SETTING %08lx to %x\n",
- (&slot->pSG[i].ins),
+ (&slot->pSG[i].ins),
slot->SG[i].ins));
}
slot->resume_offset = 0;
diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h
index f5c3caf344a..f38822db421 100644
--- a/drivers/scsi/53c700.h
+++ b/drivers/scsi/53c700.h
@@ -415,31 +415,31 @@ struct NCR_700_Host_Parameters {
#define NCR_710_MIN_XFERP 0
#define NCR_700_MIN_PERIOD 25 /* for SDTR message, 100ns */
-#define script_patch_32(script, symbol, value) \
+#define script_patch_32(dev, script, symbol, value) \
{ \
int i; \
for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \
__u32 val = bS_to_cpu((script)[A_##symbol##_used[i]]) + value; \
(script)[A_##symbol##_used[i]] = bS_to_host(val); \
- dma_cache_sync(&(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \
+ dma_cache_sync((dev), &(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \
DEBUG((" script, patching %s at %d to 0x%lx\n", \
#symbol, A_##symbol##_used[i], (value))); \
} \
}
-#define script_patch_32_abs(script, symbol, value) \
+#define script_patch_32_abs(dev, script, symbol, value) \
{ \
int i; \
for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \
(script)[A_##symbol##_used[i]] = bS_to_host(value); \
- dma_cache_sync(&(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \
+ dma_cache_sync((dev), &(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \
DEBUG((" script, patching %s at %d to 0x%lx\n", \
#symbol, A_##symbol##_used[i], (value))); \
} \
}
/* Used for patching the SCSI ID in the SELECT instruction */
-#define script_patch_ID(script, symbol, value) \
+#define script_patch_ID(dev, script, symbol, value) \
{ \
int i; \
for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \
@@ -447,13 +447,13 @@ struct NCR_700_Host_Parameters {
val &= 0xff00ffff; \
val |= ((value) & 0xff) << 16; \
(script)[A_##symbol##_used[i]] = bS_to_host(val); \
- dma_cache_sync(&(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \
+ dma_cache_sync((dev), &(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \
DEBUG((" script, patching ID field %s at %d to 0x%x\n", \
#symbol, A_##symbol##_used[i], val)); \
} \
}
-#define script_patch_16(script, symbol, value) \
+#define script_patch_16(dev, script, symbol, value) \
{ \
int i; \
for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \
@@ -461,7 +461,7 @@ struct NCR_700_Host_Parameters {
val &= 0xffff0000; \
val |= ((value) & 0xffff); \
(script)[A_##symbol##_used[i]] = bS_to_host(val); \
- dma_cache_sync(&(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \
+ dma_cache_sync((dev), &(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \
DEBUG((" script, patching short field %s at %d to 0x%x\n", \
#symbol, A_##symbol##_used[i], val)); \
} \
diff --git a/drivers/scsi/aic94xx/aic94xx.h b/drivers/scsi/aic94xx/aic94xx.h
index 71a031df7a3..32f513b1b78 100644
--- a/drivers/scsi/aic94xx/aic94xx.h
+++ b/drivers/scsi/aic94xx/aic94xx.h
@@ -56,8 +56,8 @@
/* 2*ITNL timeout + 1 second */
#define AIC94XX_SCB_TIMEOUT (5*HZ)
-extern kmem_cache_t *asd_dma_token_cache;
-extern kmem_cache_t *asd_ascb_cache;
+extern struct kmem_cache *asd_dma_token_cache;
+extern struct kmem_cache *asd_ascb_cache;
extern char sas_addr_str[2*SAS_ADDR_SIZE + 1];
static inline void asd_stringify_sas_addr(char *p, const u8 *sas_addr)
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c
index af7e0113436..da94e126ca8 100644
--- a/drivers/scsi/aic94xx/aic94xx_hwi.c
+++ b/drivers/scsi/aic94xx/aic94xx_hwi.c
@@ -1047,7 +1047,7 @@ irqreturn_t asd_hw_isr(int irq, void *dev_id)
static inline struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha,
gfp_t gfp_flags)
{
- extern kmem_cache_t *asd_ascb_cache;
+ extern struct kmem_cache *asd_ascb_cache;
struct asd_seq_data *seq = &asd_ha->seq;
struct asd_ascb *ascb;
unsigned long flags;
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
index 42302ef05ee..fbc82b00a41 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -450,8 +450,8 @@ static inline void asd_destroy_ha_caches(struct asd_ha_struct *asd_ha)
asd_ha->scb_pool = NULL;
}
-kmem_cache_t *asd_dma_token_cache;
-kmem_cache_t *asd_ascb_cache;
+struct kmem_cache *asd_dma_token_cache;
+struct kmem_cache *asd_ascb_cache;
static int asd_create_global_caches(void)
{
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 1427a41e844..8f6b5bf580f 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -110,6 +110,7 @@ typedef struct ide_scsi_obj {
} idescsi_scsi_t;
static DEFINE_MUTEX(idescsi_ref_mutex);
+static int idescsi_nocd; /* Set by module param to skip cd */
#define ide_scsi_g(disk) \
container_of((disk)->private_data, struct ide_scsi_obj, driver)
@@ -1127,6 +1128,9 @@ static int ide_scsi_probe(ide_drive_t *drive)
warned = 1;
}
+ if (idescsi_nocd && drive->media == ide_cdrom)
+ return -ENODEV;
+
if (!strstr("ide-scsi", drive->driver_req) ||
!drive->present ||
drive->media == ide_disk ||
@@ -1187,6 +1191,8 @@ static void __exit exit_idescsi_module(void)
driver_unregister(&idescsi_driver.gen_driver);
}
+module_param(idescsi_nocd, int, 0600);
+MODULE_PARM_DESC(idescsi_nocd, "Disable handling of CD-ROMs so they may be driven by ide-cd");
module_init(init_idescsi_module);
module_exit(exit_idescsi_module);
MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index ccd4dafce8e..b318500785e 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -6940,7 +6940,7 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
return -ENOMEM;
for (i = 0; i < IPR_NUM_CMD_BLKS; i++) {
- ipr_cmd = pci_pool_alloc (ioa_cfg->ipr_cmd_pool, SLAB_KERNEL, &dma_addr);
+ ipr_cmd = pci_pool_alloc (ioa_cfg->ipr_cmd_pool, GFP_KERNEL, &dma_addr);
if (!ipr_cmd) {
ipr_free_cmd_blks(ioa_cfg);
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c
index d65bc4e0f21..2f0c07fc3f4 100644
--- a/drivers/scsi/libsas/sas_init.c
+++ b/drivers/scsi/libsas/sas_init.c
@@ -36,7 +36,7 @@
#include "../scsi_sas_internal.h"
-kmem_cache_t *sas_task_cache;
+struct kmem_cache *sas_task_cache;
/*------------ SAS addr hash -----------*/
void sas_hash_addr(u8 *hashed, const u8 *sas_addr)
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index cbe0cad83b6..d03523d3bf3 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -24,7 +24,7 @@ char qla2x00_version_str[40];
/*
* SRB allocation cache
*/
-static kmem_cache_t *srb_cachep;
+static struct kmem_cache *srb_cachep;
/*
* Ioctl related information.
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 969c9e43102..9ef693c8809 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -19,7 +19,7 @@ char qla4xxx_version_str[40];
/*
* SRB allocation cache
*/
-static kmem_cache_t *srb_cachep;
+static struct kmem_cache *srb_cachep;
/*
* Module parameter information and variables
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index fafc00deaad..24cffd98ee6 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -136,7 +136,7 @@ const char * scsi_device_type(unsigned type)
EXPORT_SYMBOL(scsi_device_type);
struct scsi_host_cmd_pool {
- kmem_cache_t *slab;
+ struct kmem_cache *slab;
unsigned int users;
char *name;
unsigned int slab_flags;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index fb616c69151..1748e27501c 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -36,7 +36,7 @@
struct scsi_host_sg_pool {
size_t size;
char *name;
- kmem_cache_t *slab;
+ struct kmem_cache *slab;
mempool_t *pool;
};
@@ -241,7 +241,7 @@ struct scsi_io_context {
char sense[SCSI_SENSE_BUFFERSIZE];
};
-static kmem_cache_t *scsi_io_context_cache;
+static struct kmem_cache *scsi_io_context_cache;
static void scsi_end_async(struct request *req, int uptodate)
{
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
index 386dbae17b4..d402aff5f31 100644
--- a/drivers/scsi/scsi_tgt_lib.c
+++ b/drivers/scsi/scsi_tgt_lib.c
@@ -33,7 +33,7 @@
#include "scsi_tgt_priv.h"
static struct workqueue_struct *scsi_tgtd;
-static kmem_cache_t *scsi_tgt_cmd_cache;
+static struct kmem_cache *scsi_tgt_cmd_cache;
/*
* TODO: this struct will be killed when the block layer supports large bios
diff --git a/drivers/serial/8250_exar_st16c554.c b/drivers/serial/8250_exar_st16c554.c
new file mode 100644
index 00000000000..567143ace15
--- /dev/null
+++ b/drivers/serial/8250_exar_st16c554.c
@@ -0,0 +1,52 @@
+/*
+ * linux/drivers/serial/8250_exar.c
+ *
+ * Written by Paul B Schroeder < pschroeder "at" uplogix "dot" com >
+ * Based on 8250_boca.
+ *
+ * Copyright (C) 2005 Russell King.
+ * Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define PORT(_base,_irq) \
+ { \
+ .iobase = _base, \
+ .irq = _irq, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_PORT, \
+ .flags = UPF_BOOT_AUTOCONF, \
+ }
+
+static struct plat_serial8250_port exar_data[] = {
+ PORT(0x100, 5),
+ PORT(0x108, 5),
+ PORT(0x110, 5),
+ PORT(0x118, 5),
+ { },
+};
+
+static struct platform_device exar_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_EXAR_ST16C554,
+ .dev = {
+ .platform_data = exar_data,
+ },
+};
+
+static int __init exar_init(void)
+{
+ return platform_device_register(&exar_device);
+}
+
+module_init(exar_init);
+
+MODULE_AUTHOR("Paul B Schroeder");
+MODULE_DESCRIPTION("8250 serial probe module for Exar cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 71d907c8288..d3d6b82706b 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -464,11 +464,38 @@ static void __devexit serial_pnp_remove(struct pnp_dev *dev)
serial8250_unregister_port(line - 1);
}
+#ifdef CONFIG_PM
+static int serial_pnp_suspend(struct pnp_dev *dev, pm_message_t state)
+{
+ long line = (long)pnp_get_drvdata(dev);
+
+ if (!line)
+ return -ENODEV;
+ serial8250_suspend_port(line - 1);
+ return 0;
+}
+
+static int serial_pnp_resume(struct pnp_dev *dev)
+{
+ long line = (long)pnp_get_drvdata(dev);
+
+ if (!line)
+ return -ENODEV;
+ serial8250_resume_port(line - 1);
+ return 0;
+}
+#else
+#define serial_pnp_suspend NULL
+#define serial_pnp_resume NULL
+#endif /* CONFIG_PM */
+
static struct pnp_driver serial_pnp_driver = {
.name = "serial",
- .id_table = pnp_dev_table,
.probe = serial_pnp_probe,
.remove = __devexit_p(serial_pnp_remove),
+ .suspend = serial_pnp_suspend,
+ .resume = serial_pnp_resume,
+ .id_table = pnp_dev_table,
};
static int __init serial8250_pnp_init(void)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 0b71e7d1890..fc12d5df10e 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -210,6 +210,17 @@ config SERIAL_8250_BOCA
To compile this driver as a module, choose M here: the module
will be called 8250_boca.
+config SERIAL_8250_EXAR_ST16C554
+ tristate "Support Exar ST16C554/554D Quad UART"
+ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+ help
+ The Uplogix Envoy TU301 uses this Exar Quad UART. If you are
+ tinkering with your Envoy TU301, or have a machine with this UART,
+ say Y here.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_exar_st16c554.
+
config SERIAL_8250_HUB6
tristate "Support Hub6 cards"
depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
@@ -511,6 +522,25 @@ config SERIAL_IMX_CONSOLE
your boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time.)
+config SERIAL_UARTLITE
+ tristate "Xilinx uartlite serial port support"
+ depends on PPC32
+ select SERIAL_CORE
+ help
+ Say Y here if you want to use the Xilinx uartlite serial controller.
+
+ To compile this driver as a module, choose M here: the
+ module will be called uartlite.ko.
+
+config SERIAL_UARTLITE_CONSOLE
+ bool "Support for console on Xilinx uartlite serial port"
+ depends on SERIAL_UARTLITE=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Say Y here if you wish to use a Xilinx uartlite as the system
+ console (the system console is the device which receives all kernel
+ messages and warnings and which allows logins in single user mode).
+
config SERIAL_SUNCORE
bool
depends on SPARC
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index b4d8a7c182e..df3632cd7df 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o
obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o
obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
+obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o
@@ -55,4 +56,5 @@ obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o
obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o
obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o
+obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 4213fabc62b..4d3626ef464 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -129,6 +129,8 @@ static void pl010_rx_chars(struct uart_port *port)
*/
rsr = readb(port->membase + UART01x_RSR) | UART_DUMMY_RSR_RX;
if (unlikely(rsr & UART01x_RSR_ANY)) {
+ writel(0, port->membase + UART01x_ECR);
+
if (rsr & UART01x_RSR_BE) {
rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE);
port->icount.brk++;
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index 53662b33b84..af1544f3356 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -1,11 +1,13 @@
/*
- * dz.c: Serial port driver for DECStations equiped
+ * dz.c: Serial port driver for DECstations equipped
* with the DZ chipset.
*
* Copyright (C) 1998 Olivier A. D. Lebaillif
*
* Email: olivier.lebaillif@ifrsys.com
*
+ * Copyright (C) 2004, 2006 Maciej W. Rozycki
+ *
* [31-AUG-98] triemer
* Changed IRQ to use Harald's dec internals interrupts.h
* removed base_addr code - moving address assignment to setup.c
@@ -26,10 +28,16 @@
#undef DEBUG_DZ
+#if defined(CONFIG_SERIAL_DZ_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/delay.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/console.h>
+#include <linux/sysrq.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
@@ -45,14 +53,10 @@
#include <asm/system.h>
#include <asm/uaccess.h>
-#define CONSOLE_LINE (3) /* for definition of struct console */
-
#include "dz.h"
-#define DZ_INTR_DEBUG 1
-
static char *dz_name = "DECstation DZ serial driver version ";
-static char *dz_version = "1.02";
+static char *dz_version = "1.03";
struct dz_port {
struct uart_port port;
@@ -61,22 +65,6 @@ struct dz_port {
static struct dz_port dz_ports[DZ_NB_PORT];
-#ifdef DEBUG_DZ
-/*
- * debugging code to send out chars via prom
- */
-static void debug_console(const char *s, int count)
-{
- unsigned i;
-
- for (i = 0; i < count; i++) {
- if (*s == 10)
- prom_printf("%c", 13);
- prom_printf("%c", *s++);
- }
-}
-#endif
-
/*
* ------------------------------------------------------------
* dz_in () and dz_out ()
@@ -90,6 +78,7 @@ static inline unsigned short dz_in(struct dz_port *dport, unsigned offset)
{
volatile unsigned short *addr =
(volatile unsigned short *) (dport->port.membase + offset);
+
return *addr;
}
@@ -98,6 +87,7 @@ static inline void dz_out(struct dz_port *dport, unsigned offset,
{
volatile unsigned short *addr =
(volatile unsigned short *) (dport->port.membase + offset);
+
*addr = value;
}
@@ -144,7 +134,7 @@ static void dz_stop_rx(struct uart_port *uport)
spin_lock_irqsave(&dport->port.lock, flags);
dport->cflag &= ~DZ_CREAD;
- dz_out(dport, DZ_LPR, dport->cflag);
+ dz_out(dport, DZ_LPR, dport->cflag | dport->port.line);
spin_unlock_irqrestore(&dport->port.lock, flags);
}
@@ -155,14 +145,14 @@ static void dz_enable_ms(struct uart_port *port)
/*
* ------------------------------------------------------------
- * Here starts the interrupt handling routines. All of the
- * following subroutines are declared as inline and are folded
- * into dz_interrupt. They were separated out for readability's
- * sake.
*
- * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * Here start the interrupt handling routines. All of the following
+ * subroutines are declared as inline and are folded into
+ * dz_interrupt. They were separated out for readability's sake.
+ *
+ * Note: dz_interrupt() is a "fast" interrupt, which means that it
* runs with interrupts turned off. People who may want to modify
- * rs_interrupt() should try to keep the interrupt handler as fast as
+ * dz_interrupt() should try to keep the interrupt handler as fast as
* possible. After you are done making modifications, it is not a bad
* idea to do:
*
@@ -180,92 +170,74 @@ static void dz_enable_ms(struct uart_port *port)
* This routine deals with inputs from any lines.
* ------------------------------------------------------------
*/
-static inline void dz_receive_chars(struct dz_port *dport)
+static inline void dz_receive_chars(struct dz_port *dport_in,
+ struct pt_regs *regs)
{
+ struct dz_port *dport;
struct tty_struct *tty = NULL;
struct uart_icount *icount;
- int ignore = 0;
- unsigned short status, tmp;
+ int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 };
+ unsigned short status;
unsigned char ch, flag;
+ int i;
- /* this code is going to be a problem...
- the call to tty_flip_buffer is going to need
- to be rethought...
- */
- do {
- status = dz_in(dport, DZ_RBUF);
-
- /* punt so we don't get duplicate characters */
- if (!(status & DZ_DVAL))
- goto ignore_char;
-
-
- ch = UCHAR(status); /* grab the char */
- flag = TTY_NORMAL;
+ while ((status = dz_in(dport_in, DZ_RBUF)) & DZ_DVAL) {
+ dport = &dz_ports[LINE(status)];
+ tty = dport->port.info->tty; /* point to the proper dev */
-#if 0
- if (info->is_console) {
- if (ch == 0)
- return; /* it's a break ... */
- }
-#endif
+ ch = UCHAR(status); /* grab the char */
- tty = dport->port.info->tty;/* now tty points to the proper dev */
icount = &dport->port.icount;
-
- if (!tty)
- break;
-
icount->rx++;
- /* keep track of the statistics */
- if (status & (DZ_OERR | DZ_FERR | DZ_PERR)) {
- if (status & DZ_PERR) /* parity error */
- icount->parity++;
- else if (status & DZ_FERR) /* frame error */
- icount->frame++;
- if (status & DZ_OERR) /* overrun error */
- icount->overrun++;
-
- /* check to see if we should ignore the character
- and mask off conditions that should be ignored
+ flag = TTY_NORMAL;
+ if (status & DZ_FERR) { /* frame error */
+ /*
+ * There is no separate BREAK status bit, so
+ * treat framing errors as BREAKs for Magic SysRq
+ * and SAK; normally, otherwise.
*/
-
- if (status & dport->port.ignore_status_mask) {
- if (++ignore > 100)
- break;
- goto ignore_char;
- }
- /* mask off the error conditions we want to ignore */
- tmp = status & dport->port.read_status_mask;
-
- if (tmp & DZ_PERR) {
- flag = TTY_PARITY;
-#ifdef DEBUG_DZ
- debug_console("PERR\n", 5);
-#endif
- } else if (tmp & DZ_FERR) {
+ if (uart_handle_break(&dport->port))
+ continue;
+ if (dport->port.flags & UPF_SAK)
+ flag = TTY_BREAK;
+ else
flag = TTY_FRAME;
-#ifdef DEBUG_DZ
- debug_console("FERR\n", 5);
-#endif
- }
- if (tmp & DZ_OERR) {
-#ifdef DEBUG_DZ
- debug_console("OERR\n", 5);
-#endif
- tty_insert_flip_char(tty, ch, flag);
- ch = 0;
- flag = TTY_OVERRUN;
- }
+ } else if (status & DZ_OERR) /* overrun error */
+ flag = TTY_OVERRUN;
+ else if (status & DZ_PERR) /* parity error */
+ flag = TTY_PARITY;
+
+ /* keep track of the statistics */
+ switch (flag) {
+ case TTY_FRAME:
+ icount->frame++;
+ break;
+ case TTY_PARITY:
+ icount->parity++;
+ break;
+ case TTY_OVERRUN:
+ icount->overrun++;
+ break;
+ case TTY_BREAK:
+ icount->brk++;
+ break;
+ default:
+ break;
}
- tty_insert_flip_char(tty, ch, flag);
- ignore_char:
- ;
- } while (status & DZ_DVAL);
- if (tty)
- tty_flip_buffer_push(tty);
+ if (uart_handle_sysrq_char(&dport->port, ch, regs))
+ continue;
+
+ if ((status & dport->port.ignore_status_mask) == 0) {
+ uart_insert_char(&dport->port,
+ status, DZ_OERR, ch, flag);
+ lines_rx[LINE(status)] = 1;
+ }
+ }
+ for (i = 0; i < DZ_NB_PORT; i++)
+ if (lines_rx[i])
+ tty_flip_buffer_push(dz_ports[i].port.info->tty);
}
/*
@@ -275,26 +247,32 @@ static inline void dz_receive_chars(struct dz_port *dport)
* This routine deals with outputs to any lines.
* ------------------------------------------------------------
*/
-static inline void dz_transmit_chars(struct dz_port *dport)
+static inline void dz_transmit_chars(struct dz_port *dport_in)
{
- struct circ_buf *xmit = &dport->port.info->xmit;
+ struct dz_port *dport;
+ struct circ_buf *xmit;
+ unsigned short status;
unsigned char tmp;
- if (dport->port.x_char) { /* XON/XOFF chars */
+ status = dz_in(dport_in, DZ_CSR);
+ dport = &dz_ports[LINE(status)];
+ xmit = &dport->port.info->xmit;
+
+ if (dport->port.x_char) { /* XON/XOFF chars */
dz_out(dport, DZ_TDR, dport->port.x_char);
dport->port.icount.tx++;
dport->port.x_char = 0;
return;
}
- /* if nothing to do or stopped or hardware stopped */
+ /* If nothing to do or stopped or hardware stopped. */
if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) {
dz_stop_tx(&dport->port);
return;
}
/*
- * if something to do ... (rember the dz has no output fifo so we go
- * one char at a time :-<
+ * If something to do... (remember the dz has no output fifo,
+ * so we go one char at a time) :-<
*/
tmp = xmit->buf[xmit->tail];
xmit->tail = (xmit->tail + 1) & (DZ_XMIT_SIZE - 1);
@@ -304,23 +282,29 @@ static inline void dz_transmit_chars(struct dz_port *dport)
if (uart_circ_chars_pending(xmit) < DZ_WAKEUP_CHARS)
uart_write_wakeup(&dport->port);
- /* Are we done */
+ /* Are we are done. */
if (uart_circ_empty(xmit))
dz_stop_tx(&dport->port);
}
/*
* ------------------------------------------------------------
- * check_modem_status ()
+ * check_modem_status()
*
- * Only valid for the MODEM line duh !
+ * DS 3100 & 5100: Only valid for the MODEM line, duh!
+ * DS 5000/200: Valid for the MODEM and PRINTER line.
* ------------------------------------------------------------
*/
static inline void check_modem_status(struct dz_port *dport)
{
+ /*
+ * FIXME:
+ * 1. No status change interrupt; use a timer.
+ * 2. Handle the 3100/5000 as appropriate. --macro
+ */
unsigned short status;
- /* if not ne modem line just return */
+ /* If not the modem line just return. */
if (dport->port.line != DZ_MODEM)
return;
@@ -341,21 +325,18 @@ static inline void check_modem_status(struct dz_port *dport)
*/
static irqreturn_t dz_interrupt(int irq, void *dev)
{
- struct dz_port *dport;
+ struct dz_port *dport = (struct dz_port *)dev;
unsigned short status;
/* get the reason why we just got an irq */
- status = dz_in((struct dz_port *)dev, DZ_CSR);
- dport = &dz_ports[LINE(status)];
+ status = dz_in(dport, DZ_CSR);
- if (status & DZ_RDONE)
- dz_receive_chars(dport);
+ if ((status & (DZ_RDONE | DZ_RIE)) == (DZ_RDONE | DZ_RIE))
+ dz_receive_chars(dport, regs);
- if (status & DZ_TRDY)
+ if ((status & (DZ_TRDY | DZ_TIE)) == (DZ_TRDY | DZ_TIE))
dz_transmit_chars(dport);
- /* FIXME: what about check modem status??? --rmk */
-
return IRQ_HANDLED;
}
@@ -367,13 +348,13 @@ static irqreturn_t dz_interrupt(int irq, void *dev)
static unsigned int dz_get_mctrl(struct uart_port *uport)
{
+ /*
+ * FIXME: Handle the 3100/5000 as appropriate. --macro
+ */
struct dz_port *dport = (struct dz_port *)uport;
unsigned int mctrl = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
if (dport->port.line == DZ_MODEM) {
- /*
- * CHECKME: This is a guess from the other code... --rmk
- */
if (dz_in(dport, DZ_MSR) & DZ_MODEM_DSR)
mctrl &= ~TIOCM_DSR;
}
@@ -383,6 +364,9 @@ static unsigned int dz_get_mctrl(struct uart_port *uport)
static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl)
{
+ /*
+ * FIXME: Handle the 3100/5000 as appropriate. --macro
+ */
struct dz_port *dport = (struct dz_port *)uport;
unsigned short tmp;
@@ -409,13 +393,6 @@ static int dz_startup(struct uart_port *uport)
unsigned long flags;
unsigned short tmp;
- /* The dz lines for the mouse/keyboard must be
- * opened using their respective drivers.
- */
- if ((dport->port.line == DZ_KEYBOARD) ||
- (dport->port.line == DZ_MOUSE))
- return -ENODEV;
-
spin_lock_irqsave(&dport->port.lock, flags);
/* enable the interrupt and the scanning */
@@ -442,7 +419,8 @@ static void dz_shutdown(struct uart_port *uport)
}
/*
- * get_lsr_info - get line status register info
+ * -------------------------------------------------------------------
+ * dz_tx_empty() -- get the transmitter empty status
*
* Purpose: Let user call ioctl() to get info when the UART physically
* is emptied. On bus types like RS485, the transmitter must
@@ -450,21 +428,28 @@ static void dz_shutdown(struct uart_port *uport)
* the transmit shift register is empty, not be done when the
* transmit holding register is empty. This functionality
* allows an RS485 driver to be written in user space.
+ * -------------------------------------------------------------------
*/
static unsigned int dz_tx_empty(struct uart_port *uport)
{
struct dz_port *dport = (struct dz_port *)uport;
- unsigned short status = dz_in(dport, DZ_LPR);
+ unsigned short tmp, mask = 1 << dport->port.line;
- /* FIXME: this appears to be obviously broken --rmk. */
- return status ? TIOCSER_TEMT : 0;
+ tmp = dz_in(dport, DZ_TCR);
+ tmp &= mask;
+
+ return tmp ? 0 : TIOCSER_TEMT;
}
static void dz_break_ctl(struct uart_port *uport, int break_state)
{
+ /*
+ * FIXME: Can't access BREAK bits in TDR easily;
+ * reuse the code for polled TX. --macro
+ */
struct dz_port *dport = (struct dz_port *)uport;
unsigned long flags;
- unsigned short tmp, mask = 1 << uport->line;
+ unsigned short tmp, mask = 1 << dport->port.line;
spin_lock_irqsave(&uport->lock, flags);
tmp = dz_in(dport, DZ_TCR);
@@ -561,7 +546,7 @@ static void dz_set_termios(struct uart_port *uport, struct termios *termios,
spin_lock_irqsave(&dport->port.lock, flags);
- dz_out(dport, DZ_LPR, cflag);
+ dz_out(dport, DZ_LPR, cflag | dport->port.line);
dport->cflag = cflag;
/* setup accept flag */
@@ -650,7 +635,7 @@ static void __init dz_init_ports(void)
for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) {
spin_lock_init(&dport->port.lock);
dport->port.membase = (char *) base;
- dport->port.iotype = UPIO_PORT;
+ dport->port.iotype = UPIO_MEM;
dport->port.irq = dec_interrupt[DEC_IRQ_DZ11];
dport->port.line = i;
dport->port.fifosize = 1;
@@ -662,10 +647,7 @@ static void __init dz_init_ports(void)
static void dz_reset(struct dz_port *dport)
{
dz_out(dport, DZ_CSR, DZ_CLR);
-
while (dz_in(dport, DZ_CSR) & DZ_CLR);
- /* FIXME: cpu_relax? */
-
iob();
/* enable scanning */
@@ -673,26 +655,55 @@ static void dz_reset(struct dz_port *dport)
}
#ifdef CONFIG_SERIAL_DZ_CONSOLE
+/*
+ * -------------------------------------------------------------------
+ * dz_console_putchar() -- transmit a character
+ *
+ * Polled transmission. This is tricky. We need to mask transmit
+ * interrupts so that they do not interfere, enable the transmitter
+ * for the line requested and then wait till the transmit scanner
+ * requests data for this line. But it may request data for another
+ * line first, in which case we have to disable its transmitter and
+ * repeat waiting till our line pops up. Only then the character may
+ * be transmitted. Finally, the state of the transmitter mask is
+ * restored. Welcome to the world of PDP-11!
+ * -------------------------------------------------------------------
+ */
static void dz_console_putchar(struct uart_port *uport, int ch)
{
struct dz_port *dport = (struct dz_port *)uport;
unsigned long flags;
- int loops = 2500;
- unsigned short tmp = (unsigned char)ch;
- /* this code sends stuff out to serial device - spinning its
- wheels and waiting. */
+ unsigned short csr, tcr, trdy, mask;
+ int loops = 10000;
spin_lock_irqsave(&dport->port.lock, flags);
+ csr = dz_in(dport, DZ_CSR);
+ dz_out(dport, DZ_CSR, csr & ~DZ_TIE);
+ tcr = dz_in(dport, DZ_TCR);
+ tcr |= 1 << dport->port.line;
+ mask = tcr;
+ dz_out(dport, DZ_TCR, mask);
+ iob();
+ spin_unlock_irqrestore(&dport->port.lock, flags);
- /* spin our wheels */
- while (((dz_in(dport, DZ_CSR) & DZ_TRDY) != DZ_TRDY) && loops--)
- /* FIXME: cpu_relax, udelay? --rmk */
- ;
+ while (loops--) {
+ trdy = dz_in(dport, DZ_CSR);
+ if (!(trdy & DZ_TRDY))
+ continue;
+ trdy = (trdy & DZ_TLINE) >> 8;
+ if (trdy == dport->port.line)
+ break;
+ mask &= ~(1 << trdy);
+ dz_out(dport, DZ_TCR, mask);
+ iob();
+ udelay(2);
+ }
- /* Actually transmit the character. */
- dz_out(dport, DZ_TDR, tmp);
+ if (loops) /* Cannot send otherwise. */
+ dz_out(dport, DZ_TDR, ch);
- spin_unlock_irqrestore(&dport->port.lock, flags);
+ dz_out(dport, DZ_TCR, tcr);
+ dz_out(dport, DZ_CSR, csr);
}
/*
@@ -703,11 +714,11 @@ static void dz_console_putchar(struct uart_port *uport, int ch)
* The console must be locked when we get here.
* -------------------------------------------------------------------
*/
-static void dz_console_print(struct console *cons,
+static void dz_console_print(struct console *co,
const char *str,
unsigned int count)
{
- struct dz_port *dport = &dz_ports[CONSOLE_LINE];
+ struct dz_port *dport = &dz_ports[co->index];
#ifdef DEBUG_DZ
prom_printf((char *) str);
#endif
@@ -716,49 +727,43 @@ static void dz_console_print(struct console *cons,
static int __init dz_console_setup(struct console *co, char *options)
{
- struct dz_port *dport = &dz_ports[CONSOLE_LINE];
+ struct dz_port *dport = &dz_ports[co->index];
int baud = 9600;
int bits = 8;
int parity = 'n';
int flow = 'n';
- int ret;
- unsigned short mask, tmp;
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
dz_reset(dport);
- ret = uart_set_options(&dport->port, co, baud, parity, bits, flow);
- if (ret == 0) {
- mask = 1 << dport->port.line;
- tmp = dz_in(dport, DZ_TCR); /* read the TX flag */
- if (!(tmp & mask)) {
- tmp |= mask; /* set the TX flag */
- dz_out(dport, DZ_TCR, tmp);
- }
- }
-
- return ret;
+ return uart_set_options(&dport->port, co, baud, parity, bits, flow);
}
-static struct console dz_sercons =
-{
+static struct uart_driver dz_reg;
+static struct console dz_sercons = {
.name = "ttyS",
.write = dz_console_print,
.device = uart_console_device,
.setup = dz_console_setup,
- .flags = CON_CONSDEV | CON_PRINTBUFFER,
- .index = CONSOLE_LINE,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+ .data = &dz_reg,
};
-void __init dz_serial_console_init(void)
+static int __init dz_serial_console_init(void)
{
- dz_init_ports();
-
- register_console(&dz_sercons);
+ if (!IOASIC) {
+ dz_init_ports();
+ register_console(&dz_sercons);
+ return 0;
+ } else
+ return -ENXIO;
}
+console_initcall(dz_serial_console_init);
+
#define SERIAL_DZ_CONSOLE &dz_sercons
#else
#define SERIAL_DZ_CONSOLE NULL
@@ -767,35 +772,29 @@ void __init dz_serial_console_init(void)
static struct uart_driver dz_reg = {
.owner = THIS_MODULE,
.driver_name = "serial",
- .dev_name = "ttyS%d",
+ .dev_name = "ttyS",
.major = TTY_MAJOR,
.minor = 64,
.nr = DZ_NB_PORT,
.cons = SERIAL_DZ_CONSOLE,
};
-int __init dz_init(void)
+static int __init dz_init(void)
{
- unsigned long flags;
int ret, i;
+ if (IOASIC)
+ return -ENXIO;
+
printk("%s%s\n", dz_name, dz_version);
dz_init_ports();
- save_flags(flags);
- cli();
-
#ifndef CONFIG_SERIAL_DZ_CONSOLE
/* reset the chip */
dz_reset(&dz_ports[0]);
#endif
- /* order matters here... the trick is that flags
- is updated... in request_irq - to immediatedly obliterate
- it is unwise. */
- restore_flags(flags);
-
if (request_irq(dz_ports[0].port.irq, dz_interrupt,
IRQF_DISABLED, "DZ", &dz_ports[0]))
panic("Unable to register DZ interrupt");
@@ -810,5 +809,7 @@ int __init dz_init(void)
return ret;
}
+module_init(dz_init);
+
MODULE_DESCRIPTION("DECstation DZ serial driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/serial/dz.h b/drivers/serial/dz.h
index 86ef417382b..9674d4e4987 100644
--- a/drivers/serial/dz.h
+++ b/drivers/serial/dz.h
@@ -1,20 +1,22 @@
/*
- * dz.h: Serial port driver for DECStations equiped
+ * dz.h: Serial port driver for DECstations equipped
* with the DZ chipset.
*
* Copyright (C) 1998 Olivier A. D. Lebaillif
*
* Email: olivier.lebaillif@ifrsys.com
*
+ * Copyright (C) 2004, 2006 Maciej W. Rozycki
*/
#ifndef DZ_SERIAL_H
#define DZ_SERIAL_H
/*
- * Definitions for the Control and Status Received.
+ * Definitions for the Control and Status Register.
*/
#define DZ_TRDY 0x8000 /* Transmitter empty */
-#define DZ_TIE 0x4000 /* Transmitter Interrupt Enable */
+#define DZ_TIE 0x4000 /* Transmitter Interrupt Enbl */
+#define DZ_TLINE 0x0300 /* Transmitter Line Number */
#define DZ_RDONE 0x0080 /* Receiver data ready */
#define DZ_RIE 0x0040 /* Receive Interrupt Enable */
#define DZ_MSE 0x0020 /* Master Scan Enable */
@@ -22,32 +24,44 @@
#define DZ_MAINT 0x0008 /* Loop Back Mode */
/*
- * Definitions for the Received buffer.
+ * Definitions for the Receiver Buffer Register.
*/
-#define DZ_RBUF_MASK 0x00FF /* Data Mask in the Receive Buffer */
-#define DZ_LINE_MASK 0x0300 /* Line Mask in the Receive Buffer */
+#define DZ_RBUF_MASK 0x00FF /* Data Mask */
+#define DZ_LINE_MASK 0x0300 /* Line Mask */
#define DZ_DVAL 0x8000 /* Valid Data indicator */
#define DZ_OERR 0x4000 /* Overrun error indicator */
#define DZ_FERR 0x2000 /* Frame error indicator */
#define DZ_PERR 0x1000 /* Parity error indicator */
-#define LINE(x) (x & DZ_LINE_MASK) >> 8 /* Get the line number from the input buffer */
-#define UCHAR(x) (unsigned char)(x & DZ_RBUF_MASK)
+#define LINE(x) ((x & DZ_LINE_MASK) >> 8) /* Get the line number
+ from the input buffer */
+#define UCHAR(x) ((unsigned char)(x & DZ_RBUF_MASK))
/*
- * Definitions for the Transmit Register.
+ * Definitions for the Transmit Control Register.
*/
#define DZ_LINE_KEYBOARD 0x0001
#define DZ_LINE_MOUSE 0x0002
#define DZ_LINE_MODEM 0x0004
#define DZ_LINE_PRINTER 0x0008
+#define DZ_MODEM_RTS 0x0800 /* RTS for the modem line (2) */
#define DZ_MODEM_DTR 0x0400 /* DTR for the modem line (2) */
+#define DZ_PRINT_RTS 0x0200 /* RTS for the prntr line (3) */
+#define DZ_PRINT_DTR 0x0100 /* DTR for the prntr line (3) */
+#define DZ_LNENB 0x000f /* Transmitter Line Enable */
/*
* Definitions for the Modem Status Register.
*/
+#define DZ_MODEM_RI 0x0800 /* RI for the modem line (2) */
+#define DZ_MODEM_CD 0x0400 /* CD for the modem line (2) */
#define DZ_MODEM_DSR 0x0200 /* DSR for the modem line (2) */
+#define DZ_MODEM_CTS 0x0100 /* CTS for the modem line (2) */
+#define DZ_PRINT_RI 0x0008 /* RI for the printer line (3) */
+#define DZ_PRINT_CD 0x0004 /* CD for the printer line (3) */
+#define DZ_PRINT_DSR 0x0002 /* DSR for the prntr line (3) */
+#define DZ_PRINT_CTS 0x0001 /* CTS for the prntr line (3) */
/*
* Definitions for the Transmit Data Register.
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index 8eea69f2998..29823bd60fb 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -555,7 +555,7 @@ mpsc_sdma_start_tx(struct mpsc_port_info *pi)
if (!mpsc_sdma_tx_active(pi)) {
txre = (struct mpsc_tx_desc *)(pi->txr +
(pi->txr_tail * MPSC_TXRE_SIZE));
- dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE);
+ dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE);
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
invalidate_dcache_range((ulong)txre,
@@ -931,7 +931,7 @@ mpsc_init_rings(struct mpsc_port_info *pi)
}
txre->link = cpu_to_be32(pi->txr_p); /* Wrap last back to first */
- dma_cache_sync((void *) pi->dma_region, MPSC_DMA_ALLOC_SIZE,
+ dma_cache_sync(pi->port.dev, (void *) pi->dma_region, MPSC_DMA_ALLOC_SIZE,
DMA_BIDIRECTIONAL);
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
@@ -1005,7 +1005,7 @@ mpsc_rx_intr(struct mpsc_port_info *pi)
rxre = (struct mpsc_rx_desc *)(pi->rxr + (pi->rxr_posn*MPSC_RXRE_SIZE));
- dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
+ dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
invalidate_dcache_range((ulong)rxre,
@@ -1029,7 +1029,7 @@ mpsc_rx_intr(struct mpsc_port_info *pi)
}
bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE);
- dma_cache_sync((void *) bp, MPSC_RXBE_SIZE, DMA_FROM_DEVICE);
+ dma_cache_sync(pi->port.dev, (void *) bp, MPSC_RXBE_SIZE, DMA_FROM_DEVICE);
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
invalidate_dcache_range((ulong)bp,
@@ -1098,7 +1098,7 @@ next_frame:
SDMA_DESC_CMDSTAT_F |
SDMA_DESC_CMDSTAT_L);
wmb();
- dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL);
+ dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL);
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
flush_dcache_range((ulong)rxre,
@@ -1109,7 +1109,7 @@ next_frame:
pi->rxr_posn = (pi->rxr_posn + 1) & (MPSC_RXR_ENTRIES - 1);
rxre = (struct mpsc_rx_desc *)(pi->rxr +
(pi->rxr_posn * MPSC_RXRE_SIZE));
- dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
+ dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
invalidate_dcache_range((ulong)rxre,
@@ -1143,7 +1143,7 @@ mpsc_setup_tx_desc(struct mpsc_port_info *pi, u32 count, u32 intr)
SDMA_DESC_CMDSTAT_EI
: 0));
wmb();
- dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_BIDIRECTIONAL);
+ dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_BIDIRECTIONAL);
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
flush_dcache_range((ulong)txre,
@@ -1192,7 +1192,7 @@ mpsc_copy_tx_data(struct mpsc_port_info *pi)
else /* All tx data copied into ring bufs */
return;
- dma_cache_sync((void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL);
+ dma_cache_sync(pi->port.dev, (void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL);
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
flush_dcache_range((ulong)bp,
@@ -1217,7 +1217,7 @@ mpsc_tx_intr(struct mpsc_port_info *pi)
txre = (struct mpsc_tx_desc *)(pi->txr +
(pi->txr_tail * MPSC_TXRE_SIZE));
- dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE);
+ dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE);
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
invalidate_dcache_range((ulong)txre,
@@ -1235,7 +1235,7 @@ mpsc_tx_intr(struct mpsc_port_info *pi)
txre = (struct mpsc_tx_desc *)(pi->txr +
(pi->txr_tail * MPSC_TXRE_SIZE));
- dma_cache_sync((void *) txre, MPSC_TXRE_SIZE,
+ dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE,
DMA_FROM_DEVICE);
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
@@ -1652,7 +1652,7 @@ mpsc_console_write(struct console *co, const char *s, uint count)
count--;
}
- dma_cache_sync((void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL);
+ dma_cache_sync(pi->port.dev, (void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL);
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
flush_dcache_range((ulong)bp,
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
new file mode 100644
index 00000000000..83690653b78
--- /dev/null
+++ b/drivers/serial/uartlite.c
@@ -0,0 +1,505 @@
+/*
+ * uartlite.c: Serial driver for Xilinx uartlite serial controller
+ *
+ * Peter Korsgaard <jacmet@sunsite.dk>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+
+#define ULITE_MAJOR 204
+#define ULITE_MINOR 187
+#define ULITE_NR_UARTS 4
+
+/* For register details see datasheet:
+ http://www.xilinx.com/bvdocs/ipcenter/data_sheet/opb_uartlite.pdf
+*/
+#define ULITE_RX 0x00
+#define ULITE_TX 0x04
+#define ULITE_STATUS 0x08
+#define ULITE_CONTROL 0x0c
+
+#define ULITE_REGION 16
+
+#define ULITE_STATUS_RXVALID 0x01
+#define ULITE_STATUS_RXFULL 0x02
+#define ULITE_STATUS_TXEMPTY 0x04
+#define ULITE_STATUS_TXFULL 0x08
+#define ULITE_STATUS_IE 0x10
+#define ULITE_STATUS_OVERRUN 0x20
+#define ULITE_STATUS_FRAME 0x40
+#define ULITE_STATUS_PARITY 0x80
+
+#define ULITE_CONTROL_RST_TX 0x01
+#define ULITE_CONTROL_RST_RX 0x02
+#define ULITE_CONTROL_IE 0x10
+
+
+static struct uart_port ports[ULITE_NR_UARTS];
+
+static int ulite_receive(struct uart_port *port, int stat)
+{
+ struct tty_struct *tty = port->info->tty;
+ unsigned char ch = 0;
+ char flag = TTY_NORMAL;
+
+ if ((stat & (ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN
+ | ULITE_STATUS_FRAME)) == 0)
+ return 0;
+
+ /* stats */
+ if (stat & ULITE_STATUS_RXVALID) {
+ port->icount.rx++;
+ ch = readb(port->membase + ULITE_RX);
+
+ if (stat & ULITE_STATUS_PARITY)
+ port->icount.parity++;
+ }
+
+ if (stat & ULITE_STATUS_OVERRUN)
+ port->icount.overrun++;
+
+ if (stat & ULITE_STATUS_FRAME)
+ port->icount.frame++;
+
+
+ /* drop byte with parity error if IGNPAR specificed */
+ if (stat & port->ignore_status_mask & ULITE_STATUS_PARITY)
+ stat &= ~ULITE_STATUS_RXVALID;
+
+ stat &= port->read_status_mask;
+
+ if (stat & ULITE_STATUS_PARITY)
+ flag = TTY_PARITY;
+
+
+ stat &= ~port->ignore_status_mask;
+
+ if (stat & ULITE_STATUS_RXVALID)
+ tty_insert_flip_char(tty, ch, flag);
+
+ if (stat & ULITE_STATUS_FRAME)
+ tty_insert_flip_char(tty, 0, TTY_FRAME);
+
+ if (stat & ULITE_STATUS_OVERRUN)
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+
+ return 1;
+}
+
+static int ulite_transmit(struct uart_port *port, int stat)
+{
+ struct circ_buf *xmit = &port->info->xmit;
+
+ if (stat & ULITE_STATUS_TXFULL)
+ return 0;
+
+ if (port->x_char) {
+ writeb(port->x_char, port->membase + ULITE_TX);
+ port->x_char = 0;
+ port->icount.tx++;
+ return 1;
+ }
+
+ if (uart_circ_empty(xmit) || uart_tx_stopped(port))
+ return 0;
+
+ writeb(xmit->buf[xmit->tail], port->membase + ULITE_TX);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1);
+ port->icount.tx++;
+
+ /* wake up */
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(port);
+
+ return 1;
+}
+
+static irqreturn_t ulite_isr(int irq, void *dev_id)
+{
+ struct uart_port *port = (struct uart_port *)dev_id;
+ int busy;
+
+ do {
+ int stat = readb(port->membase + ULITE_STATUS);
+ busy = ulite_receive(port, stat);
+ busy |= ulite_transmit(port, stat);
+ } while (busy);
+
+ tty_flip_buffer_push(port->info->tty);
+
+ return IRQ_HANDLED;
+}
+
+static unsigned int ulite_tx_empty(struct uart_port *port)
+{
+ unsigned long flags;
+ unsigned int ret;
+
+ spin_lock_irqsave(&port->lock, flags);
+ ret = readb(port->membase + ULITE_STATUS);
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0;
+}
+
+static unsigned int ulite_get_mctrl(struct uart_port *port)
+{
+ return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+}
+
+static void ulite_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ /* N/A */
+}
+
+static void ulite_stop_tx(struct uart_port *port)
+{
+ /* N/A */
+}
+
+static void ulite_start_tx(struct uart_port *port)
+{
+ ulite_transmit(port, readb(port->membase + ULITE_STATUS));
+}
+
+static void ulite_stop_rx(struct uart_port *port)
+{
+ /* don't forward any more data (like !CREAD) */
+ port->ignore_status_mask = ULITE_STATUS_RXVALID | ULITE_STATUS_PARITY
+ | ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN;
+}
+
+static void ulite_enable_ms(struct uart_port *port)
+{
+ /* N/A */
+}
+
+static void ulite_break_ctl(struct uart_port *port, int ctl)
+{
+ /* N/A */
+}
+
+static int ulite_startup(struct uart_port *port)
+{
+ int ret;
+
+ ret = request_irq(port->irq, ulite_isr,
+ IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "uartlite", port);
+ if (ret)
+ return ret;
+
+ writeb(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX,
+ port->membase + ULITE_CONTROL);
+ writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL);
+
+ return 0;
+}
+
+static void ulite_shutdown(struct uart_port *port)
+{
+ writeb(0, port->membase + ULITE_CONTROL);
+ readb(port->membase + ULITE_CONTROL); /* dummy */
+ free_irq(port->irq, port);
+}
+
+static void ulite_set_termios(struct uart_port *port, struct termios *termios,
+ struct termios *old)
+{
+ unsigned long flags;
+ unsigned int baud;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ port->read_status_mask = ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN
+ | ULITE_STATUS_TXFULL;
+
+ if (termios->c_iflag & INPCK)
+ port->read_status_mask |=
+ ULITE_STATUS_PARITY | ULITE_STATUS_FRAME;
+
+ port->ignore_status_mask = 0;
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= ULITE_STATUS_PARITY
+ | ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN;
+
+ /* ignore all characters if CREAD is not set */
+ if ((termios->c_cflag & CREAD) == 0)
+ port->ignore_status_mask |=
+ ULITE_STATUS_RXVALID | ULITE_STATUS_PARITY
+ | ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN;
+
+ /* update timeout */
+ baud = uart_get_baud_rate(port, termios, old, 0, 460800);
+ uart_update_timeout(port, termios->c_cflag, baud);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *ulite_type(struct uart_port *port)
+{
+ return port->type == PORT_UARTLITE ? "uartlite" : NULL;
+}
+
+static void ulite_release_port(struct uart_port *port)
+{
+ release_mem_region(port->mapbase, ULITE_REGION);
+ iounmap(port->membase);
+ port->membase = 0;
+}
+
+static int ulite_request_port(struct uart_port *port)
+{
+ if (!request_mem_region(port->mapbase, ULITE_REGION, "uartlite")) {
+ dev_err(port->dev, "Memory region busy\n");
+ return -EBUSY;
+ }
+
+ port->membase = ioremap(port->mapbase, ULITE_REGION);
+ if (!port->membase) {
+ dev_err(port->dev, "Unable to map registers\n");
+ release_mem_region(port->mapbase, ULITE_REGION);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static void ulite_config_port(struct uart_port *port, int flags)
+{
+ ulite_request_port(port);
+ port->type = PORT_UARTLITE;
+}
+
+static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+ /* we don't want the core code to modify any port params */
+ return -EINVAL;
+}
+
+static struct uart_ops ulite_ops = {
+ .tx_empty = ulite_tx_empty,
+ .set_mctrl = ulite_set_mctrl,
+ .get_mctrl = ulite_get_mctrl,
+ .stop_tx = ulite_stop_tx,
+ .start_tx = ulite_start_tx,
+ .stop_rx = ulite_stop_rx,
+ .enable_ms = ulite_enable_ms,
+ .break_ctl = ulite_break_ctl,
+ .startup = ulite_startup,
+ .shutdown = ulite_shutdown,
+ .set_termios = ulite_set_termios,
+ .type = ulite_type,
+ .release_port = ulite_release_port,
+ .request_port = ulite_request_port,
+ .config_port = ulite_config_port,
+ .verify_port = ulite_verify_port
+};
+
+#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
+static void ulite_console_wait_tx(struct uart_port *port)
+{
+ int i;
+
+ /* wait up to 10ms for the character(s) to be sent */
+ for (i = 0; i < 10000; i++) {
+ if (readb(port->membase + ULITE_STATUS) & ULITE_STATUS_TXEMPTY)
+ break;
+ udelay(1);
+ }
+}
+
+static void ulite_console_putchar(struct uart_port *port, int ch)
+{
+ ulite_console_wait_tx(port);
+ writeb(ch, port->membase + ULITE_TX);
+}
+
+static void ulite_console_write(struct console *co, const char *s,
+ unsigned int count)
+{
+ struct uart_port *port = &ports[co->index];
+ unsigned long flags;
+ unsigned int ier;
+ int locked = 1;
+
+ if (oops_in_progress) {
+ locked = spin_trylock_irqsave(&port->lock, flags);
+ } else
+ spin_lock_irqsave(&port->lock, flags);
+
+ /* save and disable interrupt */
+ ier = readb(port->membase + ULITE_STATUS) & ULITE_STATUS_IE;
+ writeb(0, port->membase + ULITE_CONTROL);
+
+ uart_console_write(port, s, count, ulite_console_putchar);
+
+ ulite_console_wait_tx(port);
+
+ /* restore interrupt state */
+ if (ier)
+ writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL);
+
+ if (locked)
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int __init ulite_console_setup(struct console *co, char *options)
+{
+ struct uart_port *port;
+ int baud = 9600;
+ int bits = 8;
+ int parity = 'n';
+ int flow = 'n';
+
+ if (co->index < 0 || co->index >= ULITE_NR_UARTS)
+ return -EINVAL;
+
+ port = &ports[co->index];
+
+ /* not initialized yet? */
+ if (!port->membase)
+ return -ENODEV;
+
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+ return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver ulite_uart_driver;
+
+static struct console ulite_console = {
+ .name = "ttyUL",
+ .write = ulite_console_write,
+ .device = uart_console_device,
+ .setup = ulite_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1, /* Specified on the cmdline (e.g. console=ttyUL0 ) */
+ .data = &ulite_uart_driver,
+};
+
+static int __init ulite_console_init(void)
+{
+ register_console(&ulite_console);
+ return 0;
+}
+
+console_initcall(ulite_console_init);
+
+#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
+
+static struct uart_driver ulite_uart_driver = {
+ .owner = THIS_MODULE,
+ .driver_name = "uartlite",
+ .dev_name = "ttyUL",
+ .major = ULITE_MAJOR,
+ .minor = ULITE_MINOR,
+ .nr = ULITE_NR_UARTS,
+#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
+ .cons = &ulite_console,
+#endif
+};
+
+static int __devinit ulite_probe(struct platform_device *pdev)
+{
+ struct resource *res, *res2;
+ struct uart_port *port;
+
+ if (pdev->id < 0 || pdev->id >= ULITE_NR_UARTS)
+ return -EINVAL;
+
+ if (ports[pdev->id].membase)
+ return -EBUSY;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res2)
+ return -ENODEV;
+
+ port = &ports[pdev->id];
+
+ port->fifosize = 16;
+ port->regshift = 2;
+ port->iotype = UPIO_MEM;
+ port->iobase = 1; /* mark port in use */
+ port->mapbase = res->start;
+ port->membase = 0;
+ port->ops = &ulite_ops;
+ port->irq = res2->start;
+ port->flags = UPF_BOOT_AUTOCONF;
+ port->dev = &pdev->dev;
+ port->type = PORT_UNKNOWN;
+ port->line = pdev->id;
+
+ uart_add_one_port(&ulite_uart_driver, port);
+ platform_set_drvdata(pdev, port);
+
+ return 0;
+}
+
+static int ulite_remove(struct platform_device *pdev)
+{
+ struct uart_port *port = platform_get_drvdata(pdev);
+
+ platform_set_drvdata(pdev, NULL);
+
+ if (port)
+ uart_remove_one_port(&ulite_uart_driver, port);
+
+ /* mark port as free */
+ port->membase = 0;
+
+ return 0;
+}
+
+static struct platform_driver ulite_platform_driver = {
+ .probe = ulite_probe,
+ .remove = ulite_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "uartlite",
+ },
+};
+
+int __init ulite_init(void)
+{
+ int ret;
+
+ ret = uart_register_driver(&ulite_uart_driver);
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&ulite_platform_driver);
+ if (ret)
+ uart_unregister_driver(&ulite_uart_driver);
+
+ return ret;
+}
+
+void __exit ulite_exit(void)
+{
+ platform_driver_unregister(&ulite_platform_driver);
+ uart_unregister_driver(&ulite_uart_driver);
+}
+
+module_init(ulite_init);
+module_exit(ulite_exit);
+
+MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
+MODULE_DESCRIPTION("Xilinx uartlite serial driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index c3c0626f550..270e6211c2e 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -360,12 +360,13 @@ spi_alloc_master(struct device *dev, unsigned size)
if (!dev)
return NULL;
- master = kzalloc(size + sizeof *master, SLAB_KERNEL);
+ master = kzalloc(size + sizeof *master, GFP_KERNEL);
if (!master)
return NULL;
class_device_initialize(&master->cdev);
master->cdev.class = &spi_master_class;
+ kobj_set_kset_s(&master->cdev, spi_master_class.subsys);
master->cdev.dev = get_device(dev);
spi_master_set_devdata(master, &master[1]);
@@ -447,7 +448,9 @@ static int __unregister(struct device *dev, void *unused)
*/
void spi_unregister_master(struct spi_master *master)
{
- (void) device_for_each_child(master->cdev.dev, NULL, __unregister);
+ int dummy;
+
+ dummy = device_for_each_child(master->cdev.dev, NULL, __unregister);
class_device_unregister(&master->cdev);
}
EXPORT_SYMBOL_GPL(spi_unregister_master);
@@ -463,15 +466,13 @@ EXPORT_SYMBOL_GPL(spi_unregister_master);
*/
struct spi_master *spi_busnum_to_master(u16 bus_num)
{
- if (bus_num) {
- char name[8];
- struct kobject *bus;
-
- snprintf(name, sizeof name, "spi%u", bus_num);
- bus = kset_find_obj(&spi_master_class.subsys.kset, name);
- if (bus)
- return container_of(bus, struct spi_master, cdev.kobj);
- }
+ char name[9];
+ struct kobject *bus;
+
+ snprintf(name, sizeof name, "spi%u", bus_num);
+ bus = kset_find_obj(&spi_master_class.subsys.kset, name);
+ if (bus)
+ return container_of(bus, struct spi_master, cdev.kobj);
return NULL;
}
EXPORT_SYMBOL_GPL(spi_busnum_to_master);
@@ -607,7 +608,7 @@ static int __init spi_init(void)
{
int status;
- buf = kmalloc(SPI_BUFSIZ, SLAB_KERNEL);
+ buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
if (!buf) {
status = -ENOMEM;
goto err0;
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c
index 08c1c57c612..57289b61d0b 100644
--- a/drivers/spi/spi_bitbang.c
+++ b/drivers/spi/spi_bitbang.c
@@ -196,7 +196,7 @@ int spi_bitbang_setup(struct spi_device *spi)
return -EINVAL;
if (!cs) {
- cs = kzalloc(sizeof *cs, SLAB_KERNEL);
+ cs = kzalloc(sizeof *cs, GFP_KERNEL);
if (!cs)
return -ENOMEM;
spi->controller_state = cs;
diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c
index c2f601f8e4f..312987a0321 100644
--- a/drivers/spi/spi_butterfly.c
+++ b/drivers/spi/spi_butterfly.c
@@ -251,6 +251,8 @@ static void butterfly_attach(struct parport *p)
* setting up a platform device like this is an ugly kluge...
*/
pdev = platform_device_register_simple("butterfly", -1, NULL, 0);
+ if (IS_ERR(pdev))
+ return;
master = spi_alloc_master(&pdev->dev, sizeof *pp);
if (!master) {
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index f2d196fa1e8..dae4ef1e8fe 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -64,6 +64,8 @@
#include <linux/kthread.h>
#include <linux/version.h>
#include <linux/mutex.h>
+#include <linux/freezer.h>
+
#include <asm/unaligned.h>
#include "usbatm.h"
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index 840442a25b6..c3915dc2860 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -93,7 +93,7 @@ void hcd_buffer_destroy (struct usb_hcd *hcd)
}
-/* sometimes alloc/free could use kmalloc with SLAB_DMA, for
+/* sometimes alloc/free could use kmalloc with GFP_DMA, for
* better sharing and to leverage mm/slab.c intelligence.
*/
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 9be41ed1f9a..2651c2e2a89 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -22,6 +22,7 @@
#include <linux/usbdevice_fs.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
+#include <linux/freezer.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>
@@ -460,7 +461,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
* since each TT has "at least two" buffers that can need it (and
* there can be many TTs per hub). even if they're uncommon.
*/
- if ((clear = kmalloc (sizeof *clear, SLAB_ATOMIC)) == NULL) {
+ if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) {
dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n");
/* FIXME recover somehow ... RESET_TT? */
return;
@@ -2371,7 +2372,7 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
struct usb_qualifier_descriptor *qual;
int status;
- qual = kmalloc (sizeof *qual, SLAB_KERNEL);
+ qual = kmalloc (sizeof *qual, GFP_KERNEL);
if (qual == NULL)
return;
@@ -2922,7 +2923,7 @@ static int config_descriptors_changed(struct usb_device *udev)
if (len < le16_to_cpu(udev->config[index].desc.wTotalLength))
len = le16_to_cpu(udev->config[index].desc.wTotalLength);
}
- buf = kmalloc (len, SLAB_KERNEL);
+ buf = kmalloc (len, GFP_KERNEL);
if (buf == NULL) {
dev_err(&udev->dev, "no mem to re-read configs after reset\n");
/* assume the worst */
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 7390b67c609..149aa8bfb1f 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -488,7 +488,7 @@ void usb_sg_wait (struct usb_sg_request *io)
int retval;
io->urbs [i]->dev = io->dev;
- retval = usb_submit_urb (io->urbs [i], SLAB_ATOMIC);
+ retval = usb_submit_urb (io->urbs [i], GFP_ATOMIC);
/* after we submit, let completions or cancelations fire;
* we handshake using io->status.
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 8b975d15538..c98316ce838 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -250,7 +250,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
-#include <linux/suspend.h>
+#include <linux/freezer.h>
#include <linux/utsname.h>
#include <linux/usb_ch9.h>
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index 64554acad63..31351826f2b 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -1236,7 +1236,7 @@ autoconf_fail:
/* ok, we made sense of the hardware ... */
- dev = kzalloc(sizeof(*dev), SLAB_KERNEL);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) {
return -ENOMEM;
}
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index a3076da3f4e..805a9826842 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -1864,7 +1864,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
/* alloc, and start init */
- dev = kmalloc (sizeof *dev, SLAB_KERNEL);
+ dev = kmalloc (sizeof *dev, GFP_KERNEL);
if (dev == NULL){
pr_debug("enomem %s\n", pci_name(pdev));
retval = -ENOMEM;
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 86924f9cdd7..3fb1044a4db 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -412,7 +412,7 @@ ep_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
/* FIXME readahead for O_NONBLOCK and poll(); careful with ZLPs */
value = -ENOMEM;
- kbuf = kmalloc (len, SLAB_KERNEL);
+ kbuf = kmalloc (len, GFP_KERNEL);
if (unlikely (!kbuf))
goto free1;
@@ -456,7 +456,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
/* FIXME writebehind for O_NONBLOCK and poll(), qlen = 1 */
value = -ENOMEM;
- kbuf = kmalloc (len, SLAB_KERNEL);
+ kbuf = kmalloc (len, GFP_KERNEL);
if (!kbuf)
goto free1;
if (copy_from_user (kbuf, buf, len)) {
@@ -1898,7 +1898,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
buf += 4;
length -= 4;
- kbuf = kmalloc (length, SLAB_KERNEL);
+ kbuf = kmalloc (length, GFP_KERNEL);
if (!kbuf)
return -ENOMEM;
if (copy_from_user (kbuf, buf, length)) {
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 0b590831582..3024c679e38 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -2861,7 +2861,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
}
/* alloc, and start init */
- dev = kzalloc (sizeof *dev, SLAB_KERNEL);
+ dev = kzalloc (sizeof *dev, GFP_KERNEL);
if (dev == NULL){
retval = -ENOMEM;
goto done;
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 48a09fd89d1..030d87c28c2 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -2581,7 +2581,7 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv)
/* UDC_PULLUP_EN gates the chip clock */
// OTG_SYSCON_1_REG |= DEV_IDLE_EN;
- udc = kzalloc(sizeof(*udc), SLAB_KERNEL);
+ udc = kzalloc(sizeof(*udc), GFP_KERNEL);
if (!udc)
return -ENOMEM;
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 0f809dd6849..40710ea1b49 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -1190,7 +1190,7 @@ autoconf_fail:
/* ok, we made sense of the hardware ... */
- dev = kzalloc(sizeof(*dev), SLAB_KERNEL);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
spin_lock_init (&dev->lock);
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 34b7a31cd85..56349d21e6e 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -492,7 +492,7 @@ show_periodic (struct class_device *class_dev, char *buf)
unsigned i;
__le32 tag;
- if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC)))
+ if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC)))
return 0;
seen_count = 0;
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index 87eca6aeacf..9325e46a68c 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -188,7 +188,7 @@ static DEFINE_TIMER(bulk_eot_timer, NULL, 0, 0);
#define CHECK_ALIGN(x) if (((__u32)(x)) & 0x00000003) \
{panic("Alignment check (DWORD) failed at %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__);}
-#define SLAB_FLAG (in_interrupt() ? SLAB_ATOMIC : SLAB_KERNEL)
+#define SLAB_FLAG (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL)
#define KMALLOC_FLAG (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL)
/* Most helpful debugging aid */
@@ -275,13 +275,13 @@ static volatile USB_SB_Desc_t TxIntrSB_zout __attribute__ ((aligned (4)));
static int zout_buffer[4] __attribute__ ((aligned (4)));
/* Cache for allocating new EP and SB descriptors. */
-static kmem_cache_t *usb_desc_cache;
+static struct kmem_cache *usb_desc_cache;
/* Cache for the registers allocated in the top half. */
-static kmem_cache_t *top_half_reg_cache;
+static struct kmem_cache *top_half_reg_cache;
/* Cache for the data allocated in the isoc descr top half. */
-static kmem_cache_t *isoc_compl_cache;
+static struct kmem_cache *isoc_compl_cache;
static struct usb_bus *etrax_usb_bus;
@@ -1743,7 +1743,7 @@ static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc)
*R_DMA_CH8_SUB3_CLR_INTR = IO_STATE(R_DMA_CH8_SUB3_CLR_INTR, clr_descr, do);
- comp_data = (usb_isoc_complete_data_t*)kmem_cache_alloc(isoc_compl_cache, SLAB_ATOMIC);
+ comp_data = (usb_isoc_complete_data_t*)kmem_cache_alloc(isoc_compl_cache, GFP_ATOMIC);
assert(comp_data != NULL);
INIT_WORK(&comp_data->usb_bh, etrax_usb_isoc_descr_interrupt_bottom_half, comp_data);
@@ -3010,7 +3010,7 @@ static void etrax_usb_add_to_isoc_sb_list(struct urb *urb, int epid)
if (!urb->iso_frame_desc[i].length)
continue;
- next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_ATOMIC);
+ next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_ATOMIC);
assert(next_sb_desc != NULL);
if (urb->iso_frame_desc[i].length > 0) {
@@ -3063,7 +3063,7 @@ static void etrax_usb_add_to_isoc_sb_list(struct urb *urb, int epid)
if (TxIsocEPList[epid].sub == 0) {
dbg_isoc("Isoc traffic not already running, allocating SB");
- next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_ATOMIC);
+ next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_ATOMIC);
assert(next_sb_desc != NULL);
next_sb_desc->command = (IO_STATE(USB_SB_command, tt, in) |
@@ -3317,7 +3317,7 @@ static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc)
restore_flags(flags);
- reg = (usb_interrupt_registers_t *)kmem_cache_alloc(top_half_reg_cache, SLAB_ATOMIC);
+ reg = (usb_interrupt_registers_t *)kmem_cache_alloc(top_half_reg_cache, GFP_ATOMIC);
assert(reg != NULL);
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index 8293c1d4be3..0f47a57dac2 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -505,7 +505,7 @@ show_periodic (struct class_device *class_dev, char *buf)
char *next;
unsigned i;
- if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC)))
+ if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC)))
return 0;
seen_count = 0;
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c
index 2dbb7741490..7f26f9bdbaf 100644
--- a/drivers/usb/host/ohci-pnx4008.c
+++ b/drivers/usb/host/ohci-pnx4008.c
@@ -134,7 +134,7 @@ static int isp1301_attach(struct i2c_adapter *adap, int addr, int kind)
{
struct i2c_client *c;
- c = (struct i2c_client *)kzalloc(sizeof(*c), SLAB_KERNEL);
+ c = (struct i2c_client *)kzalloc(sizeof(*c), GFP_KERNEL);
if (!c)
return -ENOMEM;
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 226bf3de8ed..e87692c31be 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -81,7 +81,7 @@ MODULE_PARM_DESC(debug, "Debug level");
static char *errbuf;
#define ERRBUF_LEN (32 * 1024)
-static kmem_cache_t *uhci_up_cachep; /* urb_priv */
+static struct kmem_cache *uhci_up_cachep; /* urb_priv */
static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state);
static void wakeup_rh(struct uhci_hcd *uhci);
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 06115f22a4f..30b88459ac7 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -498,7 +498,7 @@ static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci,
{
struct urb_priv *urbp;
- urbp = kmem_cache_alloc(uhci_up_cachep, SLAB_ATOMIC);
+ urbp = kmem_cache_alloc(uhci_up_cachep, GFP_ATOMIC);
if (!urbp)
return NULL;
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c
index 0096373b5f9..909138e5aa0 100644
--- a/drivers/usb/input/acecad.c
+++ b/drivers/usb/input/acecad.c
@@ -152,7 +152,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
if (!acecad || !input_dev)
goto fail1;
- acecad->data = usb_buffer_alloc(dev, 8, SLAB_KERNEL, &acecad->data_dma);
+ acecad->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &acecad->data_dma);
if (!acecad->data)
goto fail1;
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
index bf428184608..9f52429ce65 100644
--- a/drivers/usb/input/aiptek.c
+++ b/drivers/usb/input/aiptek.c
@@ -1988,7 +1988,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
goto fail1;
aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
- SLAB_ATOMIC, &aiptek->data_dma);
+ GFP_ATOMIC, &aiptek->data_dma);
if (!aiptek->data)
goto fail1;
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
index ff23318dc30..b724e36f7b9 100644
--- a/drivers/usb/input/ati_remote.c
+++ b/drivers/usb/input/ati_remote.c
@@ -592,7 +592,7 @@ static void ati_remote_irq_in(struct urb *urb)
__FUNCTION__, urb->status);
}
- retval = usb_submit_urb(urb, SLAB_ATOMIC);
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n",
__FUNCTION__, retval);
@@ -604,12 +604,12 @@ static void ati_remote_irq_in(struct urb *urb)
static int ati_remote_alloc_buffers(struct usb_device *udev,
struct ati_remote *ati_remote)
{
- ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
+ ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC,
&ati_remote->inbuf_dma);
if (!ati_remote->inbuf)
return -1;
- ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
+ ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC,
&ati_remote->outbuf_dma);
if (!ati_remote->outbuf)
return -1;
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 4295bab4f1e..f1d0e1d6982 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1079,7 +1079,7 @@ static void hid_irq_in(struct urb *urb)
warn("input irq status %d received", urb->status);
}
- status = usb_submit_urb(urb, SLAB_ATOMIC);
+ status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
clear_bit(HID_IN_RUNNING, &hid->iofl);
if (status != -EPERM) {
@@ -1864,13 +1864,13 @@ static void hid_find_max_report(struct hid_device *hid, unsigned int type, int *
static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
{
- if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->inbuf_dma)))
+ if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->inbuf_dma)))
return -1;
- if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->outbuf_dma)))
+ if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->outbuf_dma)))
return -1;
- if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma)))
+ if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), GFP_ATOMIC, &hid->cr_dma)))
return -1;
- if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->ctrlbuf_dma)))
+ if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->ctrlbuf_dma)))
return -1;
return 0;
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
index 50aa8108a50..98bd323369c 100644
--- a/drivers/usb/input/keyspan_remote.c
+++ b/drivers/usb/input/keyspan_remote.c
@@ -456,7 +456,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
remote->in_endpoint = endpoint;
remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */
- remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma);
+ remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, GFP_ATOMIC, &remote->in_dma);
if (!remote->in_buffer) {
retval = -ENOMEM;
goto fail1;
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
index 79a85d46cb1..92c4e07da4c 100644
--- a/drivers/usb/input/mtouchusb.c
+++ b/drivers/usb/input/mtouchusb.c
@@ -164,7 +164,7 @@ static int mtouchusb_alloc_buffers(struct usb_device *udev, struct mtouch_usb *m
dbg("%s - called", __FUNCTION__);
mtouch->data = usb_buffer_alloc(udev, MTOUCHUSB_REPORT_DATA_SIZE,
- SLAB_ATOMIC, &mtouch->data_dma);
+ GFP_ATOMIC, &mtouch->data_dma);
if (!mtouch->data)
return -1;
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
index 0bf91778c40..fea97e5437f 100644
--- a/drivers/usb/input/powermate.c
+++ b/drivers/usb/input/powermate.c
@@ -277,12 +277,12 @@ static int powermate_input_event(struct input_dev *dev, unsigned int type, unsig
static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_device *pm)
{
pm->data = usb_buffer_alloc(udev, POWERMATE_PAYLOAD_SIZE_MAX,
- SLAB_ATOMIC, &pm->data_dma);
+ GFP_ATOMIC, &pm->data_dma);
if (!pm->data)
return -1;
pm->configcr = usb_buffer_alloc(udev, sizeof(*(pm->configcr)),
- SLAB_ATOMIC, &pm->configcr_dma);
+ GFP_ATOMIC, &pm->configcr_dma);
if (!pm->configcr)
return -1;
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c
index 05c0d1ca39a..2a314b06592 100644
--- a/drivers/usb/input/touchkitusb.c
+++ b/drivers/usb/input/touchkitusb.c
@@ -248,7 +248,7 @@ static int touchkit_alloc_buffers(struct usb_device *udev,
struct touchkit_usb *touchkit)
{
touchkit->data = usb_buffer_alloc(udev, TOUCHKIT_REPORT_DATA_SIZE,
- SLAB_ATOMIC, &touchkit->data_dma);
+ GFP_ATOMIC, &touchkit->data_dma);
if (!touchkit->data)
return -1;
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
index dac88640eab..8505824848f 100644
--- a/drivers/usb/input/usbkbd.c
+++ b/drivers/usb/input/usbkbd.c
@@ -122,7 +122,7 @@ static void usb_kbd_irq(struct urb *urb)
memcpy(kbd->old, kbd->new, 8);
resubmit:
- i = usb_submit_urb (urb, SLAB_ATOMIC);
+ i = usb_submit_urb (urb, GFP_ATOMIC);
if (i)
err ("can't resubmit intr, %s-%s/input0, status %d",
kbd->usbdev->bus->bus_name,
@@ -196,11 +196,11 @@ static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd)
return -1;
if (!(kbd->led = usb_alloc_urb(0, GFP_KERNEL)))
return -1;
- if (!(kbd->new = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &kbd->new_dma)))
+ if (!(kbd->new = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &kbd->new_dma)))
return -1;
- if (!(kbd->cr = usb_buffer_alloc(dev, sizeof(struct usb_ctrlrequest), SLAB_ATOMIC, &kbd->cr_dma)))
+ if (!(kbd->cr = usb_buffer_alloc(dev, sizeof(struct usb_ctrlrequest), GFP_ATOMIC, &kbd->cr_dma)))
return -1;
- if (!(kbd->leds = usb_buffer_alloc(dev, 1, SLAB_ATOMIC, &kbd->leds_dma)))
+ if (!(kbd->leds = usb_buffer_alloc(dev, 1, GFP_ATOMIC, &kbd->leds_dma)))
return -1;
return 0;
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
index 68a55642c08..64a33e420cf 100644
--- a/drivers/usb/input/usbmouse.c
+++ b/drivers/usb/input/usbmouse.c
@@ -86,7 +86,7 @@ static void usb_mouse_irq(struct urb *urb)
input_sync(dev);
resubmit:
- status = usb_submit_urb (urb, SLAB_ATOMIC);
+ status = usb_submit_urb (urb, GFP_ATOMIC);
if (status)
err ("can't resubmit intr, %s-%s/input0, status %d",
mouse->usbdev->bus->bus_name,
@@ -137,7 +137,7 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i
if (!mouse || !input_dev)
goto fail1;
- mouse->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &mouse->data_dma);
+ mouse->data = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &mouse->data_dma);
if (!mouse->data)
goto fail1;
diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c
index 49704d4ed0e..7f3c57da9bc 100644
--- a/drivers/usb/input/usbtouchscreen.c
+++ b/drivers/usb/input/usbtouchscreen.c
@@ -680,7 +680,7 @@ static int usbtouch_probe(struct usb_interface *intf,
type->process_pkt = usbtouch_process_pkt;
usbtouch->data = usb_buffer_alloc(udev, type->rept_size,
- SLAB_KERNEL, &usbtouch->data_dma);
+ GFP_KERNEL, &usbtouch->data_dma);
if (!usbtouch->data)
goto out_free;
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index df97e5c803f..e4bc76ebc83 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -325,7 +325,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
goto fail1;
xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN,
- SLAB_ATOMIC, &xpad->idata_dma);
+ GFP_ATOMIC, &xpad->idata_dma);
if (!xpad->idata)
goto fail1;
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c
index 2268ca311ad..caff8e6d744 100644
--- a/drivers/usb/input/yealink.c
+++ b/drivers/usb/input/yealink.c
@@ -874,17 +874,17 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* allocate usb buffers */
yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
- SLAB_ATOMIC, &yld->irq_dma);
+ GFP_ATOMIC, &yld->irq_dma);
if (yld->irq_data == NULL)
return usb_cleanup(yld, -ENOMEM);
yld->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN,
- SLAB_ATOMIC, &yld->ctl_dma);
+ GFP_ATOMIC, &yld->ctl_dma);
if (!yld->ctl_data)
return usb_cleanup(yld, -ENOMEM);
yld->ctl_req = usb_buffer_alloc(udev, sizeof(*(yld->ctl_req)),
- SLAB_ATOMIC, &yld->ctl_req_dma);
+ GFP_ATOMIC, &yld->ctl_req_dma);
if (yld->ctl_req == NULL)
return usb_cleanup(yld, -ENOMEM);
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c
index 9659c79e187..371bf2b1197 100644
--- a/drivers/usb/misc/phidgetkit.c
+++ b/drivers/usb/misc/phidgetkit.c
@@ -377,7 +377,7 @@ static void interfacekit_irq(struct urb *urb)
schedule_delayed_work(&kit->do_notify, 0);
resubmit:
- status = usb_submit_urb(urb, SLAB_ATOMIC);
+ status = usb_submit_urb(urb, GFP_ATOMIC);
if (status)
err("can't resubmit intr, %s-%s/interfacekit0, status %d",
kit->udev->bus->bus_name,
@@ -568,7 +568,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
kit->dev_no = -1;
kit->ifkit = ifkit;
- kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &kit->data_dma);
+ kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &kit->data_dma);
if (!kit->data)
goto out;
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c
index 2bb4fa572bb..5727e1ea2f9 100644
--- a/drivers/usb/misc/phidgetmotorcontrol.c
+++ b/drivers/usb/misc/phidgetmotorcontrol.c
@@ -151,7 +151,7 @@ static void motorcontrol_irq(struct urb *urb)
schedule_delayed_work(&mc->do_notify, 0);
resubmit:
- status = usb_submit_urb(urb, SLAB_ATOMIC);
+ status = usb_submit_urb(urb, GFP_ATOMIC);
if (status)
dev_err(&mc->intf->dev,
"can't resubmit intr, %s-%s/motorcontrol0, status %d",
@@ -338,7 +338,7 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic
goto out;
mc->dev_no = -1;
- mc->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &mc->data_dma);
+ mc->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &mc->data_dma);
if (!mc->data)
goto out;
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 194065dbb51..fb321864a92 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -213,7 +213,7 @@ static struct urb *simple_alloc_urb (
if (bytes < 0)
return NULL;
- urb = usb_alloc_urb (0, SLAB_KERNEL);
+ urb = usb_alloc_urb (0, GFP_KERNEL);
if (!urb)
return urb;
usb_fill_bulk_urb (urb, udev, pipe, NULL, bytes, simple_callback, NULL);
@@ -223,7 +223,7 @@ static struct urb *simple_alloc_urb (
urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
if (usb_pipein (pipe))
urb->transfer_flags |= URB_SHORT_NOT_OK;
- urb->transfer_buffer = usb_buffer_alloc (udev, bytes, SLAB_KERNEL,
+ urb->transfer_buffer = usb_buffer_alloc (udev, bytes, GFP_KERNEL,
&urb->transfer_dma);
if (!urb->transfer_buffer) {
usb_free_urb (urb);
@@ -315,7 +315,7 @@ static int simple_io (
init_completion (&completion);
if (usb_pipeout (urb->pipe))
simple_fill_buf (urb);
- if ((retval = usb_submit_urb (urb, SLAB_KERNEL)) != 0)
+ if ((retval = usb_submit_urb (urb, GFP_KERNEL)) != 0)
break;
/* NOTE: no timeouts; can't be broken out of by interrupt */
@@ -374,7 +374,7 @@ alloc_sglist (int nents, int max, int vary)
unsigned i;
unsigned size = max;
- sg = kmalloc (nents * sizeof *sg, SLAB_KERNEL);
+ sg = kmalloc (nents * sizeof *sg, GFP_KERNEL);
if (!sg)
return NULL;
@@ -382,7 +382,7 @@ alloc_sglist (int nents, int max, int vary)
char *buf;
unsigned j;
- buf = kzalloc (size, SLAB_KERNEL);
+ buf = kzalloc (size, GFP_KERNEL);
if (!buf) {
free_sglist (sg, i);
return NULL;
@@ -428,7 +428,7 @@ static int perform_sglist (
(udev->speed == USB_SPEED_HIGH)
? (INTERRUPT_RATE << 3)
: INTERRUPT_RATE,
- sg, nents, 0, SLAB_KERNEL);
+ sg, nents, 0, GFP_KERNEL);
if (retval)
break;
@@ -819,7 +819,7 @@ error:
/* resubmit if we need to, else mark this as done */
if ((status == 0) && (ctx->pending < ctx->count)) {
- if ((status = usb_submit_urb (urb, SLAB_ATOMIC)) != 0) {
+ if ((status = usb_submit_urb (urb, GFP_ATOMIC)) != 0) {
dbg ("can't resubmit ctrl %02x.%02x, err %d",
reqp->bRequestType, reqp->bRequest, status);
urb->dev = NULL;
@@ -855,7 +855,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
* as with bulk/intr sglists, sglen is the queue depth; it also
* controls which subtests run (more tests than sglen) or rerun.
*/
- urb = kcalloc(param->sglen, sizeof(struct urb *), SLAB_KERNEL);
+ urb = kcalloc(param->sglen, sizeof(struct urb *), GFP_KERNEL);
if (!urb)
return -ENOMEM;
for (i = 0; i < param->sglen; i++) {
@@ -981,7 +981,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
if (!u)
goto cleanup;
- reqp = usb_buffer_alloc (udev, sizeof *reqp, SLAB_KERNEL,
+ reqp = usb_buffer_alloc (udev, sizeof *reqp, GFP_KERNEL,
&u->setup_dma);
if (!reqp)
goto cleanup;
@@ -999,7 +999,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
context.urb = urb;
spin_lock_irq (&context.lock);
for (i = 0; i < param->sglen; i++) {
- context.status = usb_submit_urb (urb [i], SLAB_ATOMIC);
+ context.status = usb_submit_urb (urb [i], GFP_ATOMIC);
if (context.status != 0) {
dbg ("can't submit urb[%d], status %d",
i, context.status);
@@ -1041,7 +1041,7 @@ static void unlink1_callback (struct urb *urb)
// we "know" -EPIPE (stall) never happens
if (!status)
- status = usb_submit_urb (urb, SLAB_ATOMIC);
+ status = usb_submit_urb (urb, GFP_ATOMIC);
if (status) {
urb->status = status;
complete ((struct completion *) urb->context);
@@ -1067,7 +1067,7 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async)
* FIXME want additional tests for when endpoint is STALLing
* due to errors, or is just NAKing requests.
*/
- if ((retval = usb_submit_urb (urb, SLAB_KERNEL)) != 0) {
+ if ((retval = usb_submit_urb (urb, GFP_KERNEL)) != 0) {
dev_dbg (&dev->intf->dev, "submit fail %d\n", retval);
return retval;
}
@@ -1251,7 +1251,7 @@ static int ctrl_out (struct usbtest_dev *dev,
if (length < 1 || length > 0xffff || vary >= length)
return -EINVAL;
- buf = kmalloc(length, SLAB_KERNEL);
+ buf = kmalloc(length, GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -1403,7 +1403,7 @@ static struct urb *iso_alloc_urb (
maxp *= 1 + (0x3 & (le16_to_cpu(desc->wMaxPacketSize) >> 11));
packets = (bytes + maxp - 1) / maxp;
- urb = usb_alloc_urb (packets, SLAB_KERNEL);
+ urb = usb_alloc_urb (packets, GFP_KERNEL);
if (!urb)
return urb;
urb->dev = udev;
@@ -1411,7 +1411,7 @@ static struct urb *iso_alloc_urb (
urb->number_of_packets = packets;
urb->transfer_buffer_length = bytes;
- urb->transfer_buffer = usb_buffer_alloc (udev, bytes, SLAB_KERNEL,
+ urb->transfer_buffer = usb_buffer_alloc (udev, bytes, GFP_KERNEL,
&urb->transfer_dma);
if (!urb->transfer_buffer) {
usb_free_urb (urb);
@@ -1481,7 +1481,7 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param,
spin_lock_irq (&context.lock);
for (i = 0; i < param->sglen; i++) {
++context.pending;
- status = usb_submit_urb (urbs [i], SLAB_ATOMIC);
+ status = usb_submit_urb (urbs [i], GFP_ATOMIC);
if (status < 0) {
ERROR (dev, "submit iso[%d], error %d\n", i, status);
if (i == 0) {
@@ -1900,7 +1900,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id)
}
#endif
- dev = kzalloc(sizeof(*dev), SLAB_KERNEL);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
info = (struct usbtest_info *) id->driver_info;
@@ -1910,7 +1910,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id)
dev->intf = intf;
/* cacheline-aligned scratch for i/o */
- if ((dev->buf = kmalloc (TBUF_SIZE, SLAB_KERNEL)) == NULL) {
+ if ((dev->buf = kmalloc (TBUF_SIZE, GFP_KERNEL)) == NULL) {
kfree (dev);
return -ENOMEM;
}
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index 7a2346c5328..05cf2c9a8f8 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -50,7 +50,7 @@ struct mon_event_text {
#define SLAB_NAME_SZ 30
struct mon_reader_text {
- kmem_cache_t *e_slab;
+ struct kmem_cache *e_slab;
int nevents;
struct list_head e_list;
struct mon_reader r; /* In C, parent class can be placed anywhere */
@@ -63,7 +63,7 @@ struct mon_reader_text {
char slab_name[SLAB_NAME_SZ];
};
-static void mon_text_ctor(void *, kmem_cache_t *, unsigned long);
+static void mon_text_ctor(void *, struct kmem_cache *, unsigned long);
/*
* mon_text_submit
@@ -147,7 +147,7 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb,
stamp = mon_get_timestamp();
if (rp->nevents >= EVENT_MAX ||
- (ep = kmem_cache_alloc(rp->e_slab, SLAB_ATOMIC)) == NULL) {
+ (ep = kmem_cache_alloc(rp->e_slab, GFP_ATOMIC)) == NULL) {
rp->r.m_bus->cnt_text_lost++;
return;
}
@@ -188,7 +188,7 @@ static void mon_text_error(void *data, struct urb *urb, int error)
struct mon_event_text *ep;
if (rp->nevents >= EVENT_MAX ||
- (ep = kmem_cache_alloc(rp->e_slab, SLAB_ATOMIC)) == NULL) {
+ (ep = kmem_cache_alloc(rp->e_slab, GFP_ATOMIC)) == NULL) {
rp->r.m_bus->cnt_text_lost++;
return;
}
@@ -450,7 +450,7 @@ const struct file_operations mon_fops_text = {
/*
* Slab interface: constructor.
*/
-static void mon_text_ctor(void *mem, kmem_cache_t *slab, unsigned long sflags)
+static void mon_text_ctor(void *mem, struct kmem_cache *slab, unsigned long sflags)
{
/*
* Nothing to initialize. No, really!
diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c
index 907b820a5fa..4852012735f 100644
--- a/drivers/usb/net/catc.c
+++ b/drivers/usb/net/catc.c
@@ -345,7 +345,7 @@ static void catc_irq_done(struct urb *urb)
}
}
resubmit:
- status = usb_submit_urb (urb, SLAB_ATOMIC);
+ status = usb_submit_urb (urb, GFP_ATOMIC);
if (status)
err ("can't resubmit intr, %s-%s, status %d",
catc->usbdev->bus->bus_name,
diff --git a/drivers/usb/net/net1080.c b/drivers/usb/net/net1080.c
index a77410562e1..49363595451 100644
--- a/drivers/usb/net/net1080.c
+++ b/drivers/usb/net/net1080.c
@@ -383,7 +383,7 @@ static void nc_ensure_sync(struct usbnet *dev)
int status;
/* Send a flush */
- urb = usb_alloc_urb(0, SLAB_ATOMIC);
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb)
return;
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
index b5690b3834e..d48c024cff5 100644
--- a/drivers/usb/net/pegasus.c
+++ b/drivers/usb/net/pegasus.c
@@ -856,7 +856,7 @@ static void intr_callback(struct urb *urb)
pegasus->stats.rx_missed_errors += ((d[3] & 0x7f) << 8) | d[4];
}
- status = usb_submit_urb(urb, SLAB_ATOMIC);
+ status = usb_submit_urb(urb, GFP_ATOMIC);
if (status == -ENODEV)
netif_device_detach(pegasus->net);
if (status && netif_msg_timer(pegasus))
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c
index c2a28d88ef3..99f26b3e502 100644
--- a/drivers/usb/net/rndis_host.c
+++ b/drivers/usb/net/rndis_host.c
@@ -469,7 +469,7 @@ static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
struct rndis_halt *halt;
/* try to clear any rndis state/activity (no i/o from stack!) */
- halt = kcalloc(1, sizeof *halt, SLAB_KERNEL);
+ halt = kcalloc(1, sizeof *halt, GFP_KERNEL);
if (halt) {
halt->msg_type = RNDIS_MSG_HALT;
halt->msg_len = ccpu2(sizeof *halt);
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
index 72171f94ded..c54235f73cb 100644
--- a/drivers/usb/net/rtl8150.c
+++ b/drivers/usb/net/rtl8150.c
@@ -587,7 +587,7 @@ static void intr_callback(struct urb *urb)
}
resubmit:
- status = usb_submit_urb (urb, SLAB_ATOMIC);
+ status = usb_submit_urb (urb, GFP_ATOMIC);
if (status == -ENODEV)
netif_device_detach(dev->netdev);
else if (status)
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index 327f9755567..6e39e998825 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -179,9 +179,9 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf)
period = max ((int) dev->status->desc.bInterval,
(dev->udev->speed == USB_SPEED_HIGH) ? 7 : 3);
- buf = kmalloc (maxp, SLAB_KERNEL);
+ buf = kmalloc (maxp, GFP_KERNEL);
if (buf) {
- dev->interrupt = usb_alloc_urb (0, SLAB_KERNEL);
+ dev->interrupt = usb_alloc_urb (0, GFP_KERNEL);
if (!dev->interrupt) {
kfree (buf);
return -ENOMEM;
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 82cd15b894b..70f93b18292 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -363,7 +363,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
/* Initialising the write urb pool */
for (j = 0; j < NUM_URBS; ++j) {
- urb = usb_alloc_urb(0,SLAB_ATOMIC);
+ urb = usb_alloc_urb(0,GFP_ATOMIC);
mos7720_port->write_urb_pool[j] = urb;
if (urb == NULL) {
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 02c89e10b2c..5432c634008 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -826,7 +826,7 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp)
/* Initialising the write urb pool */
for (j = 0; j < NUM_URBS; ++j) {
- urb = usb_alloc_urb(0, SLAB_ATOMIC);
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
mos7840_port->write_urb_pool[j] = urb;
if (urb == NULL) {
@@ -2786,7 +2786,7 @@ static int mos7840_startup(struct usb_serial *serial)
i + 1, status);
}
- mos7840_port->control_urb = usb_alloc_urb(0, SLAB_ATOMIC);
+ mos7840_port->control_urb = usb_alloc_urb(0, GFP_ATOMIC);
mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
}
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index 3a158d58441..e565d3d2ab2 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -76,7 +76,7 @@ static void usb_onetouch_irq(struct urb *urb)
input_sync(dev);
resubmit:
- status = usb_submit_urb (urb, SLAB_ATOMIC);
+ status = usb_submit_urb (urb, GFP_ATOMIC);
if (status)
err ("can't resubmit intr, %s-%s/input0, status %d",
onetouch->udev->bus->bus_name,
@@ -154,7 +154,7 @@ int onetouch_connect_input(struct us_data *ss)
goto fail1;
onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN,
- SLAB_ATOMIC, &onetouch->data_dma);
+ GFP_ATOMIC, &onetouch->data_dma);
if (!onetouch->data)
goto fail1;
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 47644b5b615..323293a3e61 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -427,7 +427,7 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
US_DEBUGP("%s: xfer %u bytes, %d entries\n", __FUNCTION__,
length, num_sg);
result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0,
- sg, num_sg, length, SLAB_NOIO);
+ sg, num_sg, length, GFP_NOIO);
if (result) {
US_DEBUGP("usb_sg_init returned %d\n", result);
return USB_STOR_XFER_ERROR;
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index b401084b3d2..70644506651 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -49,7 +49,7 @@
#include <linux/sched.h>
#include <linux/errno.h>
-#include <linux/suspend.h>
+#include <linux/freezer.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
index 0d3643fc629..a454dcb8e21 100644
--- a/drivers/video/geode/gxfb_core.c
+++ b/drivers/video/geode/gxfb_core.c
@@ -380,7 +380,7 @@ static void gxfb_remove(struct pci_dev *pdev)
}
static struct pci_device_id gxfb_id_table[] = {
- { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_VIDEO,
+ { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_GX_VIDEO,
PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
0xff0000, 0 },
{ 0, }
diff --git a/drivers/w1/Makefile b/drivers/w1/Makefile
index 93845a2c7c2..6bb0b54965f 100644
--- a/drivers/w1/Makefile
+++ b/drivers/w1/Makefile
@@ -2,10 +2,6 @@
# Makefile for the Dallas's 1-wire bus.
#
-ifeq ($(CONFIG_W1_DS2433_CRC), y)
-EXTRA_CFLAGS += -DCONFIG_W1_F23_CRC
-endif
-
obj-$(CONFIG_W1) += wire.o
wire-objs := w1.o w1_int.o w1_family.o w1_netlink.o w1_io.o
diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile
index 70e21e2d70c..725dcfdfddb 100644
--- a/drivers/w1/slaves/Makefile
+++ b/drivers/w1/slaves/Makefile
@@ -2,10 +2,6 @@
# Makefile for the Dallas's 1-wire slaves.
#
-ifeq ($(CONFIG_W1_SLAVE_DS2433_CRC), y)
-EXTRA_CFLAGS += -DCONFIG_W1_F23_CRC
-endif
-
obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o
obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o
obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o
diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c
index 2ac238f1480..8ea17a53eed 100644
--- a/drivers/w1/slaves/w1_ds2433.c
+++ b/drivers/w1/slaves/w1_ds2433.c
@@ -13,7 +13,7 @@
#include <linux/device.h>
#include <linux/types.h>
#include <linux/delay.h>
-#ifdef CONFIG_W1_F23_CRC
+#ifdef CONFIG_W1_SLAVE_DS2433_CRC
#include <linux/crc16.h>
#define CRC16_INIT 0
@@ -62,7 +62,7 @@ static inline size_t w1_f23_fix_count(loff_t off, size_t count, size_t size)
return count;
}
-#ifdef CONFIG_W1_F23_CRC
+#ifdef CONFIG_W1_SLAVE_DS2433_CRC
static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data,
int block)
{
@@ -89,13 +89,13 @@ static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data,
return 0;
}
-#endif /* CONFIG_W1_F23_CRC */
+#endif /* CONFIG_W1_SLAVE_DS2433_CRC */
static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off,
size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
-#ifdef CONFIG_W1_F23_CRC
+#ifdef CONFIG_W1_SLAVE_DS2433_CRC
struct w1_f23_data *data = sl->family_data;
int i, min_page, max_page;
#else
@@ -107,7 +107,7 @@ static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off,
mutex_lock(&sl->master->mutex);
-#ifdef CONFIG_W1_F23_CRC
+#ifdef CONFIG_W1_SLAVE_DS2433_CRC
min_page = (off >> W1_PAGE_BITS);
max_page = (off + count - 1) >> W1_PAGE_BITS;
@@ -119,7 +119,7 @@ static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off,
}
memcpy(buf, &data->memory[off], count);
-#else /* CONFIG_W1_F23_CRC */
+#else /* CONFIG_W1_SLAVE_DS2433_CRC */
/* read directly from the EEPROM */
if (w1_reset_select_slave(sl)) {
@@ -133,7 +133,7 @@ static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off,
w1_write_block(sl->master, wrbuf, 3);
w1_read_block(sl->master, buf, count);
-#endif /* CONFIG_W1_F23_CRC */
+#endif /* CONFIG_W1_SLAVE_DS2433_CRC */
out_up:
mutex_unlock(&sl->master->mutex);
@@ -208,7 +208,7 @@ static ssize_t w1_f23_write_bin(struct kobject *kobj, char *buf, loff_t off,
if ((count = w1_f23_fix_count(off, count, W1_EEPROM_SIZE)) == 0)
return 0;
-#ifdef CONFIG_W1_F23_CRC
+#ifdef CONFIG_W1_SLAVE_DS2433_CRC
/* can only write full blocks in cached mode */
if ((off & W1_PAGE_MASK) || (count & W1_PAGE_MASK)) {
dev_err(&sl->dev, "invalid offset/count off=%d cnt=%zd\n",
@@ -223,7 +223,7 @@ static ssize_t w1_f23_write_bin(struct kobject *kobj, char *buf, loff_t off,
return -EINVAL;
}
}
-#endif /* CONFIG_W1_F23_CRC */
+#endif /* CONFIG_W1_SLAVE_DS2433_CRC */
mutex_lock(&sl->master->mutex);
@@ -262,7 +262,7 @@ static struct bin_attribute w1_f23_bin_attr = {
static int w1_f23_add_slave(struct w1_slave *sl)
{
int err;
-#ifdef CONFIG_W1_F23_CRC
+#ifdef CONFIG_W1_SLAVE_DS2433_CRC
struct w1_f23_data *data;
data = kmalloc(sizeof(struct w1_f23_data), GFP_KERNEL);
@@ -271,24 +271,24 @@ static int w1_f23_add_slave(struct w1_slave *sl)
memset(data, 0, sizeof(struct w1_f23_data));
sl->family_data = data;
-#endif /* CONFIG_W1_F23_CRC */
+#endif /* CONFIG_W1_SLAVE_DS2433_CRC */
err = sysfs_create_bin_file(&sl->dev.kobj, &w1_f23_bin_attr);
-#ifdef CONFIG_W1_F23_CRC
+#ifdef CONFIG_W1_SLAVE_DS2433_CRC
if (err)
kfree(data);
-#endif /* CONFIG_W1_F23_CRC */
+#endif /* CONFIG_W1_SLAVE_DS2433_CRC */
return err;
}
static void w1_f23_remove_slave(struct w1_slave *sl)
{
-#ifdef CONFIG_W1_F23_CRC
+#ifdef CONFIG_W1_SLAVE_DS2433_CRC
kfree(sl->family_data);
sl->family_data = NULL;
-#endif /* CONFIG_W1_F23_CRC */
+#endif /* CONFIG_W1_SLAVE_DS2433_CRC */
sysfs_remove_bin_file(&sl->dev.kobj, &w1_f23_bin_attr);
}
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index de3e9791f80..63c07243993 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -31,6 +31,7 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/kthread.h>
+#include <linux/freezer.h>
#include <asm/atomic.h>