Commit 2b9fa51a authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-scsi.bkbits.net/scsi-for-linus-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents fd0a1c61 5dd17103
......@@ -39,7 +39,7 @@ S: Ireland
N: Tigran A. Aivazian
E: tigran@veritas.com
W: http://www.ocston.org/~tigran
W: http://www.moses.uklinux.net/patches
D: BFS filesystem
D: Intel IA32 CPU microcode update support
D: Various kernel patches
......
......@@ -55,7 +55,7 @@ o util-linux 2.10o # fdformat --version
o modutils 2.4.2 # insmod -V
o e2fsprogs 1.25 # tune2fs
o jfsutils 1.0.14 # fsck.jfs -V
o reiserfsprogs 3.x.1b # reiserfsck 2>&1|grep reiserfsprogs
o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs
o xfsprogs 2.1.0 # xfs_db -V
o pcmcia-cs 3.1.21 # cardmgr -V
o PPP 2.4.0 # pppd --version
......@@ -229,7 +229,6 @@ If you are running v0.1.17 or earlier, you should upgrade to
version v0.99.0 or higher. Running old versions may cause problems
with programs using shared memory.
Networking
==========
......@@ -326,7 +325,7 @@ o <http://oss.software.ibm.com/jfs>
Reiserfsprogs
-------------
o <ftp://ftp.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.x.1b.tar.gz>
o <http://www.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.6.3.tar.gz>
Xfsprogs
--------
......
......@@ -323,8 +323,8 @@ and its mirrors.
The 1.06 revision can be found in kernel version later than 2.3.15 and pre-2.2.14,
and 1.07 revision can be found in kernel version 2.4.0.
If you have no prior experience in networking under Linux, please read
<ULink URL="http://www.linuxdoc.org/">Ethernet HOWTO</ULink> and
<ULink URL="http://www.linuxdoc.org/">Networking HOWTO</ULink> available from
<ULink URL="http://www.tldp.org/">Ethernet HOWTO</ULink> and
<ULink URL="http://www.tldp.org/">Networking HOWTO</ULink> available from
Linux Documentation Project (LDP).
</Para>
......@@ -435,7 +435,7 @@ netmask respectively. TYPE is used to set medium type used by the device.
Typical values are "10baseT"(twisted-pair 10Mbps Ethernet) or "100baseT"
(twisted-pair 100Mbps Ethernet). For more information on how to configure
network interface, please refer to
<ULink URL="http://www.linuxdoc.org/">Networking HOWTO</ULink>.
<ULink URL="http://www.tldp.org/">Networking HOWTO</ULink>.
</Para>
<Para>
......
......@@ -29,3 +29,10 @@ Mount options unique to the isofs filesystem.
unhide Show hidden files.
session=x Select number of session on multisession CD
sbsector=xxx Session begins from sector xxx
Recommended documents about ISO 9660 standard are located at:
http://www.y-adagio.com/public/standards/iso_cdromr/tocont.htm
ftp://ftp.ecma.ch/ecma-st/Ecma-119.pdf
Quoting from the PDF "This 2nd Edition of Standard ECMA-119 is technically
identical with ISO 9660.", so it is a valid and gratis substitute of the
official ISO specification.
......@@ -41,7 +41,7 @@
* Title: "The Linux Kernel"
Author: David A. Rusling.
URL: http://www.linuxdoc.org/LDP/tlk/tlk.html
URL: http://www.tldp.org/LDP/tlk/tlk.html
Keywords: everything!, book.
Description: On line, 200 pages book describing most aspects of
the Linux Kernel. Probably, the first reference for beginners.
......@@ -57,7 +57,7 @@
* Title: "The Linux Kernel Hackers' Guide"
Author: Michael K.Johnson and others.
URL: http://www.linuxdoc.org/LDP/khg/HyperNews/get/khg.html
URL: http://www.tldp.org/LDP/khg/HyperNews/get/khg.html
Keywords: everything!
Description: No more Postscript book-like version. Only HTML now.
Many people have contributed. The interface is similar to web
......@@ -277,7 +277,7 @@
* Title: "Linux Kernel Module Programming Guide"
Author: Ori Pomerantz.
URL: http://www.linuxdoc.org/LDP/lkmpg/mpg.html
URL: http://www.tldp.org/LDP/lkmpg/mpg.html
Keywords: modules, GPL book, /proc, ioctls, system calls,
interrupt handlers .
Description: Very nice 92 pages GPL book on the topic of modules
......
......@@ -44,6 +44,10 @@ dgrs.txt
- the Digi International RightSwitch SE-X Ethernet driver
dmfe.txt
- info on the Davicom DM9102(A)/DM9132/DM9801 fast ethernet driver.
e100.txt
- info on Intel's EtherExpress PRO/100 line of 10/100 boards
e1000.txt
- info on Intel's E1000 line of gigabit ethernet boards
eql.txt
- serial IP load balancing
ethertap.txt
......
......@@ -89,7 +89,7 @@ tcp_keepalive_intvl - INTEGER
tcp_retries1 - INTEGER
How many times to retry before deciding that something is wrong
and it is necessary to report this suspection to network layer.
and it is necessary to report this suspicion to network layer.
Minimal RFC value is 3, it is default, which corresponds
to ~3sec-8min depending on RTO.
......@@ -200,7 +200,7 @@ tcp_sack - BOOLEAN
Enable select acknowledgments (SACKS).
tcp_fack - BOOLEAN
Enable FACK congestion avoidance and fast restransmission.
Enable FACK congestion avoidance and fast retransmission.
The value is not used, if tcp_sack is not enabled.
tcp_dsack - BOOLEAN
......@@ -256,7 +256,7 @@ tcp_mem - vector of 3 INTEGERs: min, pressure, max
pressure: when amount of memory allocated by TCP exceeds this number
of pages, TCP moderates its memory consumption and enters memory
pressure mode, which is exited when memory consumtion falls
pressure mode, which is exited when memory consumption falls
under "low".
high: number of pages allowed for queueing by all TCP sockets.
......@@ -278,7 +278,7 @@ tcp_adv_win_scale - INTEGER
tcp_rfc1337 - BOOLEAN
If set, the TCP stack behaves conforming to RFC1337. If unset,
we are not conforming to RFC, but prevent TCP TIME_WAIT
asassination.
assassination.
Default: 0
ip_local_port_range - 2 INTEGERS
......@@ -295,7 +295,7 @@ ip_local_port_range - 2 INTEGERS
2000 connections per second to systems supporting timestamps.
ip_nonlocal_bind - BOOLEAN
If set, allows processes to bind() to non-local IP adresses,
If set, allows processes to bind() to non-local IP addresses,
which can be quite useful - but may break some applications.
Default: 0
......
......@@ -238,7 +238,7 @@ they go to 64 Bit.
On 390 our limitations & strengths make us slightly different.
For backward compatibility ( because of the psw address hi bit which
indicates whether we are in 31 or 24 bit mode ) we are only allowed
indicates whether we are in 31 or 64 bit mode ) we are only allowed
use 31 bits (2GB) of our 32 bit addresses. However,
we use entirely separate address spaces for the user & kernel.
......
......@@ -30,7 +30,7 @@ Sg driver documentation
=======================
The most recent documentation of the sg driver is kept at the Linux
Documentation Project's (LDP) site:
http://www.linuxdoc.org/HOWTO/SCSI-Generic-HOWTO
http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO
This describes the sg version 3 driver found in the lk 2.4 series.
The LDP renders documents in single and multiple page HTML, postscript
and pdf. This document can also be found at:
......@@ -51,7 +51,7 @@ in /usr/include/scsi/sg.h . Driver debugging information and other notes
can be found at the top of the /usr/src/linux/drivers/scsi/sg.c file.
A more general description of the Linux SCSI subsystem of which sg is a
part can be found at http://www.linuxdoc.org/HOWTO/SCSI-2.4-HOWTO .
part can be found at http://www.tldp.org/HOWTO/SCSI-2.4-HOWTO .
Example code and utilities
......
......@@ -2,7 +2,7 @@ SCSI subsystem documentation
============================
The Linux Documentation Project (LDP) maintains a document describing
the SCSI subsystem in the Linux kernel (lk) 2.4 series. See:
http://www.linuxdoc.org/HOWTO/SCSI-2.4-HOWTO . The LDP has single
http://www.tldp.org/HOWTO/SCSI-2.4-HOWTO . The LDP has single
and multiple page HTML renderings as well as postscript and pdf.
It can also be found at http://www.torque.net/scsi/SCSI-2.4-HOWTO .
......
......@@ -71,7 +71,7 @@ CONFIG_SOUND
interrupt and DMA channel), because you will be asked for it.
You want to read the Sound-HOWTO, available from
http://www.linuxdoc.org/docs.html#howto . General information
http://www.tldp.org/docs.html#howto . General information
about the modular sound system is contained in the files
Documentation/sound/Introduction. The file
Documentation/sound/README.OSS contains some slightly outdated but
......
......@@ -552,7 +552,7 @@ S: Maintained
EMU10K1 SOUND DRIVER
P: Rui Sousa
M: rui.p.m.sousa@clix.pt
L: emu10k1-devel@opensource.creative.com
L: emu10k1-devel@lists.sourceforge.net
W: http://opensource.creative.com/
S: Maintained
......@@ -575,14 +575,12 @@ M: miku@iki.fi
S: Maintained
EXT2 FILE SYSTEM
P: Remy Card
M: Remy.Card@linux.org
L: linux-kernel@vger.kernel.org
L: ext2-devel@lists.sourceforge.net
S: Maintained
EXT3 FILE SYSTEM
P: Remy Card, Stephen Tweedie
M: sct@redhat.com, akpm@zip.com.au, adilger@turbolinux.com
P: Stephen Tweedie, Andrew Morton
M: sct@redhat.com, akpm@zip.com.au, adilger@clusterfs.com
L: ext3-users@redhat.com
S: Maintained
......@@ -708,7 +706,7 @@ S: Maintained
i386 BOOT CODE
P: Riley H. Williams
M: rhw@memalpha.cx
M: Riley@Williams.Name
L: Linux-Kernel@vger.kernel.org
S: Maintained
......@@ -741,7 +739,7 @@ S: Maintained
IBM ServeRAID RAID DRIVER
P: Jack Hammer
P: Dave Jeffrey
M: ipslinux@us.ibm.com
M: ipslinux@adaptec.com
W: http://www.developer.ibm.com/welcome/netfinity/serveraid.html
S: Supported
......@@ -839,7 +837,7 @@ S: Maintained
IOC3 DRIVER
P: Ralf Baechle
M: ralf@oss.sgi.com
L: linux-mips@oss.sgi.com
L: linux-mips@linux-mips.org
S: Maintained
IP MASQUERADING:
......@@ -1052,7 +1050,7 @@ MIPS
P: Ralf Baechle
M: ralf@gnu.org
W: http://oss.sgi.com/mips/mips-howto.html
L: linux-mips@oss.sgi.com
L: linux-mips@linux-mips.org
S: Maintained
MISCELLANEOUS MCA-SUPPORT
......
......@@ -335,6 +335,16 @@ hex 'Compressed ROM boot loader BSS address' CONFIG_ZBOOT_ROM_BSS 0
if [ "$CONFIG_ARCH_SA1100" = "y" -o \
"$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
dep_bool 'Support CPU clock change (EXPERIMENTAL)' CONFIG_CPU_FREQ $CONFIG_EXPERIMENTAL
else
define_bool CONFIG_CPU_FREQ n
fi
if [ "$CONFIG_CPU_FREQ" = "y" ]; then
define_bool CONFIG_CPU_FREQ_24_API y
define_bool CONFIG_CPU_FREQ_26_API y
else
define_bool CONFIG_CPU_FREQ_24_API n
define_bool CONFIG_CPU_FREQ_26_API n
fi
source drivers/pci/Config.in
......
......@@ -95,13 +95,14 @@ static void __init build_tag_list(struct param_struct *params, void *taglist)
{
struct tag *tag = taglist;
printk(KERN_DEBUG "Converting old-style param struct to taglist\n");
if (params->u1.s.page_size != PAGE_SIZE) {
printk(KERN_WARNING "Warning: bad configuration page, "
"trying to continue\n");
return;
}
printk(KERN_DEBUG "Converting old-style param struct to taglist\n");
#ifdef CONFIG_ARCH_NETWINDER
if (params->u1.s.nr_pages != 0x02000 &&
params->u1.s.nr_pages != 0x04000 &&
......
......@@ -569,7 +569,7 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *)
* On a shared IRQ the caller must ensure the interrupt is disabled
* on the card it drives before calling this function.
*
* This function may be called from interrupt context.
* This function must not be called from interrupt context.
*/
void free_irq(unsigned int irq, void *dev_id)
{
......@@ -591,15 +591,19 @@ void free_irq(unsigned int irq, void *dev_id)
/* Found it - now free it */
*p = action->next;
kfree(action);
goto out;
break;
}
spin_unlock_irqrestore(&irq_controller_lock, flags);
if (!action) {
printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
#ifdef CONFIG_DEBUG_ERRORS
__backtrace();
#endif
out:
spin_unlock_irqrestore(&irq_controller_lock, flags);
} else {
synchronize_irq(irq);
kfree(action);
}
}
/* Start the interrupt probing. Unlike other architectures,
......
......@@ -28,7 +28,6 @@
#include <asm/mach/serial_sa1100.h>
#include "generic.h"
#include "sa1111.h"
static int __init adsbitsy_init(void)
{
......@@ -53,7 +52,7 @@ static int __init adsbitsy_init(void)
/*
* Probe for SA1111.
*/
ret = sa1111_init(NULL, 0x18000000, IRQ_GPIO0);
ret = sa1111_init(0x18000000, IRQ_GPIO0);
if (ret < 0)
return ret;
......
......@@ -32,7 +32,6 @@
#include <asm/mach/serial_sa1100.h>
#include "generic.h"
#include "sa1111.h"
static int __init badge4_sa1111_init(void)
{
......@@ -45,7 +44,7 @@ static int __init badge4_sa1111_init(void)
/*
* Probe for SA1111.
*/
return sa1111_init(NULL, BADGE4_SA1111_BASE, BADGE4_IRQ_GPIO_SA1111);
return sa1111_init(BADGE4_SA1111_BASE, BADGE4_IRQ_GPIO_SA1111);
}
static int __init badge4_init(void)
......
......@@ -90,9 +90,7 @@
#include <asm/hardware.h>
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
extern unsigned int sa11x0_validatespeed(unsigned int cpu, unsigned int khz);
extern unsigned int sa11x0_getspeed(void);
#include "generic.h"
typedef struct {
int speed;
......@@ -107,7 +105,7 @@ typedef struct {
static sa1100_dram_regs_t sa1100_dram_settings[] =
{
/* { mdcnfg, mdcas0, mdcas1, mdcas2 } */ /* clock frequency */
/* speed, mdcnfg, mdcas0, mdcas1, mdcas2 clock frequency */
{ 59000, 0x00dc88a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 59.0 MHz */
{ 73700, 0x011490a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 73.7 MHz */
{ 88500, 0x014e90a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 88.5 MHz */
......@@ -127,28 +125,25 @@ static sa1100_dram_regs_t sa1100_dram_settings[] =
{ 0, 0, 0, 0, 0 } /* last entry */
};
static void sa1100_update_dram_timings(int current_speed, int new_speed)
{
sa1100_dram_regs_t *settings = sa1100_dram_settings;
/* find speed */
while(settings->speed != 0) {
while (settings->speed != 0) {
if(new_speed == settings->speed)
break;
settings++;
}
if(settings->speed == 0) {
if (settings->speed == 0) {
panic("%s: couldn't find dram setting for speed %d\n",
__FUNCTION__, new_speed);
}
/* No risk, no fun: run with interrupts on! */
if(new_speed > current_speed) {
if (new_speed > current_speed) {
/* We're going FASTER, so first relax the memory
* timings before changing the core frequency
*/
......@@ -181,60 +176,39 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed)
}
}
static int sa1100_dram_notifier(struct notifier_block *nb,
unsigned long val, void *data)
static void sa1100_setspeed(struct cpufreq_policy *policy)
{
struct cpufreq_freqs *ci = data;
switch(val) {
case CPUFREQ_MINMAX:
cpufreq_updateminmax(data, sa1100_dram_settings->speed, -1);
break;
case CPUFREQ_PRECHANGE:
if(ci->new > ci->cur)
sa1100_update_dram_timings(ci->cur, ci->new);
break;
unsigned int cur = sa11x0_getspeed();
struct cpufreq_freqs freqs;
case CPUFREQ_POSTCHANGE:
if(ci->new < ci->cur)
sa1100_update_dram_timings(ci->cur, ci->new);
break;
default:
printk(KERN_INFO "%s: ignoring unknown notifier type (%ld)\n",
__FUNCTION__, val);
}
return 0;
}
freqs.old = cur;
freqs.new = policy->max;
freqs.cpu = CPUFREQ_ALL_CPUS;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
if (policy->max > cur)
sa1100_update_dram_timings(cur, policy->max);
PPCR = sa11x0_freq_to_ppcr(policy->max);
static struct notifier_block sa1100_dram_block = {
.notifier_call = sa1100_dram_notifier,
};
if (policy->max < cur)
sa1100_update_dram_timings(cur, policy->max);
static void sa1100_setspeed(unsigned int cpu, unsigned int khz)
{
PPCR = sa11x0_freq_to_ppcr(khz);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
}
static struct cpufreq_freqs sa1100_freqs = {
.min = 59000,
.max = 287000,
static struct cpufreq_policy sa1100_policy = {
.cpu = 0,
.policy = CPUFREQ_POLICY_POWERSAVE,
.max_cpu_freq = 287000,
};
static struct cpufreq_driver sa1100_driver = {
.freq = &sa1100_freqs,
.validate = sa11x0_validatespeed,
.setspeed = sa1100_setspeed,
.sync = 1,
.verify = sa11x0_verify_speed,
.setpolicy = sa1100_setspeed,
.policy = &sa1100_policy,
.cpu_min_freq = 59000,
};
static int __init sa1100_dram_init(void)
......@@ -242,11 +216,9 @@ static int __init sa1100_dram_init(void)
int ret = -ENODEV;
if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) {
ret = cpufreq_register_notifier(&sa1100_dram_block);
if (ret)
return ret;
sa1100_freqs.cur = sa11x0_getspeed();
sa1100_driver.cpu_curr_freq[0] =
sa1100_policy.min =
sa1100_policy.max = sa11x0_getspeed();
ret = cpufreq_register(&sa1100_driver);
}
......
......@@ -28,11 +28,9 @@
#include <asm/io.h>
#include <asm/system.h>
#undef DEBUG
#include "generic.h"
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
extern unsigned int sa11x0_validatespeed(unsigned int cpu, unsigned int khz);
extern unsigned int sa11x0_getspeed(void);
#undef DEBUG
struct sdram_params {
u_char rows; /* bits */
......@@ -214,15 +212,16 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
* above, we can match for an exact frequency. If we don't find
* an exact match, we will to set the lowest frequency to be safe.
*/
static void sa1110_setspeed(unsigned int cpu, unsigned int khz)
static void sa1110_setspeed(struct cpufreq_policy *policy)
{
struct sdram_params *sdram = &sdram_params;
struct cpufreq_freqs freqs;
struct sdram_info sd;
unsigned long flags;
unsigned int ppcr, unused;
ppcr = sa11x0_freq_to_ppcr(khz);
sdram_calculate_timing(&sd, khz, sdram);
ppcr = sa11x0_freq_to_ppcr(policy->max);
sdram_calculate_timing(&sd, policy->max, sdram);
#if 0
/*
......@@ -230,7 +229,7 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz)
* and errata, but they seem to work. Need to get a storage
* scope on to the SDRAM signals to work out why.
*/
if (khz < 147500) {
if (policy->max < 147500) {
sd.mdrefr |= MDREFR_K1DB2;
sd.mdcas[0] = 0xaaaaaa7f;
} else {
......@@ -240,6 +239,13 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz)
sd.mdcas[1] = 0xaaaaaaaa;
sd.mdcas[2] = 0xaaaaaaaa;
#endif
freqs.old = sa11x0_getspeed();
freqs.new = policy->max;
freqs.cpu = CPUFREQ_ALL_CPUS;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
/*
* The clock could be going away for some time. Set the SDRAMs
* to refresh rapidly (every 64 memory clock cycles). To get
......@@ -257,7 +263,7 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz)
* the programming.
*/
local_irq_save(flags);
asm("mcr p15, 0, %0, c10, c4" : : "r" (0));
asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
udelay(10);
__asm__ __volatile__("
b 2f
......@@ -282,19 +288,22 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz)
/*
* Now, return the SDRAM refresh back to normal.
*/
sdram_update_refresh(khz, sdram);
sdram_update_refresh(policy->max, sdram);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
}
static struct cpufreq_freqs sa1110_freqs = {
.min = 59000,
.max = 287000,
static struct cpufreq_policy sa1110_policy = {
.cpu = 0,
.policy = CPUFREQ_POLICY_POWERSAVE,
.max_cpu_freq = 287000,
};
static struct cpufreq_driver sa1110_driver = {
.freq = &sa1110_freqs,
.validate = sa11x0_validatespeed,
.setspeed = sa1110_setspeed,
.sync = 1,
.verify = sa11x0_verify_speed,
.setpolicy = sa1110_setspeed,
.policy = &sa1110_policy,
.cpu_min_freq = 59000,
};
static int __init sa1110_clk_init(void)
......@@ -318,8 +327,11 @@ static int __init sa1110_clk_init(void)
memcpy(&sdram_params, sdram, sizeof(sdram_params));
sa1110_freqs.cur = sa11x0_getspeed();
sa1110_setspeed(0, sa1110_freqs.cur);
sa1110_driver.cpu_cur_freq[0] =
sa1110_policy.min =
sa1110_policy.max = sa11x0_getspeed();
sa1110_setspeed(&sa1110_policy);
return cpufreq_register(&sa1110_driver);
}
......
......@@ -55,20 +55,26 @@ unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
khz /= 100;
for (i = NR_FREQS - 1; i > 0; i--)
if (cclk_frequency_100khz[i] <= khz)
for (i = 0; i < ARRAY_SIZE(cclk_frequency_100khz); i--)
if (cclk_frequency_100khz[i] >= khz)
break;
return i;
}
/*
* Validate the speed in khz. If we can't generate the precise
* frequency requested, round it down (to be on the safe side).
* Validate the policy. We aren't able to do any fancy in-kernel
* scaling, so we force min=max, and set the policy to "performance".
* If we can't generate the precise frequency requested, round it up.
*/
unsigned int sa11x0_validatespeed(unsigned int cpu, unsigned int khz)
void sa11x0_verify_speed(struct cpufreq_policy *policy)
{
return cclk_frequency_100khz[sa11x0_freq_to_ppcr(khz)] * 100;
if (policy->max > policy->max_cpu_freq)
policy->max = policy->max_cpu_freq;
policy->max = cclk_frequency_100khz[sa11x0_freq_to_ppcr(policy->max)] * 100;
policy->min = policy->max;
policy->policy = CPUFREQ_POLICY_POWERSAVE;
}
unsigned int sa11x0_getspeed(void)
......
......@@ -17,3 +17,9 @@ extern void (*sa1100fb_lcd_power)(int on);
extern void sa1110_mb_enable(void);
extern void sa1110_mb_disable(void);
struct cpufreq_policy;
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
extern void sa11x0_verify_speed(struct cpufreq_policy *policy);
extern unsigned int sa11x0_getspeed(void);
......@@ -25,7 +25,6 @@
#include <asm/mach/serial_sa1100.h>
#include "generic.h"
#include "sa1111.h"
static int __init graphicsmaster_init(void)
{
......@@ -43,7 +42,7 @@ static int __init graphicsmaster_init(void)
/*
* Probe for SA1111.
*/
ret = sa1111_init(NULL, 0x18000000, ADS_EXT_IRQ(0));
ret = sa1111_init(0x18000000, ADS_EXT_IRQ(0));
if (ret < 0)
return ret;
......
This diff is collapsed.
......@@ -16,7 +16,6 @@
#include <asm/mach/serial_sa1100.h>
#include "generic.h"
#include "sa1111.h"
#define JORTUCR_VAL 0x20000400
......@@ -46,11 +45,7 @@ static int __init jornada720_init(void)
PPSR &= ~(PPC_LDD3 | PPC_LDD4);
PPDR |= PPC_LDD3 | PPC_LDD4;
/* initialize extra IRQs */
set_GPIO_IRQ_edge(GPIO_GPIO1, GPIO_RISING_EDGE);
sa1111_init_irq(IRQ_GPIO1); /* chained on GPIO 1 */
return 0;
return sa1111_init(0x40000000, IRQ_GPIO1);
}
arch_initcall(jornada720_init);
......
......@@ -11,6 +11,7 @@
#include <linux/ioport.h>
#include <linux/serial_core.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
......@@ -23,13 +24,6 @@
#include <asm/hardware/sa1111.h>
#include <asm/sizes.h>
#include "sa1111.h"
static struct device neponset_device = {
.name = "Neponset",
.bus_id = "nep_bus",
};
/*
* Install handler for Neponset IRQ. Note that we have to loop here
* since the ETHERNET and USAR IRQs are level based, and we need to
......@@ -163,6 +157,52 @@ static struct sa1100_port_fns neponset_port_fns __initdata = {
.get_mctrl = neponset_get_mctrl,
};
/*
* LDM power management.
*/
static int neponset_suspend(struct device *dev, u32 state, u32 level)
{
/*
* Save state.
*/
if (level == SUSPEND_SAVE_STATE ||
level == SUSPEND_DISABLE ||
level == SUSPEND_POWER_DOWN) {
if (!dev->saved_state)
dev->saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL);
if (!dev->saved_state)
return -ENOMEM;
*(unsigned int *)dev->saved_state = NCR_0;
}
return 0;
}
static int neponset_resume(struct device *dev, u32 level)
{
if (level == RESUME_RESTORE_STATE || level == RESUME_ENABLE) {
if (dev->saved_state) {
NCR_0 = *(unsigned int *)dev->saved_state;
kfree(dev->saved_state);
dev->saved_state = NULL;
}
}
return 0;
}
static struct device_driver neponset_device_driver = {
.suspend = neponset_suspend,
.resume = neponset_resume,
};
static struct device neponset_device = {
.name = "Neponset",
.bus_id = "neponset",
.driver = &neponset_device_driver,
};
static int __init neponset_init(void)
{
int ret;
......@@ -191,7 +231,7 @@ static int __init neponset_init(void)
return -ENODEV;
}
ret = device_register(&neponset_device);
ret = register_sys_device(&neponset_device);
if (ret)
return ret;
......@@ -213,7 +253,7 @@ static int __init neponset_init(void)
/*
* Probe and initialise the SA1111.
*/
return sa1111_init(&neponset_device, 0x40000000, IRQ_NEPONSET_SA1111);
return sa1111_init(0x40000000, IRQ_NEPONSET_SA1111);
}
arch_initcall(neponset_init);
......
......@@ -17,7 +17,6 @@
#include <asm/mach/serial_sa1100.h>
#include "generic.h"
#include "sa1111.h"
static int __init pfs168_init(void)
......@@ -36,7 +35,7 @@ static int __init pfs168_init(void)
/*
* Probe for SA1111.
*/
return sa1111_init(NULL, 0x40000000, IRQ_GPIO25);
return sa1111_init(0x40000000, IRQ_GPIO25);
}
arch_initcall(pfs168_init);
......
......@@ -30,6 +30,7 @@
#include <linux/interrupt.h>
#include <linux/sysctl.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/cpufreq.h>
#include <asm/hardware.h>
......@@ -193,11 +194,29 @@ static int sysctl_pm_do_suspend(void)
{
int retval;
/*
* Suspend "legacy" devices.
*/
retval = pm_send_all(PM_SUSPEND, (void *)3);
if (retval == 0) {
/*
* Suspend LDM devices.
*/
device_suspend(4, SUSPEND_NOTIFY);
device_suspend(4, SUSPEND_SAVE_STATE);
device_suspend(4, SUSPEND_DISABLE);
retval = pm_do_suspend();
/*
* Resume LDM devices.
*/
device_resume(RESUME_RESTORE_STATE);
device_resume(RESUME_ENABLE);
/*
* Resume "legacy" devices.
*/
pm_send_all(PM_RESUME, (void *)0);
}
......
This diff is collapsed.
/*
* linux/arch/arm/mach-sa1100/sa1111.h
*/
struct device;
/*
* Probe for a SA1111 chip.
*/
extern int
sa1111_init(struct device *parent, unsigned long phys, unsigned int irq);
/*
* Wake up a SA1111 chip.
*/
extern void sa1111_wake(void);
/*
* Doze the SA1111 chip.
*/
extern void sa1111_doze(void);
......@@ -284,6 +284,17 @@ storkInitTSandDtoA(void)
storkClockShortToDtoA(0x0A00); /* turn on the brightness */
}
static void stork_lcd_power(int on)
{
if (on) {
storkSetLCDCPLD(0, 1);
storkSetLatchA(STORK_LCD_BACKLIGHT_INVERTER_ON);
} else {
storkSetLCDCPLD(0, 0);
storkClearLatchA(STORK_LCD_BACKLIGHT_INVERTER_ON);
}
}
struct map_desc stork_io_desc[] __initdata = {
/* virtual physical length type */
{ STORK_VM_BASE_CS1, STORK_VM_OFF_CS1, 0x01000000, MT_DEVICE }, /* EGPIO 0 */
......@@ -312,6 +323,8 @@ stork_map_io(void)
storkInitTSandDtoA();
sa1100fb_lcd_power = stork_lcd_power;
return 0;
}
......
......@@ -56,7 +56,6 @@
#include <linux/serial_core.h>
#include "generic.h"
#include "sa1111.h"
#include <asm/hardware/sa1111.h>
#define DEBUG 1
......@@ -401,7 +400,7 @@ static int __init system3_init(void)
/*
* Probe for a SA1111.
*/
ret = sa1111_init(NULL, PT_SA1111_BASE, IRQ_SYSTEM3_SA1111);
ret = sa1111_init(PT_SA1111_BASE, IRQ_SYSTEM3_SA1111);
if (ret < 0) {
printk( KERN_WARNING"PT Digital Board: no SA1111 found!\n" );
goto DONE;
......
......@@ -35,7 +35,7 @@
#else
/*
* "code" is actually the FSR register. Bit 11 set means the
* isntruction was performing a write.
* instruction was performing a write.
*/
#define DO_COW(code) ((code) & (1 << 11))
#define READ_FAULT(code) (!DO_COW(code))
......@@ -54,7 +54,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
printk(KERN_ALERT "pgd = %p\n", mm->pgd);
pgd = pgd_offset(mm, addr);
printk(KERN_ALERT "*pgd=%08lx", pgd_val(*pgd));
printk(KERN_ALERT "[%08lx] *pgd=%08lx", addr, pgd_val(*pgd));
do {
pmd_t *pmd;
......
......@@ -6,7 +6,7 @@
# To add an entry into this database, please see Documentation/arm/README,
# or contact rmk@arm.linux.org.uk
#
# Last update: Sat Jul 27 09:56:53 2002
# Last update: Sat Sep 21 13:39:13 2002
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
......@@ -214,3 +214,31 @@ emailphone SA1100_EMAILPHONE EMAILPHONE 202
h3900 ARCH_H3900 H3900 203
pxa1 ARCH_PXA1 PXA1 204
koan369 SA1100_KOAN369 KOAN369 205
cogent ARCH_COGENT COGENT 206
esl_simputer ARCH_ESL_SIMPUTER ESL_SIMPUTER 207
esl_simputer_clr ARCH_ESL_SIMPUTER_CLR ESL_SIMPUTER_CLR 208
esl_simputer_bw ARCH_ESL_SIMPUTER_BW ESL_SIMPUTER_BW 209
hhp_cradle ARCH_HHP_CRADLE HHP_CRADLE 210
he500 ARCH_HE500 HE500 211
inhandelf2 SA1100_INHANDELF2 INHANDELF2 212
inhandftip SA1100_INHANDFTIP INHANDFTIP 213
dnp1110 SA1100_DNP1110 DNP1110 214
pnp1110 SA1100_PNP1110 PNP1110 215
csb226 ARCH_CSB226 CSB226 216
arnold SA1100_ARNOLD ARNOLD 217
psiboard SA1100_PSIBOARD PSIBOARD 218
jz8028 ARCH_JZ8028 JZ8028 219
ipaq3 ARCH_IPAQ3 IPAQ3 220
forte SA1100_FORTE FORTE 221
acam SA1100_ACAM ACAM 222
abox SA1100_ABOX ABOX 223
atmel ARCH_ATMEL ATMEL 224
sitsang ARCH_SITSANG SITSANG 225
cpu1110lcdnet SA1100_CPU1110LCDNET CPU1110LCDNET 226
mpl_vcma9 ARCH_MPL_VCMA9 MPL_VCMA9 227
opus_a1 ARCH_OPUS_A1 OPUS_A1 228
daytona ARCH_DAYTONA DAYTONA 229
killbear SA1100_KILLBEAR KILLBEAR 230
yoho ARCH_YOHO YOHO 231
jasper ARCH_JASPER JASPER 232
dsc25 ARCH_DSC25 DSC25 233
......@@ -3,7 +3,7 @@
* Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
*
* Common time service routines for MIPS machines. See
* Documents/MIPS/README.txt.
* Documentation/mips/time.README.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
......
......@@ -18,6 +18,7 @@
#include <linux/kmod.h>
#include <linux/interrupt.h>
#include "base.h"
#include "fs/fs.h"
/*
* hotplugging invokes what /proc/sys/kernel/hotplug says (normally
......@@ -32,14 +33,16 @@
int dev_hotplug (struct device *dev, const char *action)
{
char *argv [3], **envp, *buffer, *scratch;
char *dev_path;
int retval;
int i = 0;
int dev_length;
pr_debug ("%s\n", __FUNCTION__);
if (!dev)
return -ENODEV;
if (!dev->bus || !dev->bus->hotplug)
if (!dev->bus)
return -ENODEV;
if (!hotplug_path [0])
......@@ -66,6 +69,18 @@ int dev_hotplug (struct device *dev, const char *action)
return -ENOMEM;
}
dev_length = get_devpath_length (dev);
dev_length += strlen("root");
dev_path = kmalloc (dev_length, GFP_KERNEL);
if (!dev_path) {
kfree (buffer);
kfree (envp);
return -ENOMEM;
}
memset (dev_path, 0x00, dev_length);
strcpy (dev_path, "root");
fill_devpath (dev, dev_path, dev_length);
/* only one standardized param to hotplug command: the bus name */
argv [0] = hotplug_path;
argv [1] = dev->bus->name;
......@@ -77,26 +92,33 @@ int dev_hotplug (struct device *dev, const char *action)
scratch = buffer;
/* action: add, remove */
envp [i++] = scratch;
scratch += sprintf (scratch, "ACTION=%s", action) + 1;
/* have the bus specific function set up the rest of the environment */
envp [i++] = scratch;
scratch += sprintf (scratch, "DEVICE=%s", dev_path) + 1;
if (dev->bus->hotplug) {
/* have the bus specific function add its stuff */
retval = dev->bus->hotplug (dev, &envp[i], NUM_ENVP - i,
scratch, BUFFER_SIZE - (scratch - buffer));
scratch,
BUFFER_SIZE - (scratch - buffer));
if (retval) {
pr_debug ("%s - hotplug() returned %d\n", __FUNCTION__, retval);
pr_debug ("%s - hotplug() returned %d\n",
__FUNCTION__, retval);
goto exit;
}
}
pr_debug ("%s: %s %s %s %s %s %s\n", __FUNCTION__, argv [0], argv[1],
action, envp[0], envp[1], envp[2]);
envp[0], envp[1], envp[2], envp[3]);
retval = call_usermodehelper (argv [0], argv, envp);
if (retval)
pr_debug ("%s - call_usermodehelper returned %d\n",
__FUNCTION__, retval);
exit:
kfree (dev_path);
kfree (buffer);
kfree (envp);
return retval;
......
......@@ -84,8 +84,6 @@ static int tosh_fn = 0;
MODULE_PARM(tosh_fn, "i");
MODULE_LICENSE("GPL");
static int tosh_get_info(char *, char **, off_t, int);
static int tosh_ioctl(struct inode *, struct file *, unsigned int,
......@@ -517,3 +515,10 @@ void cleanup_module(void)
misc_deregister(&tosh_device);
}
#endif
MODULE_LICENSE("GPL");
MODULE_PARM_DESC(tosh_fn, "User specified Fn key detection port");
MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>");
MODULE_DESCRIPTION("Toshiba laptop SMM driver");
MODULE_SUPPORTED_DEVICE("toshiba");
......@@ -292,7 +292,7 @@ CONFIG_IDEDMA_PCI_AUTO
motherboard uses a VIA VP2 chipset, in which case you should say N.
CONFIG_IDEDMA_IVB
There are unclear terms is ATA-4 and ATA-5 standards how certain
There are unclear terms in ATA-4 and ATA-5 standards how certain
hardware (an 80c ribbon) should be detected. Different interpretations
of the standards have been released in hardware. This causes problems:
for example, a host with Ultra Mode 4 (or higher) will not run
......
This diff is collapsed.
......@@ -209,3 +209,5 @@ EXPORT_SYMBOL(nand_calculate_ecc);
EXPORT_SYMBOL(nand_correct_data);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Steven J. Hill <sjhill@cotw.com>");
MODULE_DESCRIPTION("Generic NAND ECC support");
......@@ -188,6 +188,7 @@ static struct pci_device_id skfddi_pci_tbl[] __initdata = {
};
MODULE_DEVICE_TABLE(pci, skfddi_pci_tbl);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
// Define module-wide (static) variables
......
......@@ -40,7 +40,7 @@ static const char *version =
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/malloc.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <asm/system.h>
#include <asm/bitops.h>
......
......@@ -128,7 +128,7 @@ static char *open_min_error[] = {"No error", "Function Failure", "Signal Lost",
/* Module paramters */
MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ;
MODULE_DESCRIPTION("Olympic PCI/Cardbus Chipset Driver \n") ;
MODULE_DESCRIPTION("Olympic PCI/Cardbus Chipset Driver") ;
/* Ring Speed 0,4,16,100
* 0 = Autosense
......
......@@ -87,7 +87,7 @@ typedef struct lmc___ctl lmc_ctl_t;
lmc_delay(); \
LMC_CSR_WRITE((sc), csr_9, 0x30000); \
lmc_delay(); \
n--; }} while(0);
n--; }} while(0)
struct lmc_regfile_t {
lmc_csrptr_t csr_busmode; /* CSR0 */
......
......@@ -90,7 +90,7 @@ static void __init quirk_triton(struct pci_dev *dev)
* VIA Apollo KT133 needs PCI latency patch
* Made according to a windows driver based patch by George E. Breese
* see PCI Latency Adjust on http://www.viahardware.com/download/viatweak.shtm
* Also see http://home.tiscalinet.de/au-ja/review-kt133a-1-en.html for
* Also see http://www.au-ja.org/review-kt133a-1-en.phtml for
* the info on which Mr Breese based his work.
*
* Updated based on further information from the site and also on
......
......@@ -20,6 +20,7 @@ if [ "$CONFIG_PCMCIA" != "n" ]; then
fi
if [ "$CONFIG_ARM" = "y" ]; then
dep_tristate ' SA1100 support' CONFIG_PCMCIA_SA1100 $CONFIG_ARCH_SA1100 $CONFIG_PCMCIA
dep_tristate ' SA1111 support' CONFIG_PCMCIA_SA1111 $CONFIG_PCMCIA_SA1100 $CONFIG_SA1111 $CONFIG_PCMCIA
fi
fi
......
......@@ -14,6 +14,7 @@ obj-$(CONFIG_I82092) += i82092.o
obj-$(CONFIG_TCIC) += tcic.o
obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o
obj-$(CONFIG_PCMCIA_SA1111) += sa1111_cs.o
yenta_socket-objs := pci_socket.o yenta.o
......@@ -21,26 +22,29 @@ pcmcia_core-objs-y := cistpl.o rsrc_mgr.o bulkmem.o cs.o
pcmcia_core-objs-$(CONFIG_CARDBUS) += cardbus.o
pcmcia_core-objs := $(pcmcia_core-objs-y)
sa1111_cs-objs-y := sa1111_generic.o
sa1111_cs-objs-$(CONFIG_SA1100_ADSBITSY) += sa1100_adsbitsy.o
sa1111_cs-objs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o
sa1111_cs-objs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o
sa1111_cs-objs-$(CONFIG_SA1100_GRAPHICSMASTER) += sa1100_graphicsmaster.o
sa1111_cs-objs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o
sa1111_cs-objs-$(CONFIG_SA1100_PFS168) += sa1100_pfs168.o
sa1111_cs-objs-$(CONFIG_SA1100_PT_SYSTEM3) += sa1100_system3.o
sa1111_cs-objs-$(CONFIG_SA1100_XP860) += sa1100_xp860.o
sa1111_cs-objs := $(sa1111_cs-objs-y)
sa1100_cs-objs-y := sa1100_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_ADSBITSY) += sa1100_adsbitsy.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o
sa1100_cs-objs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o
sa1100_cs-objs-$(CONFIG_SA1100_FLEXANET) += sa1100_flexanet.o
sa1100_cs-objs-$(CONFIG_SA1100_FREEBIRD) += sa1100_freebird.o
sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSMASTER) += sa1100_graphicsmaster.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSCLIENT) += sa1100_graphicsclient.o
sa1100_cs-objs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o
sa1100_cs-objs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_PANGOLIN) += sa1100_pangolin.o
sa1100_cs-objs-$(CONFIG_SA1100_PFS168) += sa1100_pfs168.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_PT_SYSTEM3) += sa1100_system3.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
sa1100_cs-objs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
sa1100_cs-objs-$(CONFIG_SA1100_STORK) += sa1100_stork.o
sa1100_cs-objs-$(CONFIG_SA1100_TRIZEPS) += sa1100_trizeps.o
sa1100_cs-objs-$(CONFIG_SA1100_XP860) += sa1100_xp860.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_YOPY) += sa1100_yopy.o
sa1100_cs-objs := $(sa1100_cs-objs-y)
......
......@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include "sa1100_generic.h"
#include "sa1111_generic.h"
......
......@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/arch/badge4.h>
#include <asm/hardware/sa1111.h>
......
......@@ -110,12 +110,11 @@ sa1100_pcmcia_default_mecr_timing(unsigned int sock, unsigned int cpu_speed,
* Call board specific BS value calculation to allow boards
* to tweak the BS values.
*/
static int sa1100_pcmcia_set_mecr(int sock)
static int sa1100_pcmcia_set_mecr(int sock, unsigned int cpu_clock)
{
struct sa1100_pcmcia_socket *skt;
u32 mecr;
int clock;
long flags;
unsigned long flags;
unsigned int bs;
if (sock < 0 || sock > SA1100_PCMCIA_MAX_SOCK)
......@@ -125,8 +124,7 @@ static int sa1100_pcmcia_set_mecr(int sock)
local_irq_save(flags);
clock = cpufreq_get(0);
bs = pcmcia_low_level->socket_get_timing(sock, clock, skt->speed_io);
bs = pcmcia_low_level->socket_get_timing(sock, cpu_clock, skt->speed_io);
mecr = MECR;
MECR_FAST_SET(mecr, sock, 0);
......@@ -652,7 +650,7 @@ sa1100_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
if ( map->speed == 0)
map->speed = SA1100_PCMCIA_IO_ACCESS;
sa1100_pcmcia_set_mecr( sock );
sa1100_pcmcia_set_mecr(sock, cpufreq_get(0));
}
if (map->stop == 1)
......@@ -741,7 +739,7 @@ sa1100_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
map->speed = SA1100_PCMCIA_5V_MEM_ACCESS;
}
sa1100_pcmcia_set_mecr( sock );
sa1100_pcmcia_set_mecr(sock, cpufreq_get(0));
}
......@@ -885,9 +883,8 @@ static void sa1100_pcmcia_update_mecr(unsigned int clock)
{
unsigned int sock;
for (sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock) {
sa1100_pcmcia_set_mecr(sock);
}
for (sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock)
sa1100_pcmcia_set_mecr(sock, clock);
}
/* sa1100_pcmcia_notifier()
......@@ -904,26 +901,26 @@ static int
sa1100_pcmcia_notifier(struct notifier_block *nb, unsigned long val,
void *data)
{
struct cpufreq_info *ci = data;
struct cpufreq_freqs *freqs = data;
switch (val) {
case CPUFREQ_PRECHANGE:
if (ci->new_freq > ci->old_freq) {
DEBUG(2, "%s(): new frequency %u.%uMHz > %u.%uMHz, pre-updating\n",
__FUNCTION__,
ci->new_freq / 1000, (ci->new_freq / 100) % 10,
ci->old_freq / 1000, (ci->old_freq / 100) % 10);
sa1100_pcmcia_update_mecr(ci->new_freq);
if (freqs->new > freqs->old) {
DEBUG(2, "%s(): new frequency %u.%uMHz > %u.%uMHz, "
"pre-updating\n", __FUNCTION__,
freqs->new / 1000, (freqs->new / 100) % 10,
freqs->old / 1000, (freqs->old / 100) % 10);
sa1100_pcmcia_update_mecr(freqs->new);
}
break;
case CPUFREQ_POSTCHANGE:
if (ci->new_freq < ci->old_freq) {
DEBUG(2, "%s(): new frequency %u.%uMHz < %u.%uMHz, post-updating\n",
__FUNCTION__,
ci->new_freq / 1000, (ci->new_freq / 100) % 10,
ci->old_freq / 1000, (ci->old_freq / 100) % 10);
sa1100_pcmcia_update_mecr(ci->new_freq);
if (freqs->new < freqs->old) {
DEBUG(2, "%s(): new frequency %u.%uMHz < %u.%uMHz, "
"post-updating\n", __FUNCTION__,
freqs->new / 1000, (freqs->new / 100) % 10,
freqs->old / 1000, (freqs->old / 100) % 10);
sa1100_pcmcia_update_mecr(freqs->new);
}
break;
}
......@@ -946,7 +943,7 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
struct pcmcia_init pcmcia_init;
struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
struct pcmcia_state_array state_array;
unsigned int i;
unsigned int i, cpu_clock;
int ret;
/*
......@@ -986,6 +983,8 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
goto shutdown;
}
cpu_clock = cpufreq_get(0);
/*
* We initialize the MECR to default values here, because we are
* not guaranteed to see a SetIOMap operation at runtime.
......@@ -1019,7 +1018,7 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
goto out_err;
}
sa1100_pcmcia_set_mecr( i );
sa1100_pcmcia_set_mecr(i, cpu_clock);
}
......@@ -1110,7 +1109,7 @@ static int __init sa1100_pcmcia_init(void)
servinfo_t info;
int ret, i;
printk(KERN_INFO "SA-1100 PCMCIA (CS release %s)\n", CS_RELEASE);
printk(KERN_INFO "SA11x0 PCMCIA (CS release %s)\n", CS_RELEASE);
CardServices(GetCardServicesInfo, &info);
if (info.Revision != CS_RELEASE_CODE) {
......@@ -1127,7 +1126,8 @@ static int __init sa1100_pcmcia_init(void)
}
#ifdef CONFIG_CPU_FREQ
ret = cpufreq_register_notifier(&sa1100_pcmcia_notifier_block);
ret = cpufreq_register_notifier(&sa1100_pcmcia_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
if (ret < 0) {
printk(KERN_ERR "Unable to register CPU frequency change "
"notifier (%d)\n", ret);
......@@ -1135,15 +1135,9 @@ static int __init sa1100_pcmcia_init(void)
}
#endif
#ifdef CONFIG_SA1100_ADSBITSY
pcmcia_adsbitsy_init();
#endif
#ifdef CONFIG_SA1100_ASSABET
pcmcia_assabet_init();
#endif
#ifdef CONFIG_SA1100_BADGE4
pcmcia_badge4_init();
#endif
#ifdef CONFIG_SA1100_CERF
pcmcia_cerf_init();
#endif
......@@ -1156,24 +1150,9 @@ static int __init sa1100_pcmcia_init(void)
#ifdef CONFIG_SA1100_GRAPHICSCLIENT
pcmcia_gcplus_init();
#endif
#ifdef CONFIG_SA1100_GRAPHICSMASTER
pcmcia_graphicsmaster_init();
#endif
#ifdef CONFIG_SA1100_JORNADA720
pcmcia_jornada720_init();
#endif
#ifdef CONFIG_ASSABET_NEPONSET
pcmcia_neponset_init();
#endif
#ifdef CONFIG_SA1100_PANGOLIN
pcmcia_pangolin_init();
#endif
#ifdef CONFIG_SA1100_PFS168
pcmcia_pfs_init();
#endif
#ifdef CONFIG_SA1100_PT_SYSTEM3
pcmcia_system3_init();
#endif
#ifdef CONFIG_SA1100_SHANNON
pcmcia_shannon_init();
#endif
......@@ -1186,9 +1165,6 @@ static int __init sa1100_pcmcia_init(void)
#ifdef CONFIG_SA1100_TRIZEPS
pcmcia_trizeps_init();
#endif
#ifdef CONFIG_SA1100_XP860
pcmcia_xp860_init();
#endif
#ifdef CONFIG_SA1100_YOPY
pcmcia_yopy_init();
#endif
......@@ -1203,15 +1179,9 @@ static int __init sa1100_pcmcia_init(void)
*/
static void __exit sa1100_pcmcia_exit(void)
{
#ifdef CONFIG_SA1100_ADSBITSY
pcmcia_adsbitsy_exit();
#endif
#ifdef CONFIG_SA1100_ASSABET
pcmcia_assabet_exit();
#endif
#ifdef CONFIG_SA1100_BADGE4
pcmcia_badge4_exit();
#endif
#ifdef CONFIG_SA1100_CERF
pcmcia_cerf_exit();
#endif
......@@ -1224,21 +1194,9 @@ static void __exit sa1100_pcmcia_exit(void)
#ifdef CONFIG_SA1100_GRAPHICSCLIENT
pcmcia_gcplus_exit();
#endif
#ifdef CONFIG_SA1100_GRAPHICSMASTER
pcmcia_graphicsmaster_exit();
#endif
#ifdef CONFIG_SA1100_JORNADA720
pcmcia_jornada720_exit();
#endif
#ifdef CONFIG_ASSABET_NEPONSET
pcmcia_neponset_exit();
#endif
#ifdef CONFIG_SA1100_PANGOLIN
pcmcia_pangolin_exit();
#endif
#ifdef CONFIG_SA1100_PFS168
pcmcia_pfs_exit();
#endif
#ifdef CONFIG_SA1100_SHANNON
pcmcia_shannon_exit();
#endif
......@@ -1248,9 +1206,6 @@ static void __exit sa1100_pcmcia_exit(void)
#ifdef CONFIG_SA1100_STORK
pcmcia_stork_exit();
#endif
#ifdef CONFIG_SA1100_XP860
pcmcia_xp860_exit();
#endif
#ifdef CONFIG_SA1100_YOPY
pcmcia_yopy_exit();
#endif
......@@ -1261,7 +1216,7 @@ static void __exit sa1100_pcmcia_exit(void)
}
#ifdef CONFIG_CPU_FREQ
cpufreq_unregister_notifier(&sa1100_pcmcia_notifier_block);
cpufreq_unregister_notifier(&sa1100_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
#endif
}
......
......@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include "sa1100_generic.h"
#include "sa1111_generic.h"
......
......@@ -9,6 +9,7 @@
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include "sa1100_generic.h"
#include "sa1111_generic.h"
......
......@@ -10,33 +10,16 @@
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/arch/assabet.h>
#include <asm/mach-types.h>
#include <asm/arch/neponset.h>
#include <asm/hardware/sa1111.h>
#include "sa1100_generic.h"
#include "sa1111_generic.h"
static int neponset_pcmcia_init(struct pcmcia_init *init)
{
/* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
/* MAX1600 to standby mode: */
PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
NCR_0 &= ~(NCR_A0VPP | NCR_A1VPP);
return sa1111_pcmcia_init(init);
}
static int
neponset_pcmcia_configure_socket(const struct pcmcia_configure *conf)
{
unsigned int ncr_mask, pa_dwr_mask;
unsigned int ncr_set, pa_dwr_set;
int ret;
/* Neponset uses the Maxim MAX1600, with the following connections:
/*
* Neponset uses the Maxim MAX1600, with the following connections:
*
* MAX1600 Neponset
*
* A0VCC SA-1111 GPIO A<1>
......@@ -58,6 +41,29 @@ neponset_pcmcia_configure_socket(const struct pcmcia_configure *conf)
* the corresponding truth table.
*/
static int neponset_pcmcia_init(struct pcmcia_init *init)
{
NCR_0 &= ~(NCR_A0VPP | NCR_A1VPP);
/*
* Set GPIO_A<3:0> to be outputs for the MAX1600,
* and switch to standby mode.
*/
PA_DDR = 0;
PA_SDR = 0;
PA_DWR = 0;
PA_SSR = 0;
return sa1111_pcmcia_init(init);
}
static int
neponset_pcmcia_configure_socket(const struct pcmcia_configure *conf)
{
unsigned int ncr_mask, pa_dwr_mask;
unsigned int ncr_set, pa_dwr_set;
int ret;
switch (conf->sock) {
case 0:
pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
......@@ -135,13 +141,13 @@ int __init pcmcia_neponset_init(void)
{
int ret = -ENODEV;
if (machine_is_assabet() && sa1111)
if (machine_is_assabet())
ret = sa1100_register_pcmcia(&neponset_pcmcia_ops);
return ret;
}
void __exit pcmcia_neponset_exit(void)
void __devexit pcmcia_neponset_exit(void)
{
sa1100_unregister_pcmcia(&neponset_pcmcia_ops);
}
......@@ -7,10 +7,11 @@
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <asm/delay.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include "sa1100_generic.h"
......
......@@ -31,6 +31,7 @@
#include <linux/ioport.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/hardware/sa1111.h>
......
......@@ -10,6 +10,7 @@
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include "sa1100_generic.h"
......
......@@ -5,10 +5,12 @@
* basically means we handle everything except controlling the
* power. Power is machine specific...
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/hardware/sa1111.h>
......@@ -21,19 +23,18 @@ static struct irqs {
int irq;
const char *str;
} irqs[] = {
{ S0_CD_VALID, "SA1111 PCMCIA card detect" },
{ S0_BVD1_STSCHG, "SA1111 PCMCIA BVD1" },
{ S1_CD_VALID, "SA1111 CF card detect" },
{ S1_BVD1_STSCHG, "SA1111 CF BVD1" },
{ IRQ_S0_CD_VALID, "SA1111 PCMCIA card detect" },
{ IRQ_S0_BVD1_STSCHG, "SA1111 PCMCIA BVD1" },
{ IRQ_S1_CD_VALID, "SA1111 CF card detect" },
{ IRQ_S1_BVD1_STSCHG, "SA1111 CF BVD1" },
};
static struct sa1111_dev *pcmcia;
int sa1111_pcmcia_init(struct pcmcia_init *init)
{
int i, ret;
if (!request_mem_region(_PCCR, 512, "PCMCIA"))
return -1;
for (i = ret = 0; i < ARRAY_SIZE(irqs); i++) {
set_irq_type(irqs[i].irq, IRQT_FALLING);
ret = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
......@@ -47,8 +48,6 @@ int sa1111_pcmcia_init(struct pcmcia_init *init)
irqs[i].irq, ret);
while (i--)
free_irq(irqs[i].irq, NULL);
release_mem_region(_PCCR, 16);
}
return ret ? -1 : 2;
......@@ -61,8 +60,6 @@ int sa1111_pcmcia_shutdown(void)
for (i = 0; i < ARRAY_SIZE(irqs); i++)
free_irq(irqs[i].irq, NULL);
release_mem_region(_PCCR, 512);
return 0;
}
......@@ -73,7 +70,7 @@ int sa1111_pcmcia_socket_state(struct pcmcia_state_array *state)
if (state->size < 2)
return -1;
status = PCSR;
status = sa1111_readl(pcmcia->mapbase + SA1111_PCSR);
state->state[0].detect = status & PCSR_S0_DETECT ? 0 : 1;
state->state[0].ready = status & PCSR_S0_READY ? 1 : 0;
......@@ -99,8 +96,8 @@ int sa1111_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
int ret = 0;
switch (info->sock) {
case 0: info->irq = S0_READY_NINT; break;
case 1: info->irq = S1_READY_NINT; break;
case 0: info->irq = IRQ_S0_READY_NINT; break;
case 1: info->irq = IRQ_S1_READY_NINT; break;
default: ret = 1;
}
......@@ -109,7 +106,7 @@ int sa1111_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
int sa1111_pcmcia_configure_socket(const struct pcmcia_configure *conf)
{
unsigned int rst, flt, wait, pse, irq, pccr_mask;
unsigned int rst, flt, wait, pse, irq, pccr_mask, val;
unsigned long flags;
switch (conf->sock) {
......@@ -118,7 +115,7 @@ int sa1111_pcmcia_configure_socket(const struct pcmcia_configure *conf)
flt = PCCR_S0_FLT;
wait = PCCR_S0_PWAITEN;
pse = PCCR_S0_PSE;
irq = S0_READY_NINT;
irq = IRQ_S0_READY_NINT;
break;
case 1:
......@@ -126,7 +123,7 @@ int sa1111_pcmcia_configure_socket(const struct pcmcia_configure *conf)
flt = PCCR_S1_FLT;
wait = PCCR_S1_PWAITEN;
pse = PCCR_S1_PSE;
irq = S1_READY_NINT;
irq = IRQ_S1_READY_NINT;
break;
default:
......@@ -159,7 +156,9 @@ int sa1111_pcmcia_configure_socket(const struct pcmcia_configure *conf)
pccr_mask |= flt;
local_irq_save(flags);
PCCR = (PCCR & ~(pse | flt | wait | rst)) | pccr_mask;
val = sa1111_readl(pcmcia->mapbase + SA1111_PCCR);
val = (val & ~(pse | flt | wait | rst)) | pccr_mask;
sa1111_writel(val, pcmcia->mapbase + SA1111_PCCR);
local_irq_restore(flags);
if (conf->irq)
......@@ -179,3 +178,130 @@ int sa1111_pcmcia_socket_suspend(int sock)
{
return 0;
}
static int pcmcia_probe(struct device *dev)
{
struct sa1111_dev *sadev = SA1111_DEV(dev);
unsigned long flags;
char *base;
local_irq_save(flags);
if (pcmcia) {
local_irq_restore(flags);
return -EBUSY;
}
pcmcia = sadev;
local_irq_restore(flags);
if (!request_mem_region(sadev->res.start, 512,
SA1111_DRIVER_NAME(sadev)))
return -EBUSY;
base = sadev->mapbase;
/*
* Initialise the suspend state.
*/
sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + SA1111_PCSSR);
sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + SA1111_PCCR);
#ifdef CONFIG_SA1100_ADSBITSY
pcmcia_adsbitsy_init();
#endif
#ifdef CONFIG_SA1100_BADGE4
pcmcia_badge4_init();
#endif
#ifdef CONFIG_SA1100_GRAPHICSMASTER
pcmcia_graphicsmaster_init();
#endif
#ifdef CONFIG_SA1100_JORNADA720
pcmcia_jornada720_init();
#endif
#ifdef CONFIG_ASSABET_NEPONSET
pcmcia_neponset_init();
#endif
#ifdef CONFIG_SA1100_PFS168
pcmcia_pfs_init();
#endif
#ifdef CONFIG_SA1100_PT_SYSTEM3
pcmcia_system3_init();
#endif
#ifdef CONFIG_SA1100_XP860
pcmcia_xp860_init();
#endif
return 0;
}
static int __devexit pcmcia_remove(struct device *dev)
{
struct sa1111_dev *sadev = SA1111_DEV(dev);
#ifdef CONFIG_SA1100_ADSBITSY
pcmcia_adsbitsy_exit();
#endif
#ifdef CONFIG_SA1100_BADGE4
pcmcia_badge4_exit();
#endif
#ifdef CONFIG_SA1100_GRAPHICSMASTER
pcmcia_graphicsmaster_exit();
#endif
#ifdef CONFIG_SA1100_JORNADA720
pcmcia_jornada720_exit();
#endif
#ifdef CONFIG_ASSABET_NEPONSET
pcmcia_neponset_exit();
#endif
#ifdef CONFIG_SA1100_PFS168
pcmcia_pfs_exit();
#endif
#ifdef CONFIG_SA1100_PT_SYSTEM3
pcmcia_system3_exit();
#endif
#ifdef CONFIG_SA1100_XP860
pcmcia_xp860_exit();
#endif
release_mem_region(sadev->res.start, 512);
pcmcia = NULL;
return 0;
}
static int pcmcia_suspend(struct device *dev, u32 state, u32 level)
{
return 0;
}
static int pcmcia_resume(struct device *dev, u32 level)
{
return 0;
}
static struct sa1111_driver pcmcia_driver = {
.drv = {
.name = "SA1111 PCMCIA",
.bus = &sa1111_bus_type,
.probe = pcmcia_probe,
.remove = __devexit_p(pcmcia_remove),
.suspend = pcmcia_suspend,
.resume = pcmcia_resume,
},
.devid = SA1111_DEVID_PCMCIA,
};
static int __init sa1111_drv_pcmcia_init(void)
{
return driver_register(&pcmcia_driver.drv);
}
static void __exit sa1111_drv_pcmcia_exit(void)
{
remove_driver(&pcmcia_driver.drv);
}
module_init(sa1111_drv_pcmcia_init);
module_exit(sa1111_drv_pcmcia_exit);
MODULE_DESCRIPTION("SA1111 PCMCIA card socket driver");
MODULE_LICENSE("GPL");
......@@ -1006,9 +1006,7 @@ static void bluetooth_write_bulk_callback (struct urb *urb)
}
/* wake up our little function to let the tty layer know that something happened */
queue_task(&bluetooth->tqueue, &tq_immediate);
mark_bh(IMMEDIATE_BH);
return;
schedule_task(&bluetooth->tqueue);
}
......
......@@ -272,8 +272,7 @@ static void acm_write_bulk(struct urb *urb)
if (urb->status)
dbg("nonzero write bulk status received: %d", urb->status);
queue_task(&acm->tqueue, &tq_immediate);
mark_bh(IMMEDIATE_BH);
schedule_task(&acm->tqueue);
}
static void acm_softint(void *private)
......
......@@ -5,7 +5,7 @@
export-objs := usb.o hcd.o hcd-pci.o urb.o message.o file.o buffer.o
usbcore-objs := usb.o usb-debug.o hub.o hcd.o urb.o message.o \
config.o file.o buffer.o
config.o file.o buffer.o driverfs.o
ifeq ($(CONFIG_PCI),y)
usbcore-objs += hcd-pci.o
......
......@@ -1067,6 +1067,10 @@ static int proc_ioctl (struct dev_state *ps, void *arg)
/* disconnect kernel driver from interface, leaving it unbound. */
case USBDEVFS_DISCONNECT:
/* this function is voodoo. */
/* which function ... usb_device_remove()?
* FIXME either the module lock (BKL) should be involved
* here too, or the 'default' case below is broken
*/
driver = ifp->driver;
if (driver) {
dbg ("disconnect '%s' from dev %d interface %d",
......@@ -1083,24 +1087,26 @@ static int proc_ioctl (struct dev_state *ps, void *arg)
/* talk directly to the interface's driver */
default:
lock_kernel(); /* against module unload */
/* BKL used here to protect against changing the binding
* of this driver to this device, as well as unloading its
* driver module.
*/
lock_kernel ();
driver = ifp->driver;
if (driver == 0 || driver->ioctl == 0) {
unlock_kernel();
retval = -ENOSYS;
} else {
if (ifp->driver->owner) {
__MOD_INC_USE_COUNT(ifp->driver->owner);
unlock_kernel();
}
/* ifno might usefully be passed ... */
retval = driver->ioctl (ps->dev, ctrl.ioctl_code, buf);
/* size = min_t(int, size, retval)? */
if (ifp->driver->owner) {
__MOD_DEC_USE_COUNT(ifp->driver->owner);
} else {
if (driver->owner
&& !try_inc_mod_count (driver->owner)) {
unlock_kernel();
retval = -ENOSYS;
break;
}
unlock_kernel ();
retval = driver->ioctl (ifp, ctrl.ioctl_code, buf);
if (driver->owner)
__MOD_DEC_USE_COUNT (driver->owner);
}
if (retval == -ENOIOCTLCMD)
......
/*
* drivers/usb/core/driverfs.c
*
* (C) Copyright 2002 David Brownell
* (C) Copyright 2002 Greg Kroah-Hartman
* (C) Copyright 2002 IBM Corp.
*
* All of the driverfs file attributes for usb devices and interfaces.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/usb.h>
#include "usb.h"
/* Active configuration fields */
#define usb_actconfig_attr(field, format_string) \
static ssize_t \
show_##field (struct device *dev, char *buf, size_t count, loff_t off) \
{ \
struct usb_device *udev; \
\
if (off) \
return 0; \
\
udev = to_usb_device (dev); \
return sprintf (buf, format_string, udev->actconfig->field); \
} \
static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
usb_actconfig_attr (bNumInterfaces, "%2d\n")
usb_actconfig_attr (bConfigurationValue, "%2d\n")
usb_actconfig_attr (bmAttributes, "%2x\n")
usb_actconfig_attr (MaxPower, "%3dmA\n")
/* String fields */
static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t off)
{
struct usb_device *udev;
int len;
if (off)
return 0;
udev = to_usb_device (dev);
len = usb_string(udev, udev->descriptor.iProduct, buf, PAGE_SIZE);
if (len < 0)
return 0;
buf[len] = '\n';
buf[len+1] = 0;
return len+1;
}
static DEVICE_ATTR(product,S_IRUGO,show_product,NULL);
static ssize_t
show_manufacturer (struct device *dev, char *buf, size_t count, loff_t off)
{
struct usb_device *udev;
int len;
if (off)
return 0;
udev = to_usb_device (dev);
len = usb_string(udev, udev->descriptor.iManufacturer, buf, PAGE_SIZE);
if (len < 0)
return 0;
buf[len] = '\n';
buf[len+1] = 0;
return len+1;
}
static DEVICE_ATTR(manufacturer,S_IRUGO,show_manufacturer,NULL);
static ssize_t
show_serial (struct device *dev, char *buf, size_t count, loff_t off)
{
struct usb_device *udev;
int len;
if (off)
return 0;
udev = to_usb_device (dev);
len = usb_string(udev, udev->descriptor.iSerialNumber, buf, PAGE_SIZE);
if (len < 0)
return 0;
buf[len] = '\n';
buf[len+1] = 0;
return len+1;
}
static DEVICE_ATTR(serial,S_IRUGO,show_serial,NULL);
/* Descriptor fields */
#define usb_descriptor_attr(field, format_string) \
static ssize_t \
show_##field (struct device *dev, char *buf, size_t count, loff_t off) \
{ \
struct usb_device *udev; \
\
if (off) \
return 0; \
\
udev = to_usb_device (dev); \
return sprintf (buf, format_string, udev->descriptor.field); \
} \
static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
usb_descriptor_attr (idVendor, "%04x\n")
usb_descriptor_attr (idProduct, "%04x\n")
usb_descriptor_attr (bcdDevice, "%04x\n")
usb_descriptor_attr (bDeviceClass, "%02x\n")
usb_descriptor_attr (bDeviceSubClass, "%02x\n")
usb_descriptor_attr (bDeviceProtocol, "%02x\n")
void usb_create_driverfs_dev_files (struct usb_device *udev)
{
struct device *dev = &udev->dev;
device_create_file (dev, &dev_attr_bNumInterfaces);
device_create_file (dev, &dev_attr_bConfigurationValue);
device_create_file (dev, &dev_attr_bmAttributes);
device_create_file (dev, &dev_attr_MaxPower);
device_create_file (dev, &dev_attr_idVendor);
device_create_file (dev, &dev_attr_idProduct);
device_create_file (dev, &dev_attr_bcdDevice);
device_create_file (dev, &dev_attr_bDeviceClass);
device_create_file (dev, &dev_attr_bDeviceSubClass);
device_create_file (dev, &dev_attr_bDeviceProtocol);
if (udev->descriptor.iManufacturer)
device_create_file (dev, &dev_attr_manufacturer);
if (udev->descriptor.iProduct)
device_create_file (dev, &dev_attr_product);
if (udev->descriptor.iSerialNumber)
device_create_file (dev, &dev_attr_serial);
}
/* Interface fields */
#define usb_intf_attr(field, format_string) \
static ssize_t \
show_##field (struct device *dev, char *buf, size_t count, loff_t off) \
{ \
struct usb_interface *intf; \
int alt; \
\
if (off) \
return 0; \
\
intf = to_usb_interface (dev); \
alt = intf->act_altsetting; \
\
return sprintf (buf, format_string, intf->altsetting[alt].field); \
} \
static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
usb_intf_attr (bAlternateSetting, "%2d\n")
usb_intf_attr (bInterfaceClass, "%02x\n")
usb_intf_attr (bInterfaceSubClass, "%02x\n")
usb_intf_attr (bInterfaceProtocol, "%02x\n")
void usb_create_driverfs_intf_files (struct usb_interface *intf)
{
device_create_file (&intf->dev, &dev_attr_bAlternateSetting);
device_create_file (&intf->dev, &dev_attr_bInterfaceClass);
device_create_file (&intf->dev, &dev_attr_bInterfaceSubClass);
device_create_file (&intf->dev, &dev_attr_bInterfaceProtocol);
}
......@@ -1024,6 +1024,11 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
*/
urb = usb_get_urb (urb);
if (urb->dev == hcd->self.root_hub) {
/* NOTE: requirement on hub callers (usbfs and the hub
* driver, for now) that URBs' urb->transfer_buffer be
* valid and usb_buffer_{sync,unmap}() not be needed, since
* they could clobber root hub response data.
*/
urb->transfer_flags |= URB_NO_DMA_MAP;
return rh_urb_enqueue (hcd, urb);
}
......@@ -1132,11 +1137,11 @@ static int hcd_unlink_urb (struct urb *urb)
goto done;
}
/* For non-periodic transfers, any status except -EINPROGRESS means
* the HCD has already started to unlink this URB from the hardware.
* In that case, there's no more work to do.
/* Except for interrupt transfers, any status except -EINPROGRESS
* means the HCD already started to unlink this URB from the hardware.
* So there's no more work to do.
*
* For periodic transfers, this is the only way to trigger unlinking
* For interrupt transfers, this is the only way to trigger unlinking
* from the hardware. Since we (currently) overload urb->status to
* tell the driver to unlink, error status might get clobbered ...
* unless that transfer hasn't yet restarted. One such case is when
......@@ -1144,14 +1149,11 @@ static int hcd_unlink_urb (struct urb *urb)
*
* FIXME use an URB_UNLINKED flag to match URB_TIMEOUT_KILLED
*/
switch (usb_pipetype (urb->pipe)) {
case PIPE_CONTROL:
case PIPE_BULK:
if (urb->status != -EINPROGRESS) {
if (urb->status != -EINPROGRESS
&& usb_pipetype (urb->pipe) != PIPE_INTERRUPT) {
retval = -EINVAL;
goto done;
}
}
/* maybe set up to block on completion notification */
if ((urb->transfer_flags & USB_TIMEOUT_KILLED))
......
......@@ -537,7 +537,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
dev_set_drvdata (&intf->dev, hub);
if (usb_hub_configure(hub, endpoint) >= 0) {
strcpy (intf->dev.name, "Hub/Port Status Changes");
strcpy (intf->dev.name, "Hub");
return 0;
}
......@@ -547,8 +547,11 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
return -ENODEV;
}
static int hub_ioctl(struct usb_device *hub, unsigned int code, void *user_data)
static int
hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
{
struct usb_device *hub = interface_to_usbdev (intf);
/* assert ifno == 0 (part of hub spec) */
switch (code) {
case USBDEVFS_HUB_PORTINFO: {
......
This diff is collapsed.
......@@ -232,22 +232,19 @@ int usb_submit_urb(struct urb *urb, int mem_flags)
return -EMSGSIZE;
}
/* periodic transfers limit size per frame/uframe,
* but drivers only control those sizes for ISO.
* while we're checking, initialize return status.
*/
if (temp == PIPE_ISOCHRONOUS) {
int n, len;
/* "high bandwidth" mode, 1-3 packets/uframe? */
if (dev->speed == USB_SPEED_HIGH) {
int mult;
switch (temp) {
case PIPE_ISOCHRONOUS:
case PIPE_INTERRUPT:
mult = 1 + ((max >> 11) & 0x03);
int mult = 1 + ((max >> 11) & 0x03);
max &= 0x03ff;
max *= mult;
}
}
/* periodic transfers limit size per frame/uframe */
switch (temp) {
case PIPE_ISOCHRONOUS: {
int n, len;
if (urb->number_of_packets <= 0)
return -EINVAL;
......@@ -255,13 +252,9 @@ int usb_submit_urb(struct urb *urb, int mem_flags)
len = urb->iso_frame_desc [n].length;
if (len < 0 || len > max)
return -EMSGSIZE;
urb->iso_frame_desc [n].status = -EXDEV;
urb->iso_frame_desc [n].actual_length = 0;
}
}
break;
case PIPE_INTERRUPT:
if (urb->transfer_buffer_length > max)
return -EMSGSIZE;
}
/* the I/O buffer must be mapped/unmapped, except when length=0 */
......
......@@ -42,6 +42,7 @@
#include <linux/usb.h>
#include "hcd.h"
#include "usb.h"
extern int usb_hub_init(void);
extern void usb_hub_cleanup(void);
......@@ -123,6 +124,8 @@ int usb_device_remove(struct device *dev)
if (driver->owner) {
m = try_inc_mod_count(driver->owner);
if (m == 0) {
// FIXME this happens even when we just rmmod
// drivers that aren't in active use...
err("Dieing driver still bound to device.\n");
return -EIO;
}
......@@ -524,9 +527,8 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
if (!dev)
return -ENODEV;
/* check for generic driver, we do not call do hotplug calls for it */
if (dev->driver == &usb_generic_driver)
return -ENODEV;
return 0;
intf = to_usb_interface(dev);
if (!intf)
......@@ -629,98 +631,6 @@ static int usb_hotplug (struct device *dev, char **envp,
#endif /* CONFIG_HOTPLUG */
/* driverfs files */
/* devices have one current configuration, with one
* or more interfaces that are used concurrently
*/
static ssize_t
show_config (struct device *dev, char *buf, size_t count, loff_t off)
{
struct usb_device *udev;
if (off)
return 0;
udev = to_usb_device (dev);
return sprintf (buf, "%u\n", udev->actconfig->bConfigurationValue);
}
static DEVICE_ATTR(configuration,S_IRUGO,show_config,NULL);
/* interfaces have one current setting; alternates
* can have different endpoints and class info.
*/
static ssize_t
show_altsetting (struct device *dev, char *buf, size_t count, loff_t off)
{
struct usb_interface *interface;
if (off)
return 0;
interface = to_usb_interface (dev);
return sprintf (buf, "%u\n", interface->altsetting->bAlternateSetting);
}
static DEVICE_ATTR(altsetting,S_IRUGO,show_altsetting,NULL);
/* product driverfs file */
static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t off)
{
struct usb_device *udev;
int len;
if (off)
return 0;
udev = to_usb_device (dev);
len = usb_string(udev, udev->descriptor.iProduct, buf, PAGE_SIZE);
if (len < 0)
return 0;
buf[len] = '\n';
buf[len+1] = 0;
return len+1;
}
static DEVICE_ATTR(product,S_IRUGO,show_product,NULL);
/* manufacturer driverfs file */
static ssize_t
show_manufacturer (struct device *dev, char *buf, size_t count, loff_t off)
{
struct usb_device *udev;
int len;
if (off)
return 0;
udev = to_usb_device (dev);
len = usb_string(udev, udev->descriptor.iManufacturer, buf, PAGE_SIZE);
if (len < 0)
return 0;
buf[len] = '\n';
buf[len+1] = 0;
return len+1;
}
static DEVICE_ATTR(manufacturer,S_IRUGO,show_manufacturer,NULL);
/* serial number driverfs file */
static ssize_t
show_serial (struct device *dev, char *buf, size_t count, loff_t off)
{
struct usb_device *udev;
int len;
if (off)
return 0;
udev = to_usb_device (dev);
len = usb_string(udev, udev->descriptor.iSerialNumber, buf, PAGE_SIZE);
if (len < 0)
return 0;
buf[len] = '\n';
buf[len+1] = 0;
return len+1;
}
static DEVICE_ATTR(serial,S_IRUGO,show_serial,NULL);
/**
* usb_alloc_dev - allocate a usb device structure (usbcore-internal)
* @parent: hub to which device is connected
......@@ -1133,13 +1043,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
return err;
/* add the USB device specific driverfs files */
device_create_file (&dev->dev, &dev_attr_configuration);
if (dev->descriptor.iManufacturer)
device_create_file (&dev->dev, &dev_attr_manufacturer);
if (dev->descriptor.iProduct)
device_create_file (&dev->dev, &dev_attr_product);
if (dev->descriptor.iSerialNumber)
device_create_file (&dev->dev, &dev_attr_serial);
usb_create_driverfs_dev_files (dev);
/* Register all of the interfaces for this device with the driver core.
* Remember, interfaces get bound to drivers, not devices. */
......@@ -1169,7 +1073,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
}
dbg ("%s - registering %s", __FUNCTION__, interface->dev.bus_id);
device_register (&interface->dev);
device_create_file (&interface->dev, &dev_attr_altsetting);
usb_create_driverfs_intf_files (interface);
}
/* add a /proc/bus/usb entry */
......@@ -1194,6 +1098,8 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
* avoid behaviors like using "DMA bounce buffers", or tying down I/O mapping
* hardware for long idle periods. The implementation varies between
* platforms, depending on details of how DMA will work to this device.
* Using these buffers also helps prevent cacheline sharing problems on
* architectures where CPU caches are not DMA-coherent.
*
* When the buffer is no longer used, free it with usb_buffer_free().
*/
......
/* Functions local to drivers/usb/core/ */
extern void usb_create_driverfs_dev_files (struct usb_device *dev);
extern void usb_create_driverfs_intf_files (struct usb_interface *intf);
......@@ -749,7 +749,7 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
default:
spin_lock_irqsave (&ehci->lock, flags);
if (ehci->reclaim) {
dbg ("dq %p: reclaim = %p, %s",
vdbg ("dq %p: reclaim = %p, %s",
qh, ehci->reclaim, RUN_CONTEXT);
if (qh == ehci->reclaim) {
/* unlinking qh for another queued urb? */
......
......@@ -255,23 +255,23 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
struct urb *urb = qtd->urb;
u32 token = 0;
/* hc's on-chip qh overlay cache can overwrite our idea of
* next qtd ptrs, if we appended a qtd while the queue was
* advancing. (because we don't use dummy qtds.)
*/
if (cpu_to_le32 (qtd->qtd_dma) == qh->hw_current
&& qtd->hw_next != qh->hw_qtd_next) {
qh->hw_alt_next = qtd->hw_alt_next;
qh->hw_qtd_next = qtd->hw_next;
COUNT (ehci->stats.qpatch);
}
/* clean up any state from previous QTD ...*/
if (last) {
if (likely (last->urb != urb)) {
ehci_urb_done (ehci, last->urb);
count++;
}
/* qh overlays can have HC's old cached copies of
* next qtd ptrs, if an URB was queued afterwards.
*/
if (cpu_to_le32 (last->qtd_dma) == qh->hw_current
&& last->hw_next != qh->hw_qtd_next) {
qh->hw_alt_next = last->hw_alt_next;
qh->hw_qtd_next = last->hw_next;
COUNT (ehci->stats.qpatch);
}
ehci_qtd_free (ehci, last);
last = 0;
}
......@@ -529,7 +529,8 @@ qh_urb_transaction (
}
/* by default, enable interrupt on urb completion */
if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT)))
// ... do it always, unless we switch over to dummy qtds
// if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT)))
qtd->hw_token |= __constant_cpu_to_le32 (QTD_IOC);
return head;
......@@ -785,7 +786,6 @@ static struct ehci_qh *qh_append_tds (
/* append to tds already queued to this qh? */
if (unlikely (!list_empty (&qh->qtd_list) && qtd)) {
struct ehci_qtd *last_qtd;
int short_rx = 0;
u32 hw_next;
/* update the last qtd's "next" pointer */
......@@ -800,23 +800,16 @@ static struct ehci_qh *qh_append_tds (
&& (epnum & 0x10)) {
// only the last QTD for now
last_qtd->hw_alt_next = hw_next;
short_rx = 1;
}
/* Adjust any old copies in qh overlay too.
* Interrupt code must cope with case of HC having it
* cached, and clobbering these updates.
* ... complicates getting rid of extra interrupts!
* (Or: use dummy td, so cache always stays valid.)
/* qh_completions() may need to patch the qh overlay if
* the hc was advancing this queue while we appended.
* we know it can: last_qtd->hw_token has IOC set.
*
* or: use a dummy td (so the overlay gets the next td
* only when we set its active bit); fewer irqs.
*/
if (qh->hw_current == cpu_to_le32 (last_qtd->qtd_dma)) {
wmb ();
qh->hw_qtd_next = hw_next;
if (short_rx)
qh->hw_alt_next = hw_next
| (qh->hw_alt_next & 0x1e);
vdbg ("queue to qh %p, patch", qh);
}
/* no URB queued */
} else {
......
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