Commit 171b1609 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://lia64.bkbits.net/linux-ia64-release-2.6.11

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 9790ee6f f21ec409
The PCI Express Port Bus Driver Guide HOWTO
Tom L Nguyen tom.l.nguyen@intel.com
11/03/2004
1. About this guide
This guide describes the basics of the PCI Express Port Bus driver
and provides information on how to enable the service drivers to
register/unregister with the PCI Express Port Bus Driver.
2. Copyright 2004 Intel Corporation
3. What is the PCI Express Port Bus Driver
A PCI Express Port is a logical PCI-PCI Bridge structure. There
are two types of PCI Express Port: the Root Port and the Switch
Port. The Root Port originates a PCI Express link from a PCI Express
Root Complex and the Switch Port connects PCI Express links to
internal logical PCI buses. The Switch Port, which has its secondary
bus representing the switch's internal routing logic, is called the
switch's Upstream Port. The switch's Downstream Port is bridging from
switch's internal routing bus to a bus representing the downstream
PCI Express link from the PCI Express Switch.
A PCI Express Port can provide up to four distinct functions,
referred to in this document as services, depending on its port type.
PCI Express Port's services include native hotplug support (HP),
power management event support (PME), advanced error reporting
support (AER), and virtual channel support (VC). These services may
be handled by a single complex driver or be individually distributed
and handled by corresponding service drivers.
4. Why use the PCI Express Port Bus Driver?
In existing Linux kernels, the Linux Device Driver Model allows a
physical device to be handled by only a single driver. The PCI
Express Port is a PCI-PCI Bridge device with multiple distinct
services. To maintain a clean and simple solution each service
may have its own software service driver. In this case several
service drivers will compete for a single PCI-PCI Bridge device.
For example, if the PCI Express Root Port native hotplug service
driver is loaded first, it claims a PCI-PCI Bridge Root Port. The
kernel therefore does not load other service drivers for that Root
Port. In other words, it is impossible to have multiple service
drivers load and run on a PCI-PCI Bridge device simultaneously
using the current driver model.
To enable multiple service drivers running simultaneously requires
having a PCI Express Port Bus driver, which manages all populated
PCI Express Ports and distributes all provided service requests
to the corresponding service drivers as required. Some key
advantages of using the PCI Express Port Bus driver are listed below:
- Allow multiple service drivers to run simultaneously on
a PCI-PCI Bridge Port device.
- Allow service drivers implemented in an independent
staged approach.
- Allow one service driver to run on multiple PCI-PCI Bridge
Port devices.
- Manage and distribute resources of a PCI-PCI Bridge Port
device to requested service drivers.
5. Configuring the PCI Express Port Bus Driver vs. Service Drivers
5.1 Including the PCI Express Port Bus Driver Support into the Kernel
Including the PCI Express Port Bus driver depends on whether the PCI
Express support is included in the kernel config. The kernel will
automatically include the PCI Express Port Bus driver as a kernel
driver when the PCI Express support is enabled in the kernel.
5.2 Enabling Service Driver Support
PCI device drivers are implemented based on Linux Device Driver Model.
All service drivers are PCI device drivers. As discussed above, it is
impossible to load any service driver once the kernel has loaded the
PCI Express Port Bus Driver. To meet the PCI Express Port Bus Driver
Model requires some minimal changes on existing service drivers that
imposes no impact on the functionality of existing service drivers.
A service driver is required to use the two APIs shown below to
register its service with the PCI Express Port Bus driver (see
section 5.2.1 & 5.2.2). It is important that a service driver
initializes the pcie_port_service_driver data structure, included in
header file /include/linux/pcieport_if.h, before calling these APIs.
Failure to do so will result an identity mismatch, which prevents
the PCI Express Port Bus driver from loading a service driver.
5.2.1 pcie_port_service_register
int pcie_port_service_register(struct pcie_port_service_driver *new)
This API replaces the Linux Driver Model's pci_module_init API. A
service driver should always calls pcie_port_service_register at
module init. Note that after service driver being loaded, calls
such as pci_enable_device(dev) and pci_set_master(dev) are no longer
necessary since these calls are executed by the PCI Port Bus driver.
5.2.2 pcie_port_service_unregister
void pcie_port_service_unregister(struct pcie_port_service_driver *new)
pcie_port_service_unregister replaces the Linux Driver Model's
pci_unregister_driver. It's always called by service driver when a
module exits.
5.2.3 Sample Code
Below is sample service driver code to initialize the port service
driver data structure.
static struct pcie_port_service_id service_id[] = { {
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
.port_type = PCIE_RC_PORT,
.service_type = PCIE_PORT_SERVICE_AER,
}, { /* end: all zeroes */ }
};
static struct pcie_port_service_driver root_aerdrv = {
.name = (char *)device_name,
.id_table = &service_id[0],
.probe = aerdrv_load,
.remove = aerdrv_unload,
.suspend = aerdrv_suspend,
.resume = aerdrv_resume,
};
Below is a sample code for registering/unregistering a service
driver.
static int __init aerdrv_service_init(void)
{
int retval = 0;
retval = pcie_port_service_register(&root_aerdrv);
if (!retval) {
/*
* FIX ME
*/
}
return retval;
}
static void __exit aerdrv_service_exit(void)
{
pcie_port_service_unregister(&root_aerdrv);
}
module_init(aerdrv_service_init);
module_exit(aerdrv_service_exit);
6. Possible Resource Conflicts
Since all service drivers of a PCI-PCI Bridge Port device are
allowed to run simultaneously, below lists a few of possible resource
conflicts with proposed solutions.
6.1 MSI Vector Resource
The MSI capability structure enables a device software driver to call
pci_enable_msi to request MSI based interrupts. Once MSI interrupts
are enabled on a device, it stays in this mode until a device driver
calls pci_disable_msi to disable MSI interrupts and revert back to
INTx emulation mode. Since service drivers of the same PCI-PCI Bridge
port share the same physical device, if an individual service driver
calls pci_enable_msi/pci_disable_msi it may result unpredictable
behavior. For example, two service drivers run simultaneously on the
same physical Root Port. Both service drivers call pci_enable_msi to
request MSI based interrupts. A service driver may not know whether
any other service drivers have run on this Root Port. If either one
of them calls pci_disable_msi, it puts the other service driver
in a wrong interrupt mode.
To avoid this situation all service drivers are not permitted to
switch interrupt mode on its device. The PCI Express Port Bus driver
is responsible for determining the interrupt mode and this should be
transparent to service drivers. Service drivers need to know only
the vector IRQ assigned to the field irq of struct pcie_device, which
is passed in when the PCI Express Port Bus driver probes each service
driver. Service drivers should use (struct pcie_device*)dev->irq to
call request_irq/free_irq. In addition, the interrupt mode is stored
in the field interrupt_mode of struct pcie_device.
6.2 MSI-X Vector Resources
Similar to the MSI a device driver for an MSI-X capable device can
call pci_enable_msix to request MSI-X interrupts. All service drivers
are not permitted to switch interrupt mode on its device. The PCI
Express Port Bus driver is responsible for determining the interrupt
mode and this should be transparent to service drivers. Any attempt
by service driver to call pci_enable_msix/pci_disable_msix may
result unpredictable behavior. Service drivers should use
(struct pcie_device*)dev->irq and call request_irq/free_irq.
6.3 PCI Memory/IO Mapped Regions
Service drivers for PCI Express Power Management (PME), Advanced
Error Reporting (AER), Hot-Plug (HP) and Virtual Channel (VC) access
PCI configuration space on the PCI Express port. In all cases the
registers accessed are independent of each other. This patch assumes
that all service drivers will be well behaved and not overwrite
other service driver's configuration settings.
6.4 PCI Config Registers
Each service driver runs its PCI config operations on its own
capability structure except the PCI Express capability structure, in
which Root Control register and Device Control register are shared
between PME and AER. This patch assumes that all service drivers
will be well behaved and not overwrite other service driver's
configuration settings.
......@@ -33,6 +33,10 @@ USING DEVICE NODES
"echo > /dev/etherd/discover" tells the driver to find out what AoE
devices are available.
These character devices may disappear and be replaced by sysfs
counterparts, so distribution maintainers are encouraged to create
scripts that use these devices.
The block devices are named like this:
e{shelf}.{slot}
......@@ -57,19 +61,24 @@ USING SYSFS
There is a script in this directory that formats this information
in a convenient way.
root@makki linux# sh Documentation/aoe/status.sh
device mac netif state
e6.0 0010040010c6 eth0 up
e6.1 001004001067 eth0 up
e6.2 001004001068 eth0 up
e6.3 001004001065 eth0 up
e6.4 001004001066 eth0 up
e6.5 0010040010c7 eth0 up
e6.6 0010040010c8 eth0 up
e6.7 0010040010c9 eth0 up
e6.8 0010040010ca eth0 up
e6.9 0010040010cb eth0 up
e9.0 001004000020 eth1 up
e9.5 001004000025 eth1 up
e9.9 001004000029 eth1 up
root@makki root# sh Documentation/aoe/status.sh
e10.0 eth3 up
e10.1 eth3 up
e10.2 eth3 up
e10.3 eth3 up
e10.4 eth3 up
e10.5 eth3 up
e10.6 eth3 up
e10.7 eth3 up
e10.8 eth3 up
e10.9 eth3 up
e4.0 eth1 up
e4.1 eth1 up
e4.2 eth1 up
e4.3 eth1 up
e4.4 eth1 up
e4.5 eth1 up
e4.6 eth1 up
e4.7 eth1 up
e4.8 eth1 up
e4.9 eth1 up
#!/bin/sh
n_shelves=10
n_shelves=${n_shelves:-10}
n_partitions=${n_partitions:-16}
if test "$#" != "1"; then
echo "Usage: sh mkdevs.sh {dir}" 1>&2
echo "Usage: sh `basename $0` {dir}" 1>&2
exit 1
fi
dir=$1
......@@ -26,8 +27,10 @@ mknod -m 0200 $dir/discover c $MAJOR 3
rm -f $dir/interfaces
mknod -m 0200 $dir/interfaces c $MAJOR 4
export n_partitions
mkshelf=`echo $0 | sed 's!mkdevs!mkshelf!'`
i=0
while test $i -lt $n_shelves; do
sh -xc "sh `dirname $0`/mkshelf.sh $dir $i"
sh -xc "sh $mkshelf $dir $i"
i=`expr $i + 1`
done
#! /bin/sh
if test "$#" != "2"; then
echo "Usage: sh mkshelf.sh {dir} {shelfaddress}" 1>&2
echo "Usage: sh `basename $0` {dir} {shelfaddress}" 1>&2
exit 1
fi
n_partitions=${n_partitions:-16}
dir=$1
shelf=$2
MAJOR=152
set -e
minor=`echo 10 \* $shelf \* 16 | bc`
minor=`echo 10 \* $shelf \* $n_partitions | bc`
endp=`echo $n_partitions - 1 | bc`
for slot in `seq 0 9`; do
for part in `seq 0 15`; do
for part in `seq 0 $endp`; do
name=e$shelf.$slot
test "$part" != "0" && name=${name}p$part
rm -f $dir/$name
......
#! /bin/sh
# collate and present sysfs information about AoE storage
set -e
format="%8s\t%12s\t%8s\t%8s\n"
format="%8s\t%8s\t%8s\n"
me=`basename $0`
printf "$format" device mac netif state
# printf "$format" device mac netif state
test -z "`mount | grep sysfs`" && {
echo "$me Error: sysfs is not mounted" 1>&2
exit 1
}
test -z "`lsmod | grep '^aoe'`" && {
echo "$me Error: aoe module is not loaded" 1>&2
exit 1
}
for d in `ls -d /sys/block/etherd* 2>/dev/null | grep -v p` end; do
# maybe ls comes up empty, so we use "end"
test $d = end && continue
for d in `ls -d /sys/block/etherd* | grep -v p`; do
dev=`echo "$d" | sed 's/.*!//'`
printf "$format" \
"$dev" \
"`cat \"$d/mac\"`" \
"`cat \"$d/netif\"`" \
"`cat \"$d/state\"`"
done | sort
......@@ -2563,6 +2563,7 @@ Your cooperation is appreciated.
128 = /dev/usb/brlvgr0 First Braille Voyager device
...
131 = /dev/usb/brlvgr3 Fourth Braille Voyager device
132 = /dev/usb/idmouse ID Mouse (fingerprint scanner) device
144 = /dev/usb/lcd USB LCD device
160 = /dev/usb/legousbtower0 1st USB Legotower device
...
......
......@@ -83,7 +83,18 @@ one or more packets could finish before an error stops further endpoint I/O.
prescribed bus turn-around time
c) unknown USB error
-EILSEQ (*, **) CRC mismatch
-EILSEQ (*, **) a) CRC mismatch
b) no response packet received within the
prescribed bus turn-around time
c) unknown USB error
In cases b) and c) either -EPROTO or -EILSEQ
may be returned. Note that often the controller
hardware does not distinguish among cases a),
b), and c), so a driver cannot tell whether
there was a protocol error, a failure to respond
(often caused by device disconnect), or some
other fault.
-EPIPE (**) Endpoint stalled. For non-control endpoints,
reset this status with usb_clear_halt().
......@@ -104,8 +115,6 @@ one or more packets could finish before an error stops further endpoint I/O.
specified buffer, and URB_SHORT_NOT_OK was set in
urb->transfer_flags.
-ETIMEDOUT (**) transfer timed out, NAK
-ENODEV Device was removed. Often preceded by a burst of
other errors, since the hub driver does't detect
device removal events immediately.
......@@ -143,4 +152,4 @@ usb_register():
usb_get_*/usb_set_*():
usb_control_msg():
usb_bulk_msg():
All USB errors (submit/status) can occur
-ETIMEDOUT timeout expired before the transfer completed
......@@ -26,7 +26,7 @@ Index
1. Copyright
============
Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>
Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>
2. Disclaimer
......@@ -165,6 +165,17 @@ Description: Specify V4L2 minor mode number:
other camera.
Default: -1
-------------------------------------------------------------------------------
Name: force_munmap;
Type: bool array (min = 0, max = 64)
Syntax: <0|1[,...]>
Description: Force the application to unmap previously mapped buffer memory
before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not
all the applications support this feature. This parameter is
specific for each detected camera.
0 = do not force memory unmapping"
1 = force memory unmapping (save memory)"
Default: 0
-------------------------------------------------------------------------------
Name: debug
Type: int
Syntax: <n>
......@@ -362,11 +373,11 @@ rules:
file descriptor. Once it is selected, the application must close and reopen the
device to switch to the other I/O method;
- previously mapped buffer memory must always be unmapped before calling any
of the "VIDIOC_S_CROP", "VIDIOC_TRY_FMT" and "VIDIOC_S_FMT" ioctl's. The same
number of buffers as before will be allocated again to match the size of the
new video frames, so you have to map the buffers again before any I/O attempts
on them.
- although it is not mandatory, previously mapped buffer memory should always
be unmapped before calling any "VIDIOC_S_CROP" or "VIDIOC_S_FMT" ioctl's.
The same number of buffers as before will be allocated again to match the size
of the new video frames, so you have to map the buffers again before any I/O
attempts on them.
Consistently with the hardware limits, this driver also supports image
downscaling with arbitrary scaling factors from 1, 2 and 4 in both directions.
......
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.10-rc2
# Mon Nov 15 15:29:42 2004
# Linux kernel version: 2.6.11-rc1-bk5
# Tue Jan 18 11:36:49 2005
#
CONFIG_ARM=y
CONFIG_MMU=y
CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_IOMAP=y
#
......@@ -123,11 +124,19 @@ CONFIG_CPU_TLB_V4WBI=y
#
# General setup
#
# CONFIG_ZBOOT_ROM is not set
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
# CONFIG_XIP_KERNEL is not set
#
# PCCARD (PCMCIA/CardBus) support
#
# CONFIG_PCCARD is not set
#
# PC-card bridges
#
#
# At least one math emulation must be selected
#
......@@ -143,6 +152,7 @@ CONFIG_BINFMT_AOUT=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
CONFIG_PM=y
# CONFIG_PREEMPT is not set
......@@ -168,6 +178,7 @@ CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
CONFIG_MTD_CMDLINE_PARTS=y
......@@ -200,13 +211,15 @@ CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
CONFIG_MTD_CFI_INTELEXT=y
# CONFIG_MTD_CFI_AMDSTD is not set
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_CFI_AMDSTD_RETRY=0
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
CONFIG_MTD_ROM=y
# CONFIG_MTD_ABSENT is not set
# CONFIG_MTD_OBSOLETE_CHIPS is not set
# CONFIG_MTD_XIP is not set
#
# Mapping drivers for chip access
......@@ -226,6 +239,7 @@ CONFIG_MTD_BAST_MAXSIZE=4
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLKMTD is not set
# CONFIG_MTD_BLOCK2MTD is not set
#
# Disk-On-Chip Device Drivers
......@@ -244,6 +258,7 @@ CONFIG_MTD_NAND_S3C2410=y
# CONFIG_MTD_NAND_S3C2410_DEBUG is not set
# CONFIG_MTD_NAND_S3C2410_HWECC is not set
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_NANDSIM is not set
#
# Plug and Play support
......@@ -254,10 +269,12 @@ CONFIG_MTD_NAND_S3C2410=y
#
# CONFIG_BLK_DEV_FD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
......@@ -270,6 +287,7 @@ CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
CONFIG_ATA_OVER_ETH=m
#
# Multi-device support (RAID and LVM)
......@@ -456,6 +474,7 @@ CONFIG_SERIO=y
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PARKBD is not set
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
#
......@@ -489,6 +508,7 @@ CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_DIGI is not set
# CONFIG_MOXA_INTELLIO is not set
# CONFIG_MOXA_SMARTIO is not set
# CONFIG_ISI is not set
# CONFIG_SYNCLINKMP is not set
# CONFIG_N_HDLC is not set
# CONFIG_RISCOM8 is not set
......@@ -583,6 +603,7 @@ CONFIG_I2C_S3C2410=y
CONFIG_I2C_SENSOR=m
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ASB100 is not set
# CONFIG_SENSORS_DS1621 is not set
......@@ -600,6 +621,7 @@ CONFIG_SENSORS_LM85=m
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83L785TS is not set
......@@ -693,6 +715,7 @@ CONFIG_JFFS_FS_VERBOSE=0
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
# CONFIG_JFFS2_FS_NAND is not set
# CONFIG_JFFS2_FS_NOR_ECC is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
......@@ -812,6 +835,7 @@ CONFIG_DUMMY_CONSOLE=y
# Logo configuration
#
# CONFIG_LOGO is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
......@@ -829,6 +853,10 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
#
#
# USB Gadget Support
#
......@@ -848,8 +876,9 @@ CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_FS is not set
CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_WAITQ is not set
......@@ -870,6 +899,10 @@ CONFIG_DEBUG_S3C2410_UART=0
#
# CONFIG_CRYPTO is not set
#
# Hardware crypto devices
#
#
# Library routines
#
......
......@@ -171,22 +171,9 @@ static unsigned next_jiffy_time;
unsigned long ixp2000_gettimeoffset (void)
{
unsigned long elapsed1, elapsed2, pending;
unsigned long offset;
elapsed1 = *IXP2000_T1_CSR;
pending = (*IXP2000_IRQ_STATUS & IRQ_MASK_TIMER1);
elapsed2 = *IXP2000_T1_CSR;
offset = ticks_per_jiffy - elapsed2;
/*
* We have two cases to cover, one where we were pending
* already, and another where it overflowed while we were
* checking the timers.
*/
if ((elapsed2 > elapsed1) || pending)
offset += ticks_per_jiffy;
offset = next_jiffy_time - *IXP2000_T4_CSR;
return offset / ticks_per_usec;
}
......
......@@ -18,6 +18,7 @@
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/mmc/host.h>
#include <asm/setup.h>
#include <asm/memory.h>
......@@ -32,19 +33,18 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/irq.h>
#include <asm/arch/mmc.h>
#include <asm/arch/corgi.h>
#include <asm/hardware/scoop.h>
#include <video/w100fb.h>
#include "generic.h"
extern void corgi_ssp_lcdtg_send (u8 adrs, u8 data);
static void __init corgi_init_irq(void)
{
pxa_init_irq();
}
/*
* Corgi SCOOP Device
*/
static struct resource corgi_scoop_resources[] = {
[0] = {
.start = 0x10800000,
......@@ -68,19 +68,139 @@ static struct platform_device corgiscoop_device = {
.resource = corgi_scoop_resources,
};
/*
* Corgi SSP Device
*
* Set the parent as the scoop device because a lot of SSP devices
* also use scoop functions and this makes the power up/down order
* work correctly.
*/
extern void corgi_ssp_lcdtg_send (u8 adrs, u8 data);
static struct platform_device corgissp_device = {
.name = "corgi-ssp",
.dev = {
.parent = &corgiscoop_device.dev,
},
.id = -1,
};
/*
* Corgi w100 Frame Buffer Device
*/
static struct w100fb_mach_info corgi_fb_info = {
.w100fb_ssp_send = corgi_ssp_lcdtg_send,
.comadj = -1,
.phadadj = -1,
};
static struct resource corgi_fb_resources[] = {
[0] = {
.start = 0x08000000,
.end = 0x08ffffff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device corgifb_device = {
.name = "w100fb",
.id = -1,
.dev = {
.platform_data = &corgi_fb_info,
.parent = &corgissp_device.dev,
},
.num_resources = ARRAY_SIZE(corgi_fb_resources),
.resource = corgi_fb_resources,
};
/*
* MMC/SD Device
*
* The card detect interrupt isn't debounced so we delay it by HZ/4
* to give the card a chance to fully insert/eject.
*/
static struct mmc_detect {
struct timer_list detect_timer;
void *devid;
} mmc_detect;
static void mmc_detect_callback(unsigned long data)
{
mmc_detect_change(mmc_detect.devid);
}
static irqreturn_t corgi_mmc_detect_int(int irq, void *devid, struct pt_regs *regs)
{
mmc_detect.devid=devid;
mod_timer(&mmc_detect.detect_timer, jiffies + HZ/4);
return IRQ_HANDLED;
}
static int corgi_mci_init(struct device *dev, irqreturn_t (*unused_detect_int)(int, void *, struct pt_regs *), void *data)
{
int err;
/* setup GPIO for PXA25x MMC controller */
pxa_gpio_mode(GPIO6_MMCCLK_MD);
pxa_gpio_mode(GPIO8_MMCCS0_MD);
pxa_gpio_mode(CORGI_GPIO_nSD_DETECT | GPIO_IN);
pxa_gpio_mode(CORGI_GPIO_SD_PWR | GPIO_OUT);
err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_mmc_detect_int, SA_INTERRUPT,
"MMC card detect", data);
if (err) {
printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
return -1;
}
init_timer(&mmc_detect.detect_timer);
mmc_detect.detect_timer.function = mmc_detect_callback;
mmc_detect.detect_timer.data = (unsigned long) &mmc_detect;
set_irq_type(CORGI_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
return 0;
}
static void corgi_mci_setpower(struct device *dev, unsigned int vdd)
{
struct pxamci_platform_data* p_d = dev->platform_data;
if (( 1 << vdd) & p_d->ocr_mask) {
printk(KERN_DEBUG "%s: on\n", __FUNCTION__);
GPSR1 = GPIO_bit(CORGI_GPIO_SD_PWR);
} else {
printk(KERN_DEBUG "%s: off\n", __FUNCTION__);
GPCR1 = GPIO_bit(CORGI_GPIO_SD_PWR);
}
}
static void corgi_mci_exit(struct device *dev, void *data)
{
free_irq(CORGI_IRQ_GPIO_nSD_DETECT, data);
del_timer(&mmc_detect.detect_timer);
}
static struct pxamci_platform_data corgi_mci_platform_data = {
.ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
.init = corgi_mci_init,
.setpower = corgi_mci_setpower,
.exit = corgi_mci_exit,
};
static struct platform_device *devices[] __initdata = {
&corgiscoop_device,
&corgissp_device,
&corgifb_device,
};
static struct sharpsl_flash_param_info sharpsl_flash_param;
void corgi_get_param(void)
static void corgi_get_param(void)
{
sharpsl_flash_param.comadj_keyword = readl(FLASH_MEM_BASE + FLASH_COMADJ_MAGIC_ADR);
sharpsl_flash_param.comadj = readl(FLASH_MEM_BASE + FLASH_COMADJ_DATA_ADR);
......@@ -91,6 +211,18 @@ void corgi_get_param(void)
static void __init corgi_init(void)
{
if (sharpsl_flash_param.comadj_keyword == FLASH_COMADJ_MAJIC)
corgi_fb_info.comadj=sharpsl_flash_param.comadj;
else
corgi_fb_info.comadj=-1;
if (sharpsl_flash_param.phad_keyword == FLASH_PHAD_MAJIC)
corgi_fb_info.phadadj=sharpsl_flash_param.phadadj;
else
corgi_fb_info.phadadj=-1;
pxa_set_mci_info(&corgi_mci_platform_data);
platform_add_devices(devices, ARRAY_SIZE(devices));
}
......@@ -107,6 +239,11 @@ static void __init fixup_corgi(struct machine_desc *desc,
mi->bank[0].size = (64*1024*1024);
}
static void __init corgi_init_irq(void)
{
pxa_init_irq();
}
static struct map_desc corgi_io_desc[] __initdata = {
/* virtual physical length */
/* { 0xf1000000, 0x08000000, 0x01000000, MT_DEVICE },*/ /* LCDC (readable for Qt driver) */
......
......@@ -1063,6 +1063,29 @@ int s3c2410_dma_devconfig(int channel,
EXPORT_SYMBOL(s3c2410_dma_devconfig);
/* s3c2410_dma_getposition
*
* returns the current transfer points for the dma source and destination
*/
int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
{
s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
check_channel(channel);
if (src != NULL)
*src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
if (dst != NULL)
*dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
return 0;
}
EXPORT_SYMBOL(s3c2410_dma_getposition);
/* system device class */
#ifdef CONFIG_PM
......
......@@ -20,8 +20,9 @@
* 18-Jan-2003 BJD Added serial port configuration
* 05-Oct-2004 BJD Power management code
* 04-Nov-2004 BJD Updated serial port clocks
* 04-Jan-2006 BJD New uart init call
* 04-Jan-2005 BJD New uart init call
* 10-Jan-2005 BJD Removed include of s3c2410.h
* 14-Jan-2005 BJD Add support for muitlple NAND devices
*/
#include <linux/kernel.h>
......@@ -48,6 +49,12 @@
#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-mem.h>
#include <asm/arch/nand.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
#include "clock.h"
#include "devs.h"
......@@ -55,7 +62,7 @@
#include "usb-simtec.h"
#include "pm.h"
#define COPYRIGHT ", (c) 2004 Simtec Electronics"
#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
/* macros for virtual address mods for the io space entries */
#define VA_C5(item) ((item) + BAST_VAM_CS5)
......@@ -220,6 +227,100 @@ static struct platform_device bast_device_nor = {
.resource = bast_nor_resource,
};
/* NAND Flash on BAST board */
static int smartmedia_map[] = { 0 };
static int chip0_map[] = { 1 };
static int chip1_map[] = { 2 };
static int chip2_map[] = { 3 };
struct mtd_partition bast_default_nand_part[] = {
[0] = {
.name = "Boot Agent",
.size = SZ_16K,
.offset = 0
},
[1] = {
.name = "/boot",
.size = SZ_4M - SZ_16K,
.offset = SZ_16K,
},
[2] = {
.name = "user",
.offset = SZ_4M,
.size = MTDPART_SIZ_FULL,
}
};
/* the bast has 4 selectable slots for nand-flash, the three
* on-board chip areas, as well as the external SmartMedia
* slot.
*
* Note, there is no current hot-plug support for the SmartMedia
* socket.
*/
static struct s3c2410_nand_set bast_nand_sets[] = {
[0] = {
.name = "SmartMedia",
.nr_chips = 1,
.nr_map = smartmedia_map,
.nr_partitions = ARRAY_SIZE(bast_default_nand_part),
.partitions = bast_default_nand_part
},
[1] = {
.name = "chip0",
.nr_chips = 1,
.nr_map = chip0_map,
.nr_partitions = ARRAY_SIZE(bast_default_nand_part),
.partitions = bast_default_nand_part
},
[2] = {
.name = "chip1",
.nr_chips = 1,
.nr_map = chip1_map,
.nr_partitions = ARRAY_SIZE(bast_default_nand_part),
.partitions = bast_default_nand_part
},
[3] = {
.name = "chip2",
.nr_chips = 1,
.nr_map = chip2_map,
.nr_partitions = ARRAY_SIZE(bast_default_nand_part),
.partitions = bast_default_nand_part
}
};
static void bast_nand_select(struct s3c2410_nand_set *set, int slot)
{
unsigned int tmp;
slot = set->nr_map[slot] & 3;
pr_debug("bast_nand: selecting slot %d (set %p,%p)\n",
slot, set, set->nr_map);
tmp = __raw_readb(BAST_VA_CTRL2);
tmp &= BAST_CPLD_CTLR2_IDERST;
tmp |= slot;
tmp |= BAST_CPLD_CTRL2_WNAND;
pr_debug("bast_nand: ctrl2 now %02x\n", tmp);
__raw_writeb(tmp, BAST_VA_CTRL2);
}
static struct s3c2410_platform_nand bast_nand_info = {
.tacls = 80,
.twrph0 = 80,
.twrph1 = 80,
.nr_sets = ARRAY_SIZE(bast_nand_sets),
.sets = bast_nand_sets,
.select_chip = bast_nand_select,
};
/* Standard BAST devices */
static struct platform_device *bast_devices[] __initdata = {
......@@ -229,6 +330,7 @@ static struct platform_device *bast_devices[] __initdata = {
&s3c_device_i2c,
&s3c_device_iis,
&s3c_device_rtc,
&s3c_device_nand,
&bast_device_nor
};
......@@ -262,6 +364,8 @@ void __init bast_map_io(void)
s3c24xx_uclk.parent = &s3c24xx_clkout1;
s3c_device_nand.dev.platform_data = &bast_nand_info;
s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
......
/* linux/arch/arm/mach-s3c2410/mach-vr1000.c
*
* Copyright (c) 2003,2004 Simtec Electronics
* Copyright (c) 2003-2005 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Machine support for Thorcom VR1000 board. Designed for Thorcom by
......@@ -18,9 +18,11 @@
* 05-Apr-2004 BJD Copied to make mach-vr1000.c
* 18-Oct-2004 BJD Updated board struct
* 04-Nov-2004 BJD Clock and serial configuration update
*
* 04-Jan-2005 BJD Updated uart init call
* 10-Jan-2005 BJD Removed include of s3c2410.h
* 14-Jan-2005 BJD Added clock init
* 15-Jan-2005 BJD Add serial port device definition
*/
#include <linux/kernel.h>
......@@ -30,12 +32,19 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/arch/bast-map.h>
#include <asm/arch/vr1000-map.h>
#include <asm/arch/vr1000-irq.h>
#include <asm/arch/vr1000-cpld.h>
#include <asm/hardware.h>
#include <asm/io.h>
......@@ -69,6 +78,10 @@ static struct map_desc vr1000_iodesc[] __initdata = {
{ S3C2410_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ S3C2410_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
/* serial ports */
{ VR1000_VA_SERIAL, VR1000_PA_SERIAL, SZ_1M, MT_DEVICE },
/* we could possibly compress the next set down into a set of smaller tables
* pagetables, but that would mean using an L2 section, and it still means
* we cannot actually feed the same register to an LDR due to 16K spacing
......@@ -166,12 +179,87 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] = {
}
};
/* definitions for the vr1000 extra 16550 serial ports */
#define VR1000_BAUDBASE (3692307)
#define VR1000_SERIAL_MEMBASE(x) ((void __iomem *)VR1000_VA_SERIAL + 0x80 + ((x) << 5))
#define VR1000_SERIAL_MAPBASE(x) (VR1000_PA_SERIAL + 0x80 + ((x) << 5))
static struct plat_serial8250_port serial_platform_data[] = {
[0] = {
.membase = VR1000_SERIAL_MEMBASE(0),
.mapbase = VR1000_SERIAL_MAPBASE(0),
.irq = IRQ_VR1000_SERIAL + 0,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 0,
.uartclk = VR1000_BAUDBASE,
},
[1] = {
.membase = VR1000_SERIAL_MEMBASE(1),
.mapbase = VR1000_SERIAL_MAPBASE(1),
.irq = IRQ_VR1000_SERIAL + 1,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 0,
.uartclk = VR1000_BAUDBASE,
},
[2] = {
.membase = VR1000_SERIAL_MEMBASE(2),
.mapbase = VR1000_SERIAL_MAPBASE(2),
.irq = IRQ_VR1000_SERIAL + 2,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 0,
.uartclk = VR1000_BAUDBASE,
},
[3] = {
.membase = VR1000_SERIAL_MEMBASE(3),
.mapbase = VR1000_SERIAL_MAPBASE(3),
.irq = IRQ_VR1000_SERIAL + 3,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 0,
.uartclk = VR1000_BAUDBASE,
},
{ },
};
static struct platform_device serial_device = {
.name = "serial8250",
.id = 0,
.dev = {
.platform_data = serial_platform_data,
},
};
/* MTD NOR Flash */
static struct resource vr1000_nor_resource[] = {
[0] = {
.start = S3C2410_CS1 + 0x4000000,
.end = S3C2410_CS1 + 0x4000000 + SZ_16M - 1,
.flags = IORESOURCE_MEM,
}
};
static struct platform_device vr1000_nor = {
.name = "bast-nor",
.id = -1,
.num_resources = ARRAY_SIZE(vr1000_nor_resource),
.resource = vr1000_nor_resource,
};
static struct platform_device *vr1000_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
&serial_device,
&vr1000_nor,
};
static struct clk *vr1000_clocks[] = {
......
......@@ -1131,6 +1131,8 @@ config PCI_MMCONFIG
select ACPI_BOOT
default y
source "drivers/pci/pcie/Kconfig"
source "drivers/pci/Kconfig"
config ISA
......
......@@ -111,16 +111,17 @@ static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
{
struct _fpxreg *st = NULL;
unsigned long tos = (fxsave->swd >> 11) & 7;
unsigned long twd = (unsigned long) fxsave->twd;
unsigned long tag;
unsigned long ret = 0xffff0000u;
int i;
#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
#define FPREG_ADDR(f, n) ((void *)&(f)->st_space + (n) * 16);
for ( i = 0 ; i < 8 ; i++ ) {
if ( twd & 0x1 ) {
st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
st = FPREG_ADDR( fxsave, (i - tos) & 7 );
switch ( st->exponent & 0x7fff ) {
case 0x7fff:
......
......@@ -385,8 +385,8 @@ void __devinit pcibios_sort(void)
}
}
if (!found) {
printk(KERN_WARNING "PCI: Device %02x:%02x not found by BIOS\n",
dev->bus->number, dev->devfn);
printk(KERN_WARNING "PCI: Device %s not found by BIOS\n",
pci_name(dev));
list_del(&dev->global_list);
list_add_tail(&dev->global_list, &sorted_devices);
}
......
......@@ -28,16 +28,17 @@ static inline unsigned short twd_i387_to_fxsr(unsigned short twd)
static inline unsigned long twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
{
struct _fpxreg *st = NULL;
unsigned long tos = (fxsave->swd >> 11) & 7;
unsigned long twd = (unsigned long) fxsave->twd;
unsigned long tag;
unsigned long ret = 0xffff0000;
int i;
#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
#define FPREG_ADDR(f, n) ((void *)&(f)->st_space + (n) * 16);
for (i = 0 ; i < 8 ; i++) {
if (twd & 0x1) {
st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
st = FPREG_ADDR( fxsave, (i - tos) & 7 );
switch (st->exponent & 0x7fff) {
case 0x7fff:
......
/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
#define VERSION "4"
#define VERSION "5"
#define AOE_MAJOR 152
#define DEVICE_NAME "aoe"
#ifndef AOE_PARTITIONS
#define AOE_PARTITIONS 16
#endif
#define SYSMINOR(aoemajor, aoeminor) ((aoemajor) * 10 + (aoeminor))
#define AOEMAJOR(sysminor) ((sysminor) / 10)
#define AOEMINOR(sysminor) ((sysminor) % 10)
......@@ -101,7 +104,7 @@ struct frame {
int ndata;
/* largest possible */
char data[sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr)];
unsigned char data[sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr)];
};
struct aoedev {
......@@ -111,6 +114,7 @@ struct aoedev {
ulong sysminor;
ulong aoemajor;
ulong aoeminor;
ulong nopen; /* (bd_openers isn't available without sleeping) */
ulong rttavg; /* round trip average of requests/responses */
u16 fw_ver; /* version of blade's firmware */
struct work_struct work;/* disk create work struct */
......
......@@ -12,14 +12,9 @@
#include <linux/netdevice.h>
#include "aoe.h"
/* add attributes for our block devices in sysfs
* (see drivers/block/genhd.c:disk_attr_show, etc.)
*/
struct disk_attribute {
struct attribute attr;
ssize_t (*show)(struct gendisk *, char *);
};
static kmem_cache_t *buf_pool_cache;
/* add attributes for our block devices in sysfs */
static ssize_t aoedisk_show_state(struct gendisk * disk, char *page)
{
struct aoedev *d = disk->private_data;
......@@ -74,9 +69,18 @@ static int
aoeblk_open(struct inode *inode, struct file *filp)
{
struct aoedev *d;
ulong flags;
d = inode->i_bdev->bd_disk->private_data;
return (d->flags & DEVFL_UP) ? 0 : -ENODEV;
spin_lock_irqsave(&d->lock, flags);
if (d->flags & DEVFL_UP) {
d->nopen++;
spin_unlock_irqrestore(&d->lock, flags);
return 0;
}
spin_unlock_irqrestore(&d->lock, flags);
return -ENODEV;
}
static int
......@@ -89,7 +93,7 @@ aoeblk_release(struct inode *inode, struct file *filp)
spin_lock_irqsave(&d->lock, flags);
if (inode->i_bdev->bd_openers == 0 && (d->flags & DEVFL_CLOSEWAIT)) {
if (--d->nopen == 0 && (d->flags & DEVFL_CLOSEWAIT)) {
d->flags &= ~DEVFL_CLOSEWAIT;
spin_unlock_irqrestore(&d->lock, flags);
aoecmd_cfg(d->aoemajor, d->aoeminor);
......@@ -192,23 +196,34 @@ aoeblk_gdalloc(void *vp)
struct aoedev *d = vp;
struct gendisk *gd;
ulong flags;
enum { NPARTITIONS = 16 };
gd = alloc_disk(NPARTITIONS);
spin_lock_irqsave(&d->lock, flags);
gd = alloc_disk(AOE_PARTITIONS);
if (gd == NULL) {
printk(KERN_CRIT "aoe: aoeblk_gdalloc: cannot allocate disk "
printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate disk "
"structure for %ld.%ld\n", d->aoemajor, d->aoeminor);
spin_lock_irqsave(&d->lock, flags);
d->flags &= ~DEVFL_WORKON;
spin_unlock_irqrestore(&d->lock, flags);
return;
}
d->bufpool = mempool_create(MIN_BUFS,
mempool_alloc_slab, mempool_free_slab,
buf_pool_cache);
if (d->bufpool == NULL) {
printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate bufpool "
"for %ld.%ld\n", d->aoemajor, d->aoeminor);
put_disk(gd);
spin_lock_irqsave(&d->lock, flags);
d->flags &= ~DEVFL_WORKON;
spin_unlock_irqrestore(&d->lock, flags);
return;
}
spin_lock_irqsave(&d->lock, flags);
blk_queue_make_request(&d->blkq, aoeblk_make_request);
gd->major = AOE_MAJOR;
gd->first_minor = d->sysminor * NPARTITIONS;
gd->first_minor = d->sysminor * AOE_PARTITIONS;
gd->fops = &aoe_bdops;
gd->private_data = d;
gd->capacity = d->ssize;
......@@ -233,7 +248,7 @@ aoeblk_gdalloc(void *vp)
void __exit
aoeblk_exit(void)
{
unregister_blkdev(AOE_MAJOR, DEVICE_NAME);
kmem_cache_destroy(buf_pool_cache);
}
int __init
......@@ -241,6 +256,12 @@ aoeblk_init(void)
{
int n;
buf_pool_cache = kmem_cache_create("aoe_bufs",
sizeof(struct buf),
0, 0, NULL, NULL);
if (buf_pool_cache == NULL)
return -ENOMEM;
n = register_blkdev(AOE_MAJOR, DEVICE_NAME);
if (n < 0) {
printk(KERN_ERR "aoe: aoeblk_init: can't register major\n");
......
......@@ -266,7 +266,7 @@ aoechr_init(void)
return 0;
}
void __exit
void
aoechr_exit(void)
{
int i;
......
......@@ -11,7 +11,6 @@
static struct aoedev *devlist;
static spinlock_t devlist_lock;
static kmem_cache_t *buf_pool_cache;
struct aoedev *
aoedev_bymac(unsigned char *macaddr)
......@@ -53,9 +52,7 @@ aoedev_newdev(ulong nframes)
spin_lock_init(&d->lock);
init_timer(&d->timer);
d->bufpool = mempool_create(MIN_BUFS,
mempool_alloc_slab, mempool_free_slab,
buf_pool_cache);
d->bufpool = NULL; /* defer to aoeblk_gdalloc */
INIT_LIST_HEAD(&d->bufq);
d->next = devlist;
devlist = d;
......@@ -95,15 +92,10 @@ aoedev_downdev(struct aoedev *d)
bio_endio(bio, bio->bi_size, -EIO);
}
if (d->gd) {
struct block_device *bdev = bdget_disk(d->gd, 0);
if (bdev) {
if (bdev->bd_openers)
d->flags |= DEVFL_CLOSEWAIT;
bdput(bdev);
}
if (d->nopen)
d->flags |= DEVFL_CLOSEWAIT;
if (d->gd)
d->gd->capacity = 0;
}
d->flags &= ~DEVFL_UP;
}
......@@ -159,7 +151,7 @@ aoedev_freedev(struct aoedev *d)
kfree(d);
}
void __exit
void
aoedev_exit(void)
{
struct aoedev *d;
......@@ -177,17 +169,11 @@ aoedev_exit(void)
del_timer_sync(&d->timer);
aoedev_freedev(d);
}
kmem_cache_destroy(buf_pool_cache);
}
int __init
aoedev_init(void)
{
buf_pool_cache = kmem_cache_create("aoe_bufs",
sizeof(struct buf),
0, 0, NULL, NULL);
if (buf_pool_cache == NULL)
return -ENOMEM;
spin_lock_init(&devlist_lock);
return 0;
}
......
......@@ -53,39 +53,58 @@ discover_timer(ulong vp)
}
}
static void __exit
static void
aoe_exit(void)
{
discover_timer(TKILL);
aoenet_exit();
aoeblk_exit();
unregister_blkdev(AOE_MAJOR, DEVICE_NAME);
aoechr_exit();
aoedev_exit();
aoeblk_exit(); /* free cache after de-allocating bufs */
}
static int __init
aoe_init(void)
{
int n, (**p)(void);
int (*fns[])(void) = {
aoedev_init, aoechr_init, aoeblk_init, aoenet_init, NULL
};
int ret;
for (p=fns; *p != NULL; p++) {
n = (*p)();
if (n) {
aoe_exit();
printk(KERN_INFO "aoe: aoe_init: initialisation failure.\n");
return n;
}
ret = aoedev_init();
if (ret)
return ret;
ret = aoechr_init();
if (ret)
goto chr_fail;
ret = aoeblk_init();
if (ret)
goto blk_fail;
ret = aoenet_init();
if (ret)
goto net_fail;
ret = register_blkdev(AOE_MAJOR, DEVICE_NAME);
if (ret < 0) {
printk(KERN_ERR "aoe: aoeblk_init: can't register major\n");
goto blkreg_fail;
}
printk(KERN_INFO
"aoe: aoe_init: AoE v2.6-%s initialised.\n",
VERSION);
discover_timer(TINIT);
return 0;
blkreg_fail:
aoenet_exit();
net_fail:
aoeblk_exit();
blk_fail:
aoechr_exit();
chr_fail:
aoedev_exit();
printk(KERN_INFO "aoe: aoe_init: initialisation failure.\n");
return ret;
}
module_init(aoe_init);
......
......@@ -102,10 +102,7 @@ aoenet_xmit(struct sk_buff *sl)
}
/*
* (1) i have no idea if this is redundant, but i can't figure why
* the ifp is passed in if it is.
*
* (2) len doesn't include the header by default. I want this.
* (1) len doesn't include the header by default. I want this.
*/
static int
aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt)
......@@ -117,12 +114,11 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt)
if (!skb)
return 0;
skb->dev = ifp; /* (1) */
if (!is_aoe_netif(ifp))
goto exit;
skb->len += ETH_HLEN; /* (2) */
//skb->len += ETH_HLEN; /* (1) */
skb_push(skb, ETH_HLEN); /* (1) */
h = (struct aoe_hdr *) skb->mac.raw;
n = __be32_to_cpu(*((u32 *) h->tag));
......@@ -133,10 +129,11 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt)
n = h->err;
if (n > NECODES)
n = 0;
printk(KERN_CRIT "aoe: aoenet_rcv: error packet from %d.%d; "
"ecode=%d '%s'\n",
__be16_to_cpu(*((u16 *) h->major)), h->minor,
h->err, aoe_errlist[n]);
if (net_ratelimit())
printk(KERN_ERR "aoe: aoenet_rcv: error packet from %d.%d; "
"ecode=%d '%s'\n",
__be16_to_cpu(*((u16 *) h->major)), h->minor,
h->err, aoe_errlist[n]);
goto exit;
}
......@@ -167,7 +164,7 @@ aoenet_init(void)
return 0;
}
void __exit
void
aoenet_exit(void)
{
dev_remove_pack(&aoe_pt);
......
......@@ -19,10 +19,11 @@
static struct subsystem block_subsys;
static DECLARE_MUTEX(block_subsys_sem);
/*
* Can be deleted altogether. Later.
*
* Modified under both block_subsys.rwsem and major_names_lock.
*/
static struct blk_major_name {
struct blk_major_name *next;
......@@ -30,8 +31,6 @@ static struct blk_major_name {
char name[16];
} *major_names[MAX_PROBE_HASH];
static spinlock_t major_names_lock = SPIN_LOCK_UNLOCKED;
/* index in the above - for now: assume no multimajor ranges */
static inline int major_to_index(int major)
{
......@@ -47,13 +46,13 @@ int get_blkdev_list(char *p)
len = sprintf(p, "\nBlock devices:\n");
down_read(&block_subsys.rwsem);
down(&block_subsys_sem);
for (i = 0; i < ARRAY_SIZE(major_names); i++) {
for (n = major_names[i]; n; n = n->next)
len += sprintf(p+len, "%3d %s\n",
n->major, n->name);
}
up_read(&block_subsys.rwsem);
up(&block_subsys_sem);
return len;
}
......@@ -63,9 +62,8 @@ int register_blkdev(unsigned int major, const char *name)
{
struct blk_major_name **n, *p;
int index, ret = 0;
unsigned long flags;
down_write(&block_subsys.rwsem);
down(&block_subsys_sem);
/* temporary */
if (major == 0) {
......@@ -95,7 +93,6 @@ int register_blkdev(unsigned int major, const char *name)
p->next = NULL;
index = major_to_index(major);
spin_lock_irqsave(&major_names_lock, flags);
for (n = &major_names[index]; *n; n = &(*n)->next) {
if ((*n)->major == major)
break;
......@@ -104,7 +101,6 @@ int register_blkdev(unsigned int major, const char *name)
*n = p;
else
ret = -EBUSY;
spin_unlock_irqrestore(&major_names_lock, flags);
if (ret < 0) {
printk("register_blkdev: cannot get major %d for %s\n",
......@@ -112,7 +108,7 @@ int register_blkdev(unsigned int major, const char *name)
kfree(p);
}
out:
up_write(&block_subsys.rwsem);
up(&block_subsys_sem);
return ret;
}
......@@ -124,11 +120,9 @@ int unregister_blkdev(unsigned int major, const char *name)
struct blk_major_name **n;
struct blk_major_name *p = NULL;
int index = major_to_index(major);
unsigned long flags;
int ret = 0;
down_write(&block_subsys.rwsem);
spin_lock_irqsave(&major_names_lock, flags);
down(&block_subsys_sem);
for (n = &major_names[index]; *n; n = &(*n)->next)
if ((*n)->major == major)
break;
......@@ -138,8 +132,7 @@ int unregister_blkdev(unsigned int major, const char *name)
p = *n;
*n = p->next;
}
spin_unlock_irqrestore(&major_names_lock, flags);
up_write(&block_subsys.rwsem);
up(&block_subsys_sem);
kfree(p);
return ret;
......@@ -233,7 +226,7 @@ static void *part_start(struct seq_file *part, loff_t *pos)
struct list_head *p;
loff_t l = *pos;
down_read(&block_subsys.rwsem);
down(&block_subsys_sem);
list_for_each(p, &block_subsys.kset.list)
if (!l--)
return list_entry(p, struct gendisk, kobj.entry);
......@@ -250,7 +243,7 @@ static void *part_next(struct seq_file *part, void *v, loff_t *pos)
static void part_stop(struct seq_file *part, void *v)
{
up_read(&block_subsys.rwsem);
up(&block_subsys_sem);
}
static int show_partition(struct seq_file *part, void *v)
......@@ -322,12 +315,6 @@ subsys_initcall(device_init);
/*
* kobject & sysfs bindings for block devices
*/
struct disk_attribute {
struct attribute attr;
ssize_t (*show)(struct gendisk *, char *);
};
static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr,
char *page)
{
......@@ -508,7 +495,7 @@ static void *diskstats_start(struct seq_file *part, loff_t *pos)
loff_t k = *pos;
struct list_head *p;
down_read(&block_subsys.rwsem);
down(&block_subsys_sem);
list_for_each(p, &block_subsys.kset.list)
if (!k--)
return list_entry(p, struct gendisk, kobj.entry);
......@@ -525,7 +512,7 @@ static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos)
static void diskstats_stop(struct seq_file *part, void *v)
{
up_read(&block_subsys.rwsem);
up(&block_subsys_sem);
}
static int diskstats_show(struct seq_file *s, void *v)
......
......@@ -108,7 +108,8 @@ struct ub_dev;
*/
#define UB_URB_TIMEOUT (HZ*2)
#define UB_DATA_TIMEOUT (HZ*5) /* ZIP does spin-ups in the data phase */
#define UB_CTRL_TIMEOUT (HZ/2) /* 500ms ought to be enough to clear a stall */
#define UB_STAT_TIMEOUT (HZ*5) /* Same spinups and eject for a dataless cmd. */
#define UB_CTRL_TIMEOUT (HZ/2) /* 500ms ought to be enough to clear a stall */
/*
* An instance of a SCSI command in transit.
......@@ -307,6 +308,7 @@ static void ub_scsi_action(unsigned long _dev);
static void ub_scsi_dispatch(struct ub_dev *sc);
static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc);
static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
......@@ -894,7 +896,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
if (urb->status == -EPIPE) {
/*
* STALL while clearning STALL.
* A STALL is illegal on a control pipe!
* The control pipe clears itself - nothing to do.
* XXX Might try to reset the device here and retry.
*/
printk(KERN_NOTICE "%s: "
......@@ -917,7 +919,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
if (urb->status == -EPIPE) {
/*
* STALL while clearning STALL.
* A STALL is illegal on a control pipe!
* The control pipe clears itself - nothing to do.
* XXX Might try to reset the device here and retry.
*/
printk(KERN_NOTICE "%s: "
......@@ -941,7 +943,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
if (rc != 0) {
printk(KERN_NOTICE "%s: "
"unable to submit clear for device %u (%d)\n",
"unable to submit clear for device %u"
" (code %d)\n",
sc->name, sc->dev->devnum, rc);
/*
* This is typically ENOMEM or some other such shit.
......@@ -1001,7 +1004,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
if (rc != 0) {
printk(KERN_NOTICE "%s: "
"unable to submit clear for device %u (%d)\n",
"unable to submit clear for device %u"
" (code %d)\n",
sc->name, sc->dev->devnum, rc);
/*
* This is typically ENOMEM or some other such shit.
......@@ -1033,7 +1037,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
if (rc != 0) {
printk(KERN_NOTICE "%s: "
"unable to submit clear for device %u (%d)\n",
"unable to submit clear for device %u"
" (code %d)\n",
sc->name, sc->dev->devnum, rc);
/*
* This is typically ENOMEM or some other such shit.
......@@ -1061,33 +1066,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
sc->name, sc->dev->devnum);
goto Bad_End;
}
/*
* ub_state_stat only not dropping the count...
*/
UB_INIT_COMPLETION(sc->work_done);
sc->last_pipe = sc->recv_bulk_pipe;
usb_fill_bulk_urb(&sc->work_urb, sc->dev,
sc->recv_bulk_pipe, &sc->work_bcs,
US_BULK_CS_WRAP_LEN, ub_urb_complete, sc);
sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
sc->work_urb.actual_length = 0;
sc->work_urb.error_count = 0;
sc->work_urb.status = 0;
rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC);
if (rc != 0) {
/* XXX Clear stalls */
printk("%s: CSW #%d submit failed (%d)\n",
sc->name, cmd->tag, rc); /* P3 */
ub_complete(&sc->work_done);
ub_state_done(sc, cmd, rc);
return;
}
sc->work_timer.expires = jiffies + UB_URB_TIMEOUT;
add_timer(&sc->work_timer);
__ub_state_stat(sc, cmd);
return;
}
......@@ -1108,17 +1087,31 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
goto Bad_End;
}
#if 0
if (bcs->Signature != cpu_to_le32(US_BULK_CS_SIGN) &&
bcs->Signature != cpu_to_le32(US_BULK_CS_OLYMPUS_SIGN)) {
/* XXX Rate-limit, even for P3 tagged */
/* P3 */ printk("ub: signature 0x%x\n", bcs->Signature);
/* Windows ignores signatures, so do we. */
}
#endif
if (bcs->Tag != cmd->tag) {
/* P3 */ printk("%s: tag orig 0x%x reply 0x%x\n",
sc->name, cmd->tag, bcs->Tag);
goto Bad_End;
/*
* This usually happens when we disagree with the
* device's microcode about something. For instance,
* a few of them throw this after timeouts. They buffer
* commands and reply at commands we timed out before.
* Without flushing these replies we loop forever.
*/
if (++cmd->stat_count >= 4) {
printk(KERN_NOTICE "%s: "
"tag mismatch orig 0x%x reply 0x%x "
"on device %u\n",
sc->name, cmd->tag, bcs->Tag,
sc->dev->devnum);
goto Bad_End;
}
__ub_state_stat(sc, cmd);
return;
}
switch (bcs->Status) {
......@@ -1174,9 +1167,9 @@ static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc)
/*
* Factorization helper for the command state machine:
* Submit a CSW read and go to STAT state.
* Submit a CSW read.
*/
static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
{
int rc;
......@@ -1192,14 +1185,23 @@ static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
/* XXX Clear stalls */
printk("ub: CSW #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */
printk("%s: CSW #%d submit failed (%d)\n", sc->name, cmd->tag, rc); /* P3 */
ub_complete(&sc->work_done);
ub_state_done(sc, cmd, rc);
return;
}
sc->work_timer.expires = jiffies + UB_URB_TIMEOUT;
sc->work_timer.expires = jiffies + UB_STAT_TIMEOUT;
add_timer(&sc->work_timer);
}
/*
* Factorization helper for the command state machine:
* Submit a CSW read and go to STAT state.
*/
static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
{
__ub_state_stat(sc, cmd);
cmd->stat_count = 0;
cmd->state = UB_CMDST_STAT;
......
......@@ -112,6 +112,7 @@ config I2C_I801
82801EB
6300ESB
ICH6
ICH7
This driver can also be built as a module. If so, the module
will be called i2c-i801.
......@@ -208,7 +209,7 @@ config I2C_KEYWEST
config I2C_MPC
tristate "MPC107/824x/85xx/52xx"
depends on I2C && FSL_OCP
depends on I2C && PPC
help
If you say yes to this option, support will be included for the
built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and
......
......@@ -30,6 +30,7 @@
82801EB 24D3 (HW PEC supported, 32 byte buffer not supported)
6300ESB 25A4
ICH6 266A
ICH7 27DA
This driver supports several versions of Intel's I/O Controller Hubs (ICH).
For SMBus support, they are similar to the PIIX4 and are part
of Intel's '810' and other chipsets.
......@@ -556,6 +557,7 @@ static struct pci_device_id i801_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_3) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
{ 0, }
};
......
/*
* (C) Copyright 2003-2004
* Humboldt Solutions Ltd, adrian@humboldt.co.uk.
* This is a combined i2c adapter and algorithm driver for the
* MPC107/Tsi107 PowerPC northbridge and processors that include
* the same I2C unit (8240, 8245, 85xx).
* the same I2C unit (8240, 8245, 85xx).
*
* Release 0.6
* Release 0.8
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
......@@ -20,7 +20,13 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/io.h>
#ifdef CONFIG_FSL_OCP
#include <asm/ocp.h>
#define FSL_I2C_DEV_SEPARATE_DFSRR FS_I2C_SEPARATE_DFSRR
#define FSL_I2C_DEV_CLOCK_5200 FS_I2C_CLOCK_5200
#else
#include <linux/fsl_devices.h>
#endif
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
......@@ -50,10 +56,11 @@
struct mpc_i2c {
char *base;
struct ocp_def *ocpdef;
u32 interrupt;
wait_queue_head_t queue;
struct i2c_adapter adap;
int irq;
u32 flags;
};
static __inline__ void writeccr(struct mpc_i2c *i2c, u32 x)
......@@ -75,12 +82,12 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id, struct pt_regs *regs)
static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
{
DECLARE_WAITQUEUE(wait, current);
unsigned long orig_jiffies = jiffies;
u32 x;
int result = 0;
if (i2c->ocpdef->irq == OCP_IRQ_NA) {
if (i2c->irq == 0)
{
while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
schedule();
if (time_after(jiffies, orig_jiffies + timeout)) {
......@@ -92,28 +99,22 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
x = readb(i2c->base + MPC_I2C_SR);
writeb(0, i2c->base + MPC_I2C_SR);
} else {
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&i2c->queue, &wait);
while (!(i2c->interrupt & CSR_MIF)) {
if (signal_pending(current)) {
pr_debug("I2C: Interrupted\n");
result = -EINTR;
break;
}
if (time_after(jiffies, orig_jiffies + timeout)) {
pr_debug("I2C: timeout\n");
result = -EIO;
break;
}
msleep_interruptible(jiffies_to_msecs(timeout));
/* Interrupt mode */
result = wait_event_interruptible_timeout(i2c->queue,
(i2c->interrupt & CSR_MIF), timeout * HZ);
if (unlikely(result < 0))
pr_debug("I2C: wait interrupted\n");
else if (unlikely(!(i2c->interrupt & CSR_MIF))) {
pr_debug("I2C: wait timeout\n");
result = -ETIMEDOUT;
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&i2c->queue, &wait);
x = i2c->interrupt;
i2c->interrupt = 0;
}
if (result < -0)
if (result < 0)
return result;
if (!(x & CSR_MCF)) {
......@@ -137,12 +138,11 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
static void mpc_i2c_setclock(struct mpc_i2c *i2c)
{
struct ocp_fs_i2c_data *i2c_data = i2c->ocpdef->additions;
/* Set clock and filters */
if (i2c_data && (i2c_data->flags & FS_I2C_SEPARATE_DFSRR)) {
if (i2c->flags & FSL_I2C_DEV_SEPARATE_DFSRR) {
writeb(0x31, i2c->base + MPC_I2C_FDR);
writeb(0x10, i2c->base + MPC_I2C_DFSRR);
} else if (i2c_data && (i2c_data->flags & FS_I2C_CLOCK_5200))
} else if (i2c->flags & FSL_I2C_DEV_CLOCK_5200)
writeb(0x3f, i2c->base + MPC_I2C_FDR);
else
writel(0x1031, i2c->base + MPC_I2C_FDR);
......@@ -165,7 +165,7 @@ static int mpc_write(struct mpc_i2c *i2c, int target,
const u8 * data, int length, int restart)
{
int i;
unsigned timeout = HZ;
unsigned timeout = i2c->adap.timeout;
u32 flags = restart ? CCR_RSTA : 0;
/* Start with MEN */
......@@ -193,7 +193,7 @@ static int mpc_write(struct mpc_i2c *i2c, int target,
static int mpc_read(struct mpc_i2c *i2c, int target,
u8 * data, int length, int restart)
{
unsigned timeout = HZ;
unsigned timeout = i2c->adap.timeout;
int i;
u32 flags = restart ? CCR_RSTA : 0;
......@@ -294,6 +294,7 @@ static struct i2c_adapter mpc_ops = {
.retries = 1
};
#ifdef CONFIG_FSL_OCP
static int __devinit mpc_i2c_probe(struct ocp_device *ocp)
{
int result = 0;
......@@ -302,7 +303,10 @@ static int __devinit mpc_i2c_probe(struct ocp_device *ocp)
if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
return -ENOMEM;
}
i2c->ocpdef = ocp->def;
memset(i2c, 0, sizeof(*i2c));
i2c->irq = ocp->def->irq;
i2c->flags = ((struct ocp_fs_i2c_data *)ocp->def->additions)->flags;
init_waitqueue_head(&i2c->queue);
if (!request_mem_region(ocp->def->paddr, MPC_I2C_REGION, "i2c-mpc")) {
......@@ -318,16 +322,20 @@ static int __devinit mpc_i2c_probe(struct ocp_device *ocp)
goto fail_map;
}
if (ocp->def->irq != OCP_IRQ_NA)
if (i2c->irq != OCP_IRQ_NA)
{
if ((result = request_irq(ocp->def->irq, mpc_i2c_isr,
0, "i2c-mpc", i2c)) < 0) {
printk(KERN_ERR
"i2c-mpc - failed to attach interrupt\n");
goto fail_irq;
}
} else
i2c->irq = 0;
i2c->adap = mpc_ops;
i2c_set_adapdata(&i2c->adap, i2c);
if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
goto fail_add;
......@@ -354,9 +362,9 @@ static void __devexit mpc_i2c_remove(struct ocp_device *ocp)
i2c_del_adapter(&i2c->adap);
if (ocp->def->irq != OCP_IRQ_NA)
free_irq(i2c->ocpdef->irq, i2c);
free_irq(i2c->irq, i2c);
iounmap(i2c->base);
release_mem_region(i2c->ocpdef->paddr, MPC_I2C_REGION);
release_mem_region(ocp->def->paddr, MPC_I2C_REGION);
kfree(i2c);
}
......@@ -386,6 +394,101 @@ static void __exit iic_exit(void)
module_init(iic_init);
module_exit(iic_exit);
#else
static int fsl_i2c_probe(struct device *device)
{
int result = 0;
struct mpc_i2c *i2c;
struct platform_device *pdev = to_platform_device(device);
struct fsl_i2c_platform_data *pdata;
struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
return -ENOMEM;
}
memset(i2c, 0, sizeof(*i2c));
i2c->irq = platform_get_irq(pdev, 0);
i2c->flags = pdata->device_flags;
init_waitqueue_head(&i2c->queue);
i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION);
if (!i2c->base) {
printk(KERN_ERR "i2c-mpc - failed to map controller\n");
result = -ENOMEM;
goto fail_map;
}
if (i2c->irq != 0)
if ((result = request_irq(i2c->irq, mpc_i2c_isr,
0, "fsl-i2c", i2c)) < 0) {
printk(KERN_ERR
"i2c-mpc - failed to attach interrupt\n");
goto fail_irq;
}
i2c->adap = mpc_ops;
i2c_set_adapdata(&i2c->adap, i2c);
i2c->adap.dev.parent = &pdev->dev;
if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
goto fail_add;
}
mpc_i2c_setclock(i2c);
dev_set_drvdata(device, i2c);
return result;
fail_add:
if (i2c->irq != 0)
free_irq(i2c->irq, 0);
fail_irq:
iounmap(i2c->base);
fail_map:
kfree(i2c);
return result;
};
static int fsl_i2c_remove(struct device *device)
{
struct mpc_i2c *i2c = dev_get_drvdata(device);
dev_set_drvdata(device, NULL);
i2c_del_adapter(&i2c->adap);
if (i2c->irq != 0)
free_irq(i2c->irq, i2c);
iounmap(i2c->base);
kfree(i2c);
return 0;
};
/* Structure for a device driver */
static struct device_driver fsl_i2c_driver = {
.name = "fsl-i2c",
.bus = &platform_bus_type,
.probe = fsl_i2c_probe,
.remove = fsl_i2c_remove,
};
static int __init fsl_i2c_init(void)
{
return driver_register(&fsl_i2c_driver);
}
static void __exit fsl_i2c_exit(void)
{
driver_unregister(&fsl_i2c_driver);
}
module_init(fsl_i2c_init);
module_exit(fsl_i2c_exit);
#endif /* CONFIG_FSL_OCP */
MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
MODULE_DESCRIPTION
......
......@@ -452,6 +452,14 @@ void adm1026_init_client(struct i2c_client *client)
client->id, value);
data->config1 = value;
adm1026_write_value(client, ADM1026_REG_CONFIG1, value);
/* initialize fan_div[] to hardware defaults */
value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) |
(adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8);
for (i = 0;i <= 7;++i) {
data->fan_div[i] = DIV_FROM_REG(value & 0x03);
value >>= 2;
}
}
void adm1026_print_gpio(struct i2c_client *client)
......@@ -459,8 +467,7 @@ void adm1026_print_gpio(struct i2c_client *client)
struct adm1026_data *data = i2c_get_clientdata(client);
int i;
dev_dbg(&client->dev, "(%d): GPIO config is:",
client->id);
dev_dbg(&client->dev, "(%d): GPIO config is:", client->id);
for (i = 0;i <= 7;++i) {
if (data->config2 & (1 << i)) {
dev_dbg(&client->dev, "\t(%d): %sGP%s%d\n", client->id,
......
......@@ -78,8 +78,6 @@ static struct i2c_driver eeprom_driver = {
.detach_client = eeprom_detach_client,
};
static int eeprom_id;
static void eeprom_update_client(struct i2c_client *client, u8 slice)
{
struct eeprom_data *data = i2c_get_clientdata(client);
......@@ -165,16 +163,14 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
struct eeprom_data *data;
int err = 0;
/* Make sure we aren't probing the ISA bus!! This is just a safety check
at this moment; i2c_detect really won't call us. */
#ifdef DEBUG
if (i2c_is_isa_adapter(adapter)) {
dev_dbg(&adapter->dev, " eeprom_detect called for an ISA bus adapter?!?\n");
return 0;
}
#endif
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
/* There are three ways we can read the EEPROM data:
(1) I2C block reads (faster, but unsupported by most adapters)
(2) Consecutive byte reads (100% overhead)
(3) Regular byte data reads (200% overhead)
The third method is not implemented by this driver because all
known adapters support at least the second. */
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA
| I2C_FUNC_SMBUS_BYTE))
goto exit;
/* OK. For now, we presume we have a valid client. We now create the
......@@ -197,27 +193,28 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
/* prevent 24RF08 corruption */
i2c_smbus_write_quick(new_client, 0);
data->nature = UNKNOWN;
/* Detect the Vaio nature of EEPROMs.
We use the "PCG-" prefix as the signature. */
if (address == 0x57) {
if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P' &&
i2c_smbus_read_byte_data(new_client, 0x81) == 'C' &&
i2c_smbus_read_byte_data(new_client, 0x82) == 'G' &&
i2c_smbus_read_byte_data(new_client, 0x83) == '-')
data->nature = VAIO;
}
/* Fill in the remaining client fields */
strncpy(new_client->name, "eeprom", I2C_NAME_SIZE);
new_client->id = eeprom_id++;
strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
data->nature = UNKNOWN;
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto exit_kfree;
/* Detect the Vaio nature of EEPROMs.
We use the "PCG-" prefix as the signature. */
if (address == 0x57) {
if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P'
&& i2c_smbus_read_byte(new_client) == 'C'
&& i2c_smbus_read_byte(new_client) == 'G'
&& i2c_smbus_read_byte(new_client) == '-')
dev_info(&new_client->dev, "Vaio EEPROM detected, "
"enabling password protection\n");
data->nature = VAIO;
}
/* create the sysfs eeprom file */
sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr);
......
This diff is collapsed.
......@@ -464,8 +464,8 @@ static void lm63_init_client(struct i2c_client *client)
(data->config & 0x04) ? "tachometer input" :
"alert output");
dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n",
(data->config_fan & 0x04) ? "1.4" : "360",
((data->config_fan & 0x04) ? 700 : 180000) / data->pwm1_freq);
(data->config_fan & 0x08) ? "1.4" : "360",
((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq);
dev_dbg(&client->dev, "PWM output active %s, %s mode\n",
(data->config_fan & 0x10) ? "low" : "high",
(data->config_fan & 0x20) ? "manual" : "auto");
......
......@@ -36,7 +36,7 @@ static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */
SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
SENSORS_INSMOD_5(lm85b, lm85c, adm1027, adt7463, emc6d100);
/* The LM85 registers */
......@@ -66,11 +66,15 @@ SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
#define LM85_DEVICE_ADX 0x27
#define LM85_COMPANY_NATIONAL 0x01
#define LM85_COMPANY_ANALOG_DEV 0x41
#define LM85_COMPANY_SMSC 0x5c
#define LM85_VERSTEP_VMASK 0xf0
#define LM85_VERSTEP_GENERIC 0x60
#define LM85_VERSTEP_LM85C 0x60
#define LM85_VERSTEP_LM85B 0x62
#define LM85_VERSTEP_ADM1027 0x60
#define LM85_VERSTEP_ADT7463 0x62
#define LM85_VERSTEP_EMC6D100_A0 0x60
#define LM85_VERSTEP_EMC6D100_A1 0x61
#define LM85_REG_CONFIG 0x40
......@@ -105,6 +109,12 @@ SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
#define ADT7463_REG_THERM 0x79
#define ADT7463_REG_THERM_LIMIT 0x7A
#define EMC6D100_REG_ALARM3 0x7d
/* IN5, IN6 and IN7 */
#define EMC6D100_REG_IN(nr) (0x70 + ((nr)-5))
#define EMC6D100_REG_IN_MIN(nr) (0x73 + ((nr)-5) * 2)
#define EMC6D100_REG_IN_MAX(nr) (0x74 + ((nr)-5) * 2)
#define LM85_ALARM_IN0 0x0001
#define LM85_ALARM_IN1 0x0002
#define LM85_ALARM_IN2 0x0004
......@@ -135,7 +145,8 @@ SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
/* IN are scaled acording to built-in resistors */
static int lm85_scaling[] = { /* .001 Volts */
2500, 2250, 3300, 5000, 12000
2500, 2250, 3300, 5000, 12000,
3300, 1500, 1800 /*EMC6D100*/
};
#define SCALE(val,from,to) (((val)*(to) + ((from)/2))/(from))
#define INS_TO_REG(n,val) (SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255))
......@@ -331,9 +342,9 @@ struct lm85_data {
unsigned long last_reading; /* In jiffies */
unsigned long last_config; /* In jiffies */
u8 in[5]; /* Register value */
u8 in_max[5]; /* Register value */
u8 in_min[5]; /* Register value */
u8 in[8]; /* Register value */
u8 in_max[8]; /* Register value */
u8 in_min[8]; /* Register value */
s8 temp[3]; /* Register value */
s8 temp_min[3]; /* Register value */
s8 temp_max[3]; /* Register value */
......@@ -353,7 +364,7 @@ struct lm85_data {
u16 tmin_ctl; /* Register value */
unsigned long therm_total; /* Cummulative therm count */
u8 therm_limit; /* Register value */
u16 alarms; /* Register encoding, combined */
u32 alarms; /* Register encoding, combined */
struct lm85_autofan autofan[3];
struct lm85_zone zone[3];
};
......@@ -1072,7 +1083,7 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
&& verstep == LM85_VERSTEP_LM85B ) {
kind = lm85b ;
} else if( company == LM85_COMPANY_NATIONAL
&& (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) {
&& (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
" Defaulting to LM85.\n", verstep);
kind = any_chip ;
......@@ -1083,17 +1094,34 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
&& verstep == LM85_VERSTEP_ADT7463 ) {
kind = adt7463 ;
} else if( company == LM85_COMPANY_ANALOG_DEV
&& (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) {
&& (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
" Defaulting to ADM1027.\n", verstep);
kind = adm1027 ;
} else if( kind == 0 && (verstep & 0xf0) == 0x60) {
" Defaulting to Generic LM85.\n", verstep );
kind = any_chip ;
} else if( company == LM85_COMPANY_SMSC
&& (verstep == LM85_VERSTEP_EMC6D100_A0
|| verstep == LM85_VERSTEP_EMC6D100_A1) ) {
/* Unfortunately, we can't tell a '100 from a '101
* from the registers. Since a '101 is a '100
* in a package with fewer pins and therefore no
* 3.3V, 1.5V or 1.8V inputs, perhaps if those
* inputs read 0, then it's a '101.
*/
kind = emc6d100 ;
} else if( company == LM85_COMPANY_SMSC
&& (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
dev_err(&adapter->dev, "lm85: Detected SMSC chip\n");
dev_err(&adapter->dev, "lm85: Unrecognized version/stepping 0x%02x"
" Defaulting to Generic LM85.\n", verstep );
kind = any_chip ;
} else if( kind == any_chip
&& (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
dev_err(&adapter->dev, "Generic LM85 Version 6 detected\n");
/* Leave kind as "any_chip" */
} else {
dev_dbg(&adapter->dev, "Autodetection failed\n");
/* Not an LM85 ... */
if( kind == 0 ) { /* User used force=x,y */
if( kind == any_chip ) { /* User used force=x,y */
dev_err(&adapter->dev, "Generic LM85 Version 6 not"
" found at %d,0x%02x. Try force_lm85c.\n",
i2c_adapter_id(adapter), address );
......@@ -1114,6 +1142,8 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
type_name = "adm1027";
} else if ( kind == adt7463 ) {
type_name = "adt7463";
} else if ( kind == emc6d100){
type_name = "emc6d100";
}
strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
......@@ -1365,15 +1395,24 @@ static struct lm85_data *lm85_update_device(struct device *dev)
lm85_read_value(client, LM85_REG_PWM(i));
}
data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
if ( data->type == adt7463 ) {
if( data->therm_total < ULONG_MAX - 256 ) {
data->therm_total +=
lm85_read_value(client, ADT7463_REG_THERM );
}
} else if ( data->type == emc6d100 ) {
/* Three more voltage sensors */
for (i = 5; i <= 7; ++i) {
data->in[i] =
lm85_read_value(client, EMC6D100_REG_IN(i));
}
/* More alarm bits */
data->alarms |=
lm85_read_value(client, EMC6D100_REG_ALARM3) << 16;
}
data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
data->last_reading = jiffies ;
}; /* last_reading */
......@@ -1389,6 +1428,15 @@ static struct lm85_data *lm85_update_device(struct device *dev)
lm85_read_value(client, LM85_REG_IN_MAX(i));
}
if ( data->type == emc6d100 ) {
for (i = 5; i <= 7; ++i) {
data->in_min[i] =
lm85_read_value(client, EMC6D100_REG_IN_MIN(i));
data->in_max[i] =
lm85_read_value(client, EMC6D100_REG_IN_MAX(i));
}
}
for (i = 0; i <= 3; ++i) {
data->fan_min[i] =
lm85_read_value(client, LM85_REG_FAN_MIN(i));
......
......@@ -786,15 +786,12 @@ static struct via686a_data *via686a_update_device(struct device *dev)
}
static struct pci_device_id via686a_pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_82C686_4,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
static int __devinit via686a_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
......
......@@ -84,6 +84,7 @@ config EQUALIZER
config TUN
tristate "Universal TUN/TAP device driver support"
depends on NETDEVICES
select CRC32
---help---
TUN/TAP provides packet reception and transmission for user space
programs. It can be viewed as a simple Point-to-Point or Ethernet
......
......@@ -909,7 +909,7 @@ static void set_rx_mode_8012(struct net_device *dev)
i++, mclist = mclist->next)
{
int filterbit = ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f;
mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
}
new_mode = CMR2h_Normal;
}
......
......@@ -59,9 +59,9 @@
struct bmac_data {
/* volatile struct bmac *bmac; */
struct sk_buff_head *queue;
volatile struct dbdma_regs *tx_dma;
volatile struct dbdma_regs __iomem *tx_dma;
int tx_dma_intr;
volatile struct dbdma_regs *rx_dma;
volatile struct dbdma_regs __iomem *rx_dma;
int rx_dma_intr;
volatile struct dbdma_cmd *tx_cmds; /* xmit dma command list */
volatile struct dbdma_cmd *rx_cmds; /* recv dma command list */
......@@ -165,35 +165,35 @@ static void bmac_start(struct net_device *dev);
#define DBDMA_CLEAR(x) ( (x) << 16)
static inline void
dbdma_st32(volatile unsigned long *a, unsigned long x)
dbdma_st32(volatile __u32 __iomem *a, unsigned long x)
{
__asm__ volatile( "stwbrx %0,0,%1" : : "r" (x), "r" (a) : "memory");
return;
}
static inline unsigned long
dbdma_ld32(volatile unsigned long *a)
dbdma_ld32(volatile __u32 __iomem *a)
{
unsigned long swap;
__u32 swap;
__asm__ volatile ("lwbrx %0,0,%1" : "=r" (swap) : "r" (a));
return swap;
}
static void
dbdma_continue(volatile struct dbdma_regs *dmap)
dbdma_continue(volatile struct dbdma_regs __iomem *dmap)
{
dbdma_st32((volatile unsigned long *)&dmap->control,
dbdma_st32(&dmap->control,
DBDMA_SET(RUN|WAKE) | DBDMA_CLEAR(PAUSE|DEAD));
eieio();
}
static void
dbdma_reset(volatile struct dbdma_regs *dmap)
dbdma_reset(volatile struct dbdma_regs __iomem *dmap)
{
dbdma_st32((volatile unsigned long *)&dmap->control,
dbdma_st32(&dmap->control,
DBDMA_CLEAR(ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN));
eieio();
while (dbdma_ld32((volatile unsigned long *)&dmap->status) & RUN)
while (dbdma_ld32(&dmap->status) & RUN)
eieio();
}
......@@ -213,22 +213,22 @@ dbdma_setcmd(volatile struct dbdma_cmd *cp,
static inline
void bmwrite(struct net_device *dev, unsigned long reg_offset, unsigned data )
{
out_le16((void *)dev->base_addr + reg_offset, data);
out_le16((void __iomem *)dev->base_addr + reg_offset, data);
}
static inline
volatile unsigned short bmread(struct net_device *dev, unsigned long reg_offset )
{
return in_le16((void *)dev->base_addr + reg_offset);
return in_le16((void __iomem *)dev->base_addr + reg_offset);
}
static void
bmac_enable_and_reset_chip(struct net_device *dev)
{
struct bmac_data *bp = netdev_priv(dev);
volatile struct dbdma_regs *rd = bp->rx_dma;
volatile struct dbdma_regs *td = bp->tx_dma;
volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
volatile struct dbdma_regs __iomem *td = bp->tx_dma;
if (rd)
dbdma_reset(rd);
......@@ -406,7 +406,7 @@ static void
bmac_start_chip(struct net_device *dev)
{
struct bmac_data *bp = netdev_priv(dev);
volatile struct dbdma_regs *rd = bp->rx_dma;
volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
unsigned short oldConfig;
/* enable rx dma channel */
......@@ -476,8 +476,8 @@ static int bmac_suspend(struct macio_dev *mdev, u32 state)
bp->sleeping = 1;
spin_unlock_irqrestore(&bp->lock, flags);
if (bp->opened) {
volatile struct dbdma_regs *rd = bp->rx_dma;
volatile struct dbdma_regs *td = bp->tx_dma;
volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
volatile struct dbdma_regs __iomem *td = bp->tx_dma;
config = bmread(dev, RXCFG);
bmwrite(dev, RXCFG, (config & ~RxMACEnable));
......@@ -602,7 +602,7 @@ bitrev(unsigned char b)
static void
bmac_init_tx_ring(struct bmac_data *bp)
{
volatile struct dbdma_regs *td = bp->tx_dma;
volatile struct dbdma_regs __iomem *td = bp->tx_dma;
memset((char *)bp->tx_cmds, 0, (N_TX_RING+1) * sizeof(struct dbdma_cmd));
......@@ -623,7 +623,7 @@ bmac_init_tx_ring(struct bmac_data *bp)
static int
bmac_init_rx_ring(struct bmac_data *bp)
{
volatile struct dbdma_regs *rd = bp->rx_dma;
volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
int i;
struct sk_buff *skb;
......@@ -657,7 +657,7 @@ bmac_init_rx_ring(struct bmac_data *bp)
static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev)
{
struct bmac_data *bp = netdev_priv(dev);
volatile struct dbdma_regs *td = bp->tx_dma;
volatile struct dbdma_regs __iomem *td = bp->tx_dma;
int i;
/* see if there's a free slot in the tx ring */
......@@ -693,7 +693,7 @@ static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) dev_id;
struct bmac_data *bp = netdev_priv(dev);
volatile struct dbdma_regs *rd = bp->rx_dma;
volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
volatile struct dbdma_cmd *cp;
int i, nb, stat;
struct sk_buff *skb;
......@@ -1331,13 +1331,11 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_match *m
goto err_out_iounmap;
bp->is_bmac_plus = is_bmac_plus;
bp->tx_dma = (volatile struct dbdma_regs *)
ioremap(macio_resource_start(mdev, 1), macio_resource_len(mdev, 1));
bp->tx_dma = ioremap(macio_resource_start(mdev, 1), macio_resource_len(mdev, 1));
if (!bp->tx_dma)
goto err_out_iounmap;
bp->tx_dma_intr = macio_irq(mdev, 1);
bp->rx_dma = (volatile struct dbdma_regs *)
ioremap(macio_resource_start(mdev, 2), macio_resource_len(mdev, 2));
bp->rx_dma = ioremap(macio_resource_start(mdev, 2), macio_resource_len(mdev, 2));
if (!bp->rx_dma)
goto err_out_iounmap_tx;
bp->rx_dma_intr = macio_irq(mdev, 2);
......@@ -1392,11 +1390,11 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_match *m
err_out_irq0:
free_irq(dev->irq, dev);
err_out_iounmap_rx:
iounmap((void *)bp->rx_dma);
iounmap(bp->rx_dma);
err_out_iounmap_tx:
iounmap((void *)bp->tx_dma);
iounmap(bp->tx_dma);
err_out_iounmap:
iounmap((void *)dev->base_addr);
iounmap((void __iomem *)dev->base_addr);
out_release:
macio_release_resources(mdev);
out_free:
......@@ -1421,8 +1419,8 @@ static int bmac_open(struct net_device *dev)
static int bmac_close(struct net_device *dev)
{
struct bmac_data *bp = netdev_priv(dev);
volatile struct dbdma_regs *rd = bp->rx_dma;
volatile struct dbdma_regs *td = bp->tx_dma;
volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
volatile struct dbdma_regs __iomem *td = bp->tx_dma;
unsigned short config;
int i;
......@@ -1505,8 +1503,8 @@ static void bmac_tx_timeout(unsigned long data)
{
struct net_device *dev = (struct net_device *) data;
struct bmac_data *bp = netdev_priv(dev);
volatile struct dbdma_regs *td = bp->tx_dma;
volatile struct dbdma_regs *rd = bp->rx_dma;
volatile struct dbdma_regs __iomem *td = bp->tx_dma;
volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
volatile struct dbdma_cmd *cp;
unsigned long flags;
unsigned short config, oldConfig;
......@@ -1638,9 +1636,9 @@ static int __devexit bmac_remove(struct macio_dev *mdev)
free_irq(bp->tx_dma_intr, dev);
free_irq(bp->rx_dma_intr, dev);
iounmap((void *)dev->base_addr);
iounmap((void *)bp->tx_dma);
iounmap((void *)bp->rx_dma);
iounmap((void __iomem *)dev->base_addr);
iounmap(bp->tx_dma);
iounmap(bp->rx_dma);
macio_release_resources(mdev);
......
......@@ -512,6 +512,7 @@ struct hamachi_private {
u32 rx_int_var, tx_int_var; /* interrupt control variables */
u32 option; /* Hold on to a copy of the options */
struct pci_dev *pci_dev;
void __iomem *base;
};
MODULE_AUTHOR("Donald Becker <becker@scyld.com>, Eric Kasten <kasten@nscl.msu.edu>, Keith Underwood <keithu@parl.clemson.edu>");
......@@ -549,7 +550,7 @@ MODULE_PARM_DESC(options, "GNIC-II Bits 0-3: media type, bits 4-6: as force32, b
MODULE_PARM_DESC(full_duplex, "GNIC-II full duplex setting(s) (1)");
MODULE_PARM_DESC(force32, "GNIC-II: Bit 0: 32 bit PCI, bit 1: disable parity, bit 2: 64 bit PCI (all boards)");
static int read_eeprom(long ioaddr, int location);
static int read_eeprom(void __iomem *ioaddr, int location);
static int mdio_read(struct net_device *dev, int phy_id, int location);
static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
static int hamachi_open(struct net_device *dev);
......@@ -575,7 +576,8 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
int option, i, rx_int_var, tx_int_var, boguscnt;
int chip_id = ent->driver_data;
int irq;
long ioaddr;
void __iomem *ioaddr;
unsigned long base;
static int card_idx;
struct net_device *dev;
void *ring_space;
......@@ -594,9 +596,9 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
goto err_out;
}
ioaddr = pci_resource_start(pdev, 0);
base = pci_resource_start(pdev, 0);
#ifdef __alpha__ /* Really "64 bit addrs" */
ioaddr |= (pci_resource_start(pdev, 1) << 32);
base |= (pci_resource_start(pdev, 1) << 32);
#endif
pci_set_master(pdev);
......@@ -605,7 +607,7 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
if (i) return i;
irq = pdev->irq;
ioaddr = (long) ioremap(ioaddr, 0x400);
ioaddr = ioremap(base, 0x400);
if (!ioaddr)
goto err_out_release;
......@@ -678,7 +680,8 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
i = readb(ioaddr + PCIClkMeas);
}
dev->base_addr = ioaddr;
hmp->base = ioaddr;
dev->base_addr = (unsigned long)ioaddr;
dev->irq = irq;
pci_set_drvdata(pdev, dev);
......@@ -741,7 +744,7 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
goto err_out_unmap_rx;
}
printk(KERN_INFO "%s: %s type %x at 0x%lx, ",
printk(KERN_INFO "%s: %s type %x at %p, ",
dev->name, chip_tbl[chip_id].name, readl(ioaddr + ChipRev),
ioaddr);
for (i = 0; i < 5; i++)
......@@ -790,14 +793,14 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
err_out_cleardev:
free_netdev (dev);
err_out_iounmap:
iounmap((char *)ioaddr);
iounmap(ioaddr);
err_out_release:
pci_release_regions(pdev);
err_out:
return ret;
}
static int __devinit read_eeprom(long ioaddr, int location)
static int __devinit read_eeprom(void __iomem *ioaddr, int location)
{
int bogus_cnt = 1000;
......@@ -819,7 +822,8 @@ static int __devinit read_eeprom(long ioaddr, int location)
static int mdio_read(struct net_device *dev, int phy_id, int location)
{
long ioaddr = dev->base_addr;
struct hamachi_private *hmp = netdev_priv(dev);
void __iomem *ioaddr = hmp->base;
int i;
/* We should check busy first - per docs -KDU */
......@@ -836,7 +840,8 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
{
long ioaddr = dev->base_addr;
struct hamachi_private *hmp = netdev_priv(dev);
void __iomem *ioaddr = hmp->base;
int i;
/* We should check busy first - per docs -KDU */
......@@ -857,7 +862,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
static int hamachi_open(struct net_device *dev)
{
struct hamachi_private *hmp = netdev_priv(dev);
long ioaddr = dev->base_addr;
void __iomem *ioaddr = hmp->base;
int i;
u32 rx_int_var, tx_int_var;
u16 fifo_info;
......@@ -987,7 +992,7 @@ static int hamachi_open(struct net_device *dev)
writew(0x001D, ioaddr + RxDMACtrl);
writew(0x001D, ioaddr + TxDMACtrl);
#endif
writew(0x0001, dev->base_addr + RxCmd);
writew(0x0001, ioaddr + RxCmd);
if (hamachi_debug > 2) {
printk(KERN_DEBUG "%s: Done hamachi_open(), status: Rx %x Tx %x.\n",
......@@ -1038,7 +1043,7 @@ static void hamachi_timer(unsigned long data)
{
struct net_device *dev = (struct net_device *)data;
struct hamachi_private *hmp = netdev_priv(dev);
long ioaddr = dev->base_addr;
void __iomem *ioaddr = hmp->base;
int next_tick = 10*HZ;
if (hamachi_debug > 2) {
......@@ -1063,7 +1068,7 @@ static void hamachi_tx_timeout(struct net_device *dev)
{
int i;
struct hamachi_private *hmp = netdev_priv(dev);
long ioaddr = dev->base_addr;
void __iomem *ioaddr = hmp->base;
printk(KERN_WARNING "%s: Hamachi transmit timed out, status %8.8x,"
" resetting...\n", dev->name, (int)readw(ioaddr + TxStatus));
......@@ -1115,7 +1120,7 @@ static void hamachi_tx_timeout(struct net_device *dev)
}
udelay(60); /* Sleep 60 us just for safety sake */
writew(0x0002, dev->base_addr + RxCmd); /* STOP Rx */
writew(0x0002, ioaddr + RxCmd); /* STOP Rx */
writeb(0x01, ioaddr + ChipReset); /* Reinit the hardware */
......@@ -1157,9 +1162,9 @@ static void hamachi_tx_timeout(struct net_device *dev)
hmp->stats.tx_errors++;
/* Restart the chip's Tx/Rx processes . */
writew(0x0002, dev->base_addr + TxCmd); /* STOP Tx */
writew(0x0001, dev->base_addr + TxCmd); /* START Tx */
writew(0x0001, dev->base_addr + RxCmd); /* START Rx */
writew(0x0002, ioaddr + TxCmd); /* STOP Tx */
writew(0x0001, ioaddr + TxCmd); /* START Tx */
writew(0x0001, ioaddr + RxCmd); /* START Rx */
netif_wake_queue(dev);
}
......@@ -1275,9 +1280,9 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Wake the potentially-idle transmit channel. */
/* If we don't need to read status, DON'T -KDU */
status=readw(dev->base_addr + TxStatus);
status=readw(hmp->base + TxStatus);
if( !(status & 0x0001) || (status & 0x0002))
writew(0x0001, dev->base_addr + TxCmd);
writew(0x0001, hmp->base + TxCmd);
return 1;
}
......@@ -1343,9 +1348,9 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Wake the potentially-idle transmit channel. */
/* If we don't need to read status, DON'T -KDU */
status=readw(dev->base_addr + TxStatus);
status=readw(hmp->base + TxStatus);
if( !(status & 0x0001) || (status & 0x0002))
writew(0x0001, dev->base_addr + TxCmd);
writew(0x0001, hmp->base + TxCmd);
/* Immediately before returning, let's clear as many entries as we can. */
hamachi_tx(dev);
......@@ -1376,8 +1381,9 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs *rgs)
{
struct net_device *dev = dev_instance;
struct hamachi_private *hmp;
long ioaddr, boguscnt = max_interrupt_work;
struct hamachi_private *hmp = netdev_priv(dev);
void __iomem *ioaddr = hmp->base;
long boguscnt = max_interrupt_work;
int handled = 0;
#ifndef final_version /* Can never occur. */
......@@ -1387,8 +1393,6 @@ static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs
}
#endif
ioaddr = dev->base_addr;
hmp = netdev_priv(dev);
spin_lock(&hmp->lock);
do {
......@@ -1687,8 +1691,8 @@ static int hamachi_rx(struct net_device *dev)
/* Restart Rx engine if stopped. */
/* If we don't need to check status, don't. -KDU */
if (readw(dev->base_addr + RxStatus) & 0x0002)
writew(0x0001, dev->base_addr + RxCmd);
if (readw(hmp->base + RxStatus) & 0x0002)
writew(0x0001, hmp->base + RxCmd);
return 0;
}
......@@ -1697,8 +1701,8 @@ static int hamachi_rx(struct net_device *dev)
than just errors. */
static void hamachi_error(struct net_device *dev, int intr_status)
{
long ioaddr = dev->base_addr;
struct hamachi_private *hmp = netdev_priv(dev);
void __iomem *ioaddr = hmp->base;
if (intr_status & (LinkChange|NegotiationChange)) {
if (hamachi_debug > 1)
......@@ -1731,8 +1735,8 @@ static void hamachi_error(struct net_device *dev, int intr_status)
static int hamachi_close(struct net_device *dev)
{
long ioaddr = dev->base_addr;
struct hamachi_private *hmp = netdev_priv(dev);
void __iomem *ioaddr = hmp->base;
struct sk_buff *skb;
int i;
......@@ -1817,8 +1821,8 @@ static int hamachi_close(struct net_device *dev)
static struct net_device_stats *hamachi_get_stats(struct net_device *dev)
{
long ioaddr = dev->base_addr;
struct hamachi_private *hmp = netdev_priv(dev);
void __iomem *ioaddr = hmp->base;
/* We should lock this segment of code for SMP eventually, although
the vulnerability window is very small and statistics are
......@@ -1845,7 +1849,8 @@ static struct net_device_stats *hamachi_get_stats(struct net_device *dev)
static void set_rx_mode(struct net_device *dev)
{
long ioaddr = dev->base_addr;
struct hamachi_private *hmp = netdev_priv(dev);
void __iomem *ioaddr = hmp->base;
if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
/* Unconditionally log net taps. */
......@@ -1950,11 +1955,11 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
*/
if (!capable(CAP_NET_ADMIN))
return -EPERM;
writel(d[0], dev->base_addr + TxIntrCtrl);
writel(d[1], dev->base_addr + RxIntrCtrl);
writel(d[0], np->base + TxIntrCtrl);
writel(d[1], np->base + RxIntrCtrl);
printk(KERN_NOTICE "%s: tx %08x, rx %08x intr\n", dev->name,
(u32) readl(dev->base_addr + TxIntrCtrl),
(u32) readl(dev->base_addr + RxIntrCtrl));
(u32) readl(np->base + TxIntrCtrl),
(u32) readl(np->base + RxIntrCtrl));
rc = 0;
}
......@@ -1980,7 +1985,7 @@ static void __devexit hamachi_remove_one (struct pci_dev *pdev)
pci_free_consistent(pdev, TX_TOTAL_SIZE, hmp->tx_ring,
hmp->tx_ring_dma);
unregister_netdev(dev);
iounmap((char *)dev->base_addr);
iounmap(hmp->base);
free_netdev(dev);
pci_release_regions(pdev);
pci_set_drvdata(pdev, NULL);
......
......@@ -118,7 +118,7 @@ static void myri_enable_irq(void __iomem *lp, void __iomem *cregs)
static inline void bang_the_chip(struct myri_eth *mp)
{
struct myri_shmem *shmem = mp->shmem;
struct myri_shmem __iomem *shmem = mp->shmem;
void __iomem *cregs = mp->cregs;
sbus_writel(1, &shmem->send);
......@@ -127,9 +127,9 @@ static inline void bang_the_chip(struct myri_eth *mp)
static int myri_do_handshake(struct myri_eth *mp)
{
struct myri_shmem *shmem = mp->shmem;
struct myri_shmem __iomem *shmem = mp->shmem;
void __iomem *cregs = mp->cregs;
struct myri_channel *chan = &shmem->channel;
struct myri_channel __iomem *chan = &shmem->channel;
int tick = 0;
DET(("myri_do_handshake: "));
......@@ -427,7 +427,7 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev)
u32 csum = sbus_readl(&rxdack->csum);
int len = sbus_readl(&rxdack->myri_scatters[0].len);
int index = sbus_readl(&rxdack->ctx);
struct myri_rxd __iomem *rxd = &rq->myri_rxd[rq->tail];
struct myri_rxd __iomem *rxd = &rq->myri_rxd[sbus_readl(&rq->tail)];
struct sk_buff *skb = mp->rx_skbs[index];
/* Ack it. */
......@@ -546,7 +546,7 @@ static irqreturn_t myri_interrupt(int irq, void *dev_id, struct pt_regs *regs)
struct net_device *dev = (struct net_device *) dev_id;
struct myri_eth *mp = (struct myri_eth *) dev->priv;
void __iomem *lregs = mp->lregs;
struct myri_channel *chan = &mp->shmem->channel;
struct myri_channel __iomem *chan = &mp->shmem->channel;
unsigned long flags;
u32 status;
int handled = 0;
......
This diff is collapsed.
......@@ -583,7 +583,7 @@ typedef struct mac_info {
/* tx side stuff */
/* logical pointer of start of each Tx FIFO */
TxFIFO_element_t *tx_FIFO_start[MAX_TX_FIFOS];
TxFIFO_element_t __iomem *tx_FIFO_start[MAX_TX_FIFOS];
/* Current offset within tx_FIFO_start, where driver would write new Tx frame*/
tx_curr_put_info_t tx_curr_put_info[MAX_TX_FIFOS];
......@@ -623,8 +623,8 @@ typedef struct s2io_nic {
macaddr_t pre_mac_addr[MAX_MAC_SUPPORTED];
struct net_device_stats stats;
caddr_t bar0;
caddr_t bar1;
void __iomem *bar0;
void __iomem *bar1;
struct config_param config;
mac_info_t mac_control;
int high_dma_flag;
......@@ -736,10 +736,9 @@ typedef struct s2io_nic {
/* OS related system calls */
#ifndef readq
static inline u64 readq(void *addr)
static inline u64 readq(void __iomem *addr)
{
u64 ret = 0;
ret = readl(addr + 4);
u64 ret = readl(addr + 4);
ret <<= 32;
ret |= readl(addr);
......@@ -748,7 +747,7 @@ static inline u64 readq(void *addr)
#endif
#ifndef writeq
static inline void writeq(u64 val, void *addr)
static inline void writeq(u64 val, void __iomem *addr)
{
writel((u32) (val), addr);
writel((u32) (val >> 32), (addr + 4));
......@@ -762,7 +761,7 @@ static inline void writeq(u64 val, void *addr)
*/
#define UF 1
#define LF 2
static inline void SPECIAL_REG_WRITE(u64 val, void *addr, int order)
static inline void SPECIAL_REG_WRITE(u64 val, void __iomem *addr, int order)
{
if (order == LF) {
writel((u32) (val), addr);
......
......@@ -1051,7 +1051,7 @@ static void set_rx_mode(struct net_device *dev)
else
filterbit = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
filterbit &= 0x3f;
mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
if (tulip_debug > 2) {
printk(KERN_INFO "%s: Added filter for %2.2x:%2.2x:%2.2x:"
"%2.2x:%2.2x:%2.2x %8.8x bit %d.\n", dev->name,
......
......@@ -1410,7 +1410,7 @@ static u32 __set_rx_mode(struct net_device *dev)
i++, mclist = mclist->next) {
int filterbit = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F;
filterbit &= 0x3f;
mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
}
rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
}
......
......@@ -16,11 +16,25 @@
*/
/*
* Changes:
*
* Mark Smith <markzzzsmith@yahoo.com.au>
* Use random_ether_addr() for tap MAC address.
*
* Harald Roelle <harald.roelle@ifi.lmu.de> 2004/04/20
* Fixes in packet dropping, queue length setting and queue wakeup.
* Increased default tx queue length.
* Added ethtool API.
* Minor cleanups
*
* Daniel Podlejski <underley@underley.eu.org>
* Modifications for 2.3.99-pre5 kernel.
*/
#define TUN_VER "1.5"
#define DRV_NAME "tun"
#define DRV_VERSION "1.6"
#define DRV_DESCRIPTION "Universal TUN/TAP device driver"
#define DRV_COPYRIGHT "(C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>"
#include <linux/config.h>
#include <linux/module.h>
......@@ -31,11 +45,11 @@
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/random.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/miscdevice.h>
#include <linux/ethtool.h>
#include <linux/rtnetlink.h>
#include <linux/if.h>
#include <linux/if_arp.h>
......@@ -53,6 +67,7 @@ static int debug;
/* Network device part of the driver */
static LIST_HEAD(tun_dev_list);
static struct ethtool_ops tun_ethtool_ops;
/* Net device open. */
static int tun_net_open(struct net_device *dev)
......@@ -79,18 +94,24 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
if (!tun->attached)
goto drop;
/* Queue packet */
if (!(tun->flags & TUN_ONE_QUEUE)) {
/* Normal queueing mode.
* Packet scheduler handles dropping. */
if (skb_queue_len(&tun->readq) >= TUN_READQ_SIZE)
/* Packet dropping */
if (skb_queue_len(&tun->readq) >= dev->tx_queue_len) {
if (!(tun->flags & TUN_ONE_QUEUE)) {
/* Normal queueing mode. */
/* Packet scheduler handles dropping of further packets. */
netif_stop_queue(dev);
} else {
/* Single queue mode.
* Driver handles dropping itself. */
if (skb_queue_len(&tun->readq) >= dev->tx_queue_len)
/* We won't see all dropped packets individually, so overrun
* error is more appropriate. */
tun->stats.tx_fifo_errors++;
} else {
/* Single queue mode.
* Driver handles dropping of all packets itself. */
goto drop;
}
}
/* Queue packet */
skb_queue_tail(&tun->readq, skb);
/* Notify and wake up reader process */
......@@ -164,18 +185,16 @@ static void tun_net_init(struct net_device *dev)
/* Zero header length */
dev->type = ARPHRD_NONE;
dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
dev->tx_queue_len = 10;
dev->tx_queue_len = TUN_READQ_SIZE; /* We prefer our own queue length */
break;
case TUN_TAP_DEV:
/* Ethernet TAP Device */
dev->set_multicast_list = tun_net_mclist;
/* Generate random Ethernet address. */
*(u16 *)dev->dev_addr = htons(0x00FF);
get_random_bytes(dev->dev_addr + sizeof(u16), 4);
ether_setup(dev);
random_ether_addr(dev->dev_addr);
dev->tx_queue_len = TUN_READQ_SIZE; /* We prefer our own queue length */
break;
}
}
......@@ -354,7 +373,7 @@ static ssize_t tun_chr_readv(struct file *file, const struct iovec *iv,
schedule();
continue;
}
netif_start_queue(tun->dev);
netif_wake_queue(tun->dev);
/** Decide whether to accept this packet. This code is designed to
* behave identically to an Ethernet interface. Accept the packet if
......@@ -418,6 +437,7 @@ static void tun_setup(struct net_device *dev)
dev->hard_start_xmit = tun_net_xmit;
dev->stop = tun_net_close;
dev->get_stats = tun_net_stats;
dev->ethtool_ops = &tun_ethtool_ops;
dev->destructor = free_netdev;
}
......@@ -736,12 +756,97 @@ static struct miscdevice tun_miscdev = {
.devfs_name = "net/tun",
};
/* ethtool interface */
static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
cmd->supported = 0;
cmd->advertising = 0;
cmd->speed = SPEED_10;
cmd->duplex = DUPLEX_FULL;
cmd->port = PORT_TP;
cmd->phy_address = 0;
cmd->transceiver = XCVR_INTERNAL;
cmd->autoneg = AUTONEG_DISABLE;
cmd->maxtxpkt = 0;
cmd->maxrxpkt = 0;
return 0;
}
static void tun_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct tun_struct *tun = netdev_priv(dev);
strcpy(info->driver, DRV_NAME);
strcpy(info->version, DRV_VERSION);
strcpy(info->fw_version, "N/A");
switch (tun->flags & TUN_TYPE_MASK) {
case TUN_TUN_DEV:
strcpy(info->bus_info, "tun");
break;
case TUN_TAP_DEV:
strcpy(info->bus_info, "tap");
break;
}
}
static u32 tun_get_msglevel(struct net_device *dev)
{
#ifdef TUN_DEBUG
struct tun_struct *tun = netdev_priv(dev);
return tun->debug;
#else
return -EOPNOTSUPP;
#endif
}
static void tun_set_msglevel(struct net_device *dev, u32 value)
{
#ifdef TUN_DEBUG
struct tun_struct *tun = netdev_priv(dev);
tun->debug = value;
#endif
}
static u32 tun_get_link(struct net_device *dev)
{
struct tun_struct *tun = netdev_priv(dev);
return tun->attached;
}
static u32 tun_get_rx_csum(struct net_device *dev)
{
struct tun_struct *tun = netdev_priv(dev);
return (tun->flags & TUN_NOCHECKSUM) == 0;
}
static int tun_set_rx_csum(struct net_device *dev, u32 data)
{
struct tun_struct *tun = netdev_priv(dev);
if (data)
tun->flags &= ~TUN_NOCHECKSUM;
else
tun->flags |= TUN_NOCHECKSUM;
return 0;
}
static struct ethtool_ops tun_ethtool_ops = {
.get_settings = tun_get_settings,
.get_drvinfo = tun_get_drvinfo,
.get_msglevel = tun_get_msglevel,
.set_msglevel = tun_set_msglevel,
.get_link = tun_get_link,
.get_rx_csum = tun_get_rx_csum,
.set_rx_csum = tun_set_rx_csum
};
int __init tun_init(void)
{
int ret = 0;
printk(KERN_INFO "Universal TUN/TAP device driver %s "
"(C)1999-2002 Maxim Krasnyansky\n", TUN_VER);
printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT);
ret = misc_register(&tun_miscdev);
if (ret)
......@@ -766,5 +871,7 @@ void tun_cleanup(void)
module_init(tun_init);
module_exit(tun_cleanup);
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_AUTHOR(DRV_COPYRIGHT);
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(TUN_MINOR);
......@@ -56,4 +56,6 @@ $(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist
# Files generated that shall be removed upon make clean
clean-files := devlist.h classlist.h
# Build PCI Express stuff if needed
obj-$(CONFIG_PCIEPORTBUS) += pcie/
......@@ -7,7 +7,7 @@
* configuration space.
*/
static spinlock_t pci_lock = SPIN_LOCK_UNLOCKED;
static DEFINE_SPINLOCK(pci_lock);
/*
* Wrappers for all PCI configuration access functions. They just check
......
......@@ -134,27 +134,6 @@ config HOTPLUG_PCI_CPCI_GENERIC
When in doubt, say N.
config HOTPLUG_PCI_PCIE
tristate "PCI Express Hotplug driver"
depends on HOTPLUG_PCI
help
Say Y here if you have a motherboard that supports PCI Express Native
Hotplug
To compile this driver as a module, choose M here: the
module will be called pciehp.
When in doubt, say N.
config HOTPLUG_PCI_PCIE_POLL_EVENT_MODE
bool "Use polling mechanism for hot-plug events (for testing purpose)"
depends on HOTPLUG_PCI_PCIE
help
Say Y here if you want to use the polling mechanism for hot-plug
events for early platform testing.
When in doubt, say N.
config HOTPLUG_PCI_SHPC
tristate "SHPC PCI Hotplug driver"
depends on HOTPLUG_PCI
......
......@@ -34,6 +34,7 @@
#include <linux/delay.h>
#include <asm/semaphore.h>
#include <asm/io.h>
#include <linux/pcieport_if.h>
#include "pci_hotplug.h"
#define MY_NAME "pciehp"
......@@ -311,7 +312,7 @@ enum php_ctlr_type {
typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id);
int pcie_init(struct controller *ctrl, struct pci_dev *pdev,
int pcie_init(struct controller *ctrl, struct pcie_device *dev,
php_intr_callback_t attention_button_callback,
php_intr_callback_t switch_change_callback,
php_intr_callback_t presence_change_callback,
......
......@@ -40,6 +40,7 @@
#include <asm/uaccess.h>
#include "pciehp.h"
#include "pciehprm.h"
#include <linux/interrupt.h>
/* Global variables */
int pciehp_debug;
......@@ -346,7 +347,7 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
return 0;
}
static int pcie_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_id *id)
{
int rc;
struct controller *ctrl;
......@@ -354,7 +355,9 @@ static int pcie_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int first_device_num = 0 ; /* first PCI device number supported by this PCIE */
int num_ctlr_slots; /* number of slots supported by this HPC */
u8 value;
struct pci_dev *pdev;
dbg("%s: Called by hp_drv\n", __FUNCTION__);
ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
if (!ctrl) {
err("%s : out of memory\n", __FUNCTION__);
......@@ -363,8 +366,10 @@ static int pcie_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
memset(ctrl, 0, sizeof(struct controller));
dbg("%s: DRV_thread pid = %d\n", __FUNCTION__, current->pid);
pdev = dev->port;
rc = pcie_init(ctrl, pdev,
rc = pcie_init(ctrl, dev,
(php_intr_callback_t) pciehp_handle_attention_button,
(php_intr_callback_t) pciehp_handle_switch_change,
(php_intr_callback_t) pciehp_handle_presence_change,
......@@ -562,32 +567,52 @@ static void __exit unload_pciehpd(void)
}
int hpdriver_context = 0;
static struct pci_device_id pcied_pci_tbl[] = {
{
.class = ((PCI_CLASS_BRIDGE_PCI << 8) | 0x00),
.class_mask = ~0,
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(pci, pcied_pci_tbl);
static void pciehp_remove (struct pcie_device *device)
{
printk("%s ENTRY\n", __FUNCTION__);
printk("%s -> Call free_irq for irq = %d\n",
__FUNCTION__, device->irq);
free_irq(device->irq, &hpdriver_context);
}
#ifdef CONFIG_PM
static int pciehp_suspend (struct pcie_device *dev, u32 state)
{
printk("%s ENTRY\n", __FUNCTION__);
return 0;
}
static int pciehp_resume (struct pcie_device *dev)
{
printk("%s ENTRY\n", __FUNCTION__);
return 0;
}
#endif
static struct pci_driver pcie_driver = {
.name = PCIE_MODULE_NAME,
.id_table = pcied_pci_tbl,
.probe = pcie_probe,
/* remove: pcie_remove_one, */
static struct pcie_port_service_id port_pci_ids[] = { {
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
.port_type = PCIE_RC_PORT,
.service_type = PCIE_PORT_SERVICE_HP,
.driver_data = 0,
}, { /* end: all zeroes */ }
};
static const char device_name[] = "hpdriver";
static struct pcie_port_service_driver hpdriver_portdrv = {
.name = (char *)device_name,
.id_table = &port_pci_ids[0],
.probe = pciehp_probe,
.remove = pciehp_remove,
#ifdef CONFIG_PM
.suspend = pciehp_suspend,
.resume = pciehp_resume,
#endif /* PM */
};
static int __init pcied_init(void)
{
......@@ -603,9 +628,11 @@ static int __init pcied_init(void)
retval = pciehprm_init(PCI);
if (!retval) {
retval = pci_register_driver(&pcie_driver);
dbg("pci_register_driver = %d\n", retval);
info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
retval = pcie_port_service_register(&hpdriver_portdrv);
dbg("pcie_port_service_register = %d\n", retval);
info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
if (retval)
dbg("%s: Failure to register service\n", __FUNCTION__);
}
error_hpc_init:
......@@ -625,8 +652,8 @@ static void __exit pcied_cleanup(void)
pciehprm_cleanup();
dbg("pci_unregister_driver\n");
pci_unregister_driver(&pcie_driver);
dbg("pcie_port_service_unregister\n");
pcie_port_service_unregister(&hpdriver_portdrv);
info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
}
......
......@@ -1249,7 +1249,7 @@ static struct hpc_ops pciehp_hpc_ops = {
};
int pcie_init(struct controller * ctrl,
struct pci_dev *pdev,
struct pcie_device *dev,
php_intr_callback_t attention_button_callback,
php_intr_callback_t switch_change_callback,
php_intr_callback_t presence_change_callback,
......@@ -1265,6 +1265,7 @@ int pcie_init(struct controller * ctrl,
u32 slot_cap;
int cap_base, saved_cap_base;
u16 slot_status, slot_ctrl;
struct pci_dev *pdev;
DBG_ENTER_ROUTINE
......@@ -1277,7 +1278,8 @@ int pcie_init(struct controller * ctrl,
}
memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s));
pdev = dev->port;
php_ctlr->pci_dev = pdev; /* save pci_dev in context */
dbg("%s: pdev->vendor %x pdev->device %x\n", __FUNCTION__,
......@@ -1338,7 +1340,7 @@ int pcie_init(struct controller * ctrl,
}
dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number,
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev->irq);
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
if (pci_resource_len(pdev, rc) > 0)
dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc,
......@@ -1355,7 +1357,7 @@ int pcie_init(struct controller * ctrl,
init_waitqueue_head(&ctrl->queue);
/* find the IRQ */
php_ctlr->irq = pdev->irq;
php_ctlr->irq = dev->irq;
dbg("HPC interrupt = %d\n", php_ctlr->irq);
/* Save interrupt callback info */
......@@ -1407,17 +1409,6 @@ int pcie_init(struct controller * ctrl,
start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */
} else {
/* Installs the interrupt handler */
dbg("%s: pcie_mch_quirk = %x\n", __FUNCTION__, pcie_mch_quirk);
if (!pcie_mch_quirk) {
rc = pci_enable_msi(pdev);
if (rc) {
info("Can't get msi for the hotplug controller\n");
info("Use INTx for the hotplug controller\n");
dbg("%s: rc = %x\n", __FUNCTION__, rc);
} else
php_ctlr->irq = pdev->irq;
}
rc = request_irq(php_ctlr->irq, pcie_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
if (rc) {
......
......@@ -22,7 +22,7 @@
#include "msi.h"
static spinlock_t msi_lock = SPIN_LOCK_UNLOCKED;
static DEFINE_SPINLOCK(msi_lock);
static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
static kmem_cache_t* msi_cachep;
......@@ -374,19 +374,18 @@ static int msi_init(void)
if ((status = msi_cache_init()) < 0) {
pci_msi_enable = 0;
printk(KERN_INFO "WARNING: MSI INIT FAILURE\n");
printk(KERN_WARNING "PCI: MSI cache init failed\n");
return status;
}
last_alloc_vector = assign_irq_vector(AUTO_ASSIGN);
if (last_alloc_vector < 0) {
pci_msi_enable = 0;
printk(KERN_INFO "WARNING: ALL VECTORS ARE BUSY\n");
printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n");
status = -EBUSY;
return status;
}
vector_irq[last_alloc_vector] = 0;
nr_released_vectors++;
printk(KERN_INFO "MSI INIT SUCCESS\n");
return status;
}
......@@ -736,7 +735,9 @@ int pci_enable_msi(struct pci_dev* dev)
/* Check whether driver already requested for MSI-X vectors */
if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 &&
!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
printk(KERN_INFO "Can't enable MSI. Device already had MSI-X vectors assigned\n");
printk(KERN_INFO "PCI: %s: Can't enable MSI. "
"Device already has MSI-X vectors assigned\n",
pci_name(dev));
dev->irq = temp;
return -EINVAL;
}
......@@ -774,9 +775,9 @@ void pci_disable_msi(struct pci_dev* dev)
}
if (entry->msi_attrib.state) {
spin_unlock_irqrestore(&msi_lock, flags);
printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on vector->%d\n",
dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
dev->irq);
printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without "
"free_irq() on MSI vector %d\n",
pci_name(dev), dev->irq);
BUG_ON(entry->msi_attrib.state > 0);
} else {
vector_irq[dev->irq] = 0; /* free it */
......@@ -982,7 +983,9 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
/* Check whether driver already requested for MSI vector */
if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 &&
!msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
printk(KERN_INFO "Can't enable MSI-X. Device already had MSI vector assigned\n");
printk(KERN_INFO "PCI: %s: Can't enable MSI-X. "
"Device already has an MSI vector assigned\n",
pci_name(dev));
dev->irq = temp;
return -EINVAL;
}
......@@ -1050,9 +1053,9 @@ void pci_disable_msix(struct pci_dev* dev)
spin_unlock_irqrestore(&msi_lock, flags);
if (warning) {
dev->irq = temp;
printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on all vectors\n",
dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn));
printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
"free_irq() on all MSI-X vectors\n",
pci_name(dev));
BUG_ON(warning > 0);
} else {
dev->irq = temp;
......@@ -1088,9 +1091,9 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
state = msi_desc[dev->irq]->msi_attrib.state;
spin_unlock_irqrestore(&msi_lock, flags);
if (state) {
printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on vector->%d\n",
dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), dev->irq);
printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
"called without free_irq() on MSI vector %d\n",
pci_name(dev), dev->irq);
BUG_ON(state > 0);
} else /* Release MSI vector assigned to this device */
msi_free_vector(dev, dev->irq, 0);
......@@ -1132,9 +1135,9 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
iounmap(base);
release_mem_region(phys_addr, PCI_MSIX_ENTRY_SIZE *
multi_msix_capable(control));
printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on all vectors\n",
dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn));
printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
"called without free_irq() on all MSI-X vectors\n",
pci_name(dev));
BUG_ON(warning > 0);
}
dev->irq = temp; /* Restore IOAPIC IRQ */
......
......@@ -269,7 +269,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
if ((pmc & PCI_PM_CAP_VER_MASK) != 2) {
printk(KERN_WARNING
printk(KERN_DEBUG
"PCI: %s has unsupported PM cap regs version (%u)\n",
dev->slot_name, pmc & PCI_PM_CAP_VER_MASK);
return -EIO;
......
......@@ -59,12 +59,14 @@ struct pci_visit {
extern int pci_visit_dev(struct pci_visit *fn,
struct pci_dev_wrapped *wrapped_dev,
struct pci_bus_wrapped *wrapped_parent);
extern void pci_remove_legacy_files(struct pci_bus *bus);
/* Lock for read/write access to pci device and bus lists */
extern spinlock_t pci_bus_lock;
extern int pcie_mch_quirk;
extern struct device_attribute pci_dev_attrs[];
extern struct class_device_attribute class_device_attr_cpuaffinity;
/**
* pci_match_one_device - Tell if a PCI device structure has a matching
......
#
# PCI Express Port Bus Configuration
#
config PCIEPORTBUS
bool "PCI Express support"
depends on PCI_GOMMCONFIG || PCI_GOANY
default n
---help---
This automatically enables PCI Express Port Bus support. Users can
choose Native Hot-Plug support, Advanced Error Reporting support,
Power Management Event support and Virtual Channel support to run
on PCI Express Ports (Root or Switch).
#
# Include service Kconfig here
#
config HOTPLUG_PCI_PCIE
tristate "PCI Express Hotplug driver"
depends on HOTPLUG_PCI && PCIEPORTBUS
help
Say Y here if you have a motherboard that supports PCI Express Native
Hotplug
To compile this driver as a module, choose M here: the
module will be called pciehp.
When in doubt, say N.
config HOTPLUG_PCI_PCIE_POLL_EVENT_MODE
bool "Use polling mechanism for hot-plug events (for testing purpose)"
depends on HOTPLUG_PCI_PCIE
help
Say Y here if you want to use the polling mechanism for hot-plug
events for early platform testing.
When in doubt, say N.
#
# Makefile for PCI-Express PORT Driver
#
pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o
obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o
/*
* File: portdrv.h
* Purpose: PCI Express Port Bus Driver's Internal Data Structures
*
* Copyright (C) 2004 Intel
* Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
*/
#ifndef _PORTDRV_H_
#define _PORTDRV_H_
#if !defined(PCI_CAP_ID_PME)
#define PCI_CAP_ID_PME 1
#endif
#if !defined(PCI_CAP_ID_EXP)
#define PCI_CAP_ID_EXP 0x10
#endif
#define PORT_TYPE_MASK 0xf
#define PORT_TO_SLOT_MASK 0x100
#define SLOT_HP_CAPABLE_MASK 0x40
#define PCIE_CAPABILITIES_REG 0x2
#define PCIE_SLOT_CAPABILITIES_REG 0x14
#define PCIE_PORT_DEVICE_MAXSERVICES 4
#define PCI_CFG_SPACE_SIZE 256
#define get_descriptor_id(type, service) (((type - 4) << 4) | service)
extern struct bus_type pcie_port_bus_type;
extern struct device_driver pcieport_generic_driver;
extern int pcie_port_device_probe(struct pci_dev *dev);
extern int pcie_port_device_register(struct pci_dev *dev);
#ifdef CONFIG_PM
extern int pcie_port_device_suspend(struct pcie_device *dev, u32 state);
extern int pcie_port_device_resume(struct pcie_device *dev);
#endif
extern void pcie_port_device_remove(struct pcie_device *dev);
extern void pcie_port_bus_register(void);
extern void pcie_port_bus_unregister(void);
#endif /* _PORTDRV_H_ */
/*
* File: portdrv_bus.c
* Purpose: PCI Express Port Bus Driver's Bus Overloading Functions
*
* Copyright (C) 2004 Intel
* Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/pm.h>
#include <linux/pcieport_if.h>
static int generic_probe (struct device *dev) { return 0;}
static int generic_remove (struct device *dev) { return 0;}
static int pcie_port_bus_match(struct device *dev, struct device_driver *drv);
static int pcie_port_bus_suspend(struct device *dev, u32 state);
static int pcie_port_bus_resume(struct device *dev);
struct bus_type pcie_port_bus_type = {
.name = "pci_express",
.match = pcie_port_bus_match,
.suspend = pcie_port_bus_suspend,
.resume = pcie_port_bus_resume,
};
struct device_driver pcieport_generic_driver = {
.name = "pcieport",
.bus = &pcie_port_bus_type,
.probe = generic_probe,
.remove = generic_remove,
};
static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
{
struct pcie_device *pciedev;
struct pcie_port_service_driver *driver;
if ( drv->bus != &pcie_port_bus_type ||
dev->bus != &pcie_port_bus_type ||
drv == &pcieport_generic_driver) {
return 0;
}
pciedev = to_pcie_device(dev);
driver = to_service_driver(drv);
if ( (driver->id_table->vendor != PCI_ANY_ID &&
driver->id_table->vendor != pciedev->id.vendor) ||
(driver->id_table->device != PCI_ANY_ID &&
driver->id_table->device != pciedev->id.device) ||
driver->id_table->port_type != pciedev->id.port_type ||
driver->id_table->service_type != pciedev->id.service_type )
return 0;
return 1;
}
static int pcie_port_bus_suspend(struct device *dev, u32 state)
{
struct pcie_device *pciedev;
struct pcie_port_service_driver *driver;
if (!dev || !dev->driver)
return 0;
pciedev = to_pcie_device(dev);
driver = to_service_driver(dev->driver);
if (driver && driver->suspend)
driver->suspend(pciedev, state);
return 0;
}
static int pcie_port_bus_resume(struct device *dev)
{
struct pcie_device *pciedev;
struct pcie_port_service_driver *driver;
if (!dev || !dev->driver)
return 0;
pciedev = to_pcie_device(dev);
driver = to_service_driver(dev->driver);
if (driver && driver->resume)
driver->resume(pciedev);
return 0;
}
This diff is collapsed.
This diff is collapsed.
......@@ -62,7 +62,7 @@ static void pci_create_legacy_files(struct pci_bus *b)
}
}
static void pci_remove_legacy_files(struct pci_bus *b)
void pci_remove_legacy_files(struct pci_bus *b)
{
class_device_remove_bin_file(&b->class_dev, b->legacy_io);
class_device_remove_bin_file(&b->class_dev, b->legacy_mem);
......@@ -70,7 +70,7 @@ static void pci_remove_legacy_files(struct pci_bus *b)
}
#else /* !HAVE_PCI_LEGACY */
static inline void pci_create_legacy_files(struct pci_bus *bus) { return; }
static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; }
void pci_remove_legacy_files(struct pci_bus *bus) { return; }
#endif /* HAVE_PCI_LEGACY */
/*
......@@ -86,7 +86,7 @@ static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev, char *bu
buf[ret++] = '\n';
return ret;
}
static CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL);
CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL);
/*
* PCI Bus Class
......@@ -95,10 +95,6 @@ static void release_pcibus_dev(struct class_device *class_dev)
{
struct pci_bus *pci_bus = to_pci_bus(class_dev);
pci_remove_legacy_files(pci_bus);
class_device_remove_file(&pci_bus->class_dev,
&class_device_attr_cpuaffinity);
sysfs_remove_link(&pci_bus->class_dev.kobj, "bridge");
if (pci_bus->bridge)
put_device(pci_bus->bridge);
kfree(pci_bus);
......
......@@ -61,15 +61,18 @@ int pci_remove_device_safe(struct pci_dev *dev)
}
EXPORT_SYMBOL(pci_remove_device_safe);
void pci_remove_bus(struct pci_bus *b)
void pci_remove_bus(struct pci_bus *pci_bus)
{
pci_proc_detach_bus(b);
pci_proc_detach_bus(pci_bus);
spin_lock(&pci_bus_lock);
list_del(&b->node);
list_del(&pci_bus->node);
spin_unlock(&pci_bus_lock);
class_device_unregister(&b->class_dev);
pci_remove_legacy_files(pci_bus);
class_device_remove_file(&pci_bus->class_dev,
&class_device_attr_cpuaffinity);
sysfs_remove_link(&pci_bus->class_dev.kobj, "bridge");
class_device_unregister(&pci_bus->class_dev);
}
EXPORT_SYMBOL(pci_remove_bus);
......
This diff is collapsed.
......@@ -13,7 +13,7 @@
#include <linux/interrupt.h>
#include "pci.h"
spinlock_t pci_bus_lock = SPIN_LOCK_UNLOCKED;
DEFINE_SPINLOCK(pci_bus_lock);
static struct pci_bus * __devinit
pci_do_find_bus(struct pci_bus* bus, unsigned char busnr)
......
......@@ -59,6 +59,7 @@ obj-$(CONFIG_USB_AUERSWALD) += misc/
obj-$(CONFIG_USB_CYTHERM) += misc/
obj-$(CONFIG_USB_EMI26) += misc/
obj-$(CONFIG_USB_EMI62) += misc/
obj-$(CONFIG_USB_IDMOUSE) += misc/
obj-$(CONFIG_USB_LCD) += misc/
obj-$(CONFIG_USB_LED) += misc/
obj-$(CONFIG_USB_LEGOTOWER) += misc/
......
This diff is collapsed.
......@@ -1096,7 +1096,7 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
usblp->writebuf, 0,
usblp_bulk_write, usblp);
usblp->bidir = (usblp->protocol[protocol].epread != 0);
usblp->bidir = (usblp->protocol[protocol].epread != NULL);
if (usblp->bidir)
usb_fill_bulk_urb(usblp->readurb, usblp->dev,
usb_rcvbulkpipe(usblp->dev,
......
This diff is collapsed.
......@@ -30,7 +30,7 @@
#define MAX_USB_MINORS 256
static struct file_operations *usb_minors[MAX_USB_MINORS];
static spinlock_t minor_lock = SPIN_LOCK_UNLOCKED;
static DEFINE_SPINLOCK(minor_lock);
static int usb_open(struct inode * inode, struct file * file)
{
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment