Commit 26abd53d authored by Tony Luck's avatar Tony Luck

auto merge with /home/aegl/GIT/linus

parents ff89bf3b 8f5bb043
......@@ -14,7 +14,7 @@
</authorgroup>
<copyright>
<year>2003</year>
<year>2003-2005</year>
<holder>Jeff Garzik</holder>
</copyright>
......@@ -44,30 +44,38 @@
<toc></toc>
<chapter id="libataThanks">
<title>Thanks</title>
<para>
The bulk of the ATA knowledge comes thanks to long conversations with
Andre Hedrick (www.linux-ide.org).
</para>
<chapter id="libataIntroduction">
<title>Introduction</title>
<para>
Thanks to Alan Cox for pointing out similarities
between SATA and SCSI, and in general for motivation to hack on
libata.
libATA is a library used inside the Linux kernel to support ATA host
controllers and devices. libATA provides an ATA driver API, class
transports for ATA and ATAPI devices, and SCSI&lt;-&gt;ATA translation
for ATA devices according to the T10 SAT specification.
</para>
<para>
libata's device detection
method, ata_pio_devchk, and in general all the early probing was
based on extensive study of Hale Landis's probe/reset code in his
ATADRVR driver (www.ata-atapi.com).
This Guide documents the libATA driver API, library functions, library
internals, and a couple sample ATA low-level drivers.
</para>
</chapter>
<chapter id="libataDriverApi">
<title>libata Driver API</title>
<para>
struct ata_port_operations is defined for every low-level libata
hardware driver, and it controls how the low-level driver
interfaces with the ATA and SCSI layers.
</para>
<para>
FIS-based drivers will hook into the system with ->qc_prep() and
->qc_issue() high-level hooks. Hardware which behaves in a manner
similar to PCI IDE hardware may utilize several generic helpers,
defining at a bare minimum the bus I/O addresses of the ATA shadow
register blocks.
</para>
<sect1>
<title>struct ata_port_operations</title>
<sect2><title>Disable ATA port</title>
<programlisting>
void (*port_disable) (struct ata_port *);
</programlisting>
......@@ -78,6 +86,9 @@ void (*port_disable) (struct ata_port *);
unplug).
</para>
</sect2>
<sect2><title>Post-IDENTIFY device configuration</title>
<programlisting>
void (*dev_config) (struct ata_port *, struct ata_device *);
</programlisting>
......@@ -88,6 +99,9 @@ void (*dev_config) (struct ata_port *, struct ata_device *);
issue of SET FEATURES - XFER MODE, and prior to operation.
</para>
</sect2>
<sect2><title>Set PIO/DMA mode</title>
<programlisting>
void (*set_piomode) (struct ata_port *, struct ata_device *);
void (*set_dmamode) (struct ata_port *, struct ata_device *);
......@@ -108,6 +122,9 @@ void (*post_set_mode) (struct ata_port *ap);
->set_dma_mode() is only called if DMA is possible.
</para>
</sect2>
<sect2><title>Taskfile read/write</title>
<programlisting>
void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
......@@ -120,6 +137,9 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
taskfile register values.
</para>
</sect2>
<sect2><title>ATA command execute</title>
<programlisting>
void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
</programlisting>
......@@ -129,17 +149,37 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
->tf_load(), to be initiated in hardware.
</para>
</sect2>
<sect2><title>Per-cmd ATAPI DMA capabilities filter</title>
<programlisting>
int (*check_atapi_dma) (struct ata_queued_cmd *qc);
</programlisting>
<para>
Allow low-level driver to filter ATA PACKET commands, returning a status
indicating whether or not it is OK to use DMA for the supplied PACKET
command.
</para>
</sect2>
<sect2><title>Read specific ATA shadow registers</title>
<programlisting>
u8 (*check_status)(struct ata_port *ap);
void (*dev_select)(struct ata_port *ap, unsigned int device);
u8 (*check_altstatus)(struct ata_port *ap);
u8 (*check_err)(struct ata_port *ap);
</programlisting>
<para>
Reads the Status ATA shadow register from hardware. On some
hardware, this has the side effect of clearing the interrupt
condition.
Reads the Status/AltStatus/Error ATA shadow register from
hardware. On some hardware, reading the Status register has
the side effect of clearing the interrupt condition.
</para>
</sect2>
<sect2><title>Select ATA device on bus</title>
<programlisting>
void (*dev_select)(struct ata_port *ap, unsigned int device);
</programlisting>
......@@ -147,9 +187,13 @@ void (*dev_select)(struct ata_port *ap, unsigned int device);
<para>
Issues the low-level hardware command(s) that causes one of N
hardware devices to be considered 'selected' (active and
available for use) on the ATA bus.
available for use) on the ATA bus. This generally has no
meaning on FIS-based devices.
</para>
</sect2>
<sect2><title>Reset ATA bus</title>
<programlisting>
void (*phy_reset) (struct ata_port *ap);
</programlisting>
......@@ -162,17 +206,31 @@ void (*phy_reset) (struct ata_port *ap);
functions ata_bus_reset() or sata_phy_reset() for this hook.
</para>
</sect2>
<sect2><title>Control PCI IDE BMDMA engine</title>
<programlisting>
void (*bmdma_setup) (struct ata_queued_cmd *qc);
void (*bmdma_start) (struct ata_queued_cmd *qc);
void (*bmdma_stop) (struct ata_port *ap);
u8 (*bmdma_status) (struct ata_port *ap);
</programlisting>
<para>
When setting up an IDE BMDMA transaction, these hooks arm
(->bmdma_setup) and fire (->bmdma_start) the hardware's DMA
engine.
When setting up an IDE BMDMA transaction, these hooks arm
(->bmdma_setup), fire (->bmdma_start), and halt (->bmdma_stop)
the hardware's DMA engine. ->bmdma_status is used to read the standard
PCI IDE DMA Status register.
</para>
<para>
These hooks are typically either no-ops, or simply not implemented, in
FIS-based drivers.
</para>
</sect2>
<sect2><title>High-level taskfile hooks</title>
<programlisting>
void (*qc_prep) (struct ata_queued_cmd *qc);
int (*qc_issue) (struct ata_queued_cmd *qc);
......@@ -190,20 +248,26 @@ int (*qc_issue) (struct ata_queued_cmd *qc);
->qc_issue is used to make a command active, once the hardware
and S/G tables have been prepared. IDE BMDMA drivers use the
helper function ata_qc_issue_prot() for taskfile protocol-based
dispatch. More advanced drivers roll their own ->qc_issue
implementation, using this as the "issue new ATA command to
hardware" hook.
dispatch. More advanced drivers implement their own ->qc_issue.
</para>
</sect2>
<sect2><title>Timeout (error) handling</title>
<programlisting>
void (*eng_timeout) (struct ata_port *ap);
</programlisting>
<para>
This is a high level error handling function, called from the
error handling thread, when a command times out.
This is a high level error handling function, called from the
error handling thread, when a command times out. Most newer
hardware will implement its own error handling code here. IDE BMDMA
drivers may use the helper function ata_eng_timeout().
</para>
</sect2>
<sect2><title>Hardware interrupt handling</title>
<programlisting>
irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
void (*irq_clear) (struct ata_port *);
......@@ -216,6 +280,9 @@ void (*irq_clear) (struct ata_port *);
is quiet.
</para>
</sect2>
<sect2><title>SATA phy read/write</title>
<programlisting>
u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
......@@ -227,6 +294,9 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
if ->phy_reset hook called the sata_phy_reset() helper function.
</para>
</sect2>
<sect2><title>Init and shutdown</title>
<programlisting>
int (*port_start) (struct ata_port *ap);
void (*port_stop) (struct ata_port *ap);
......@@ -240,15 +310,17 @@ void (*host_stop) (struct ata_host_set *host_set);
tasks.
</para>
<para>
->host_stop() is called when the rmmod or hot unplug process
begins. The hook must stop all hardware interrupts, DMA
engines, etc.
</para>
<para>
->port_stop() is called after ->host_stop(). It's sole function
is to release DMA/memory resources, now that they are no longer
actively being used.
</para>
<para>
->host_stop() is called after all ->port_stop() calls
have completed. The hook must finalize hardware shutdown, release DMA
and other resources, etc.
</para>
</sect2>
</sect1>
</chapter>
......@@ -279,4 +351,24 @@ void (*host_stop) (struct ata_host_set *host_set);
!Idrivers/scsi/sata_sil.c
</chapter>
<chapter id="libataThanks">
<title>Thanks</title>
<para>
The bulk of the ATA knowledge comes thanks to long conversations with
Andre Hedrick (www.linux-ide.org), and long hours pondering the ATA
and SCSI specifications.
</para>
<para>
Thanks to Alan Cox for pointing out similarities
between SATA and SCSI, and in general for motivation to hack on
libata.
</para>
<para>
libata's device detection
method, ata_pio_devchk, and in general all the early probing was
based on extensive study of Hale Landis's probe/reset code in his
ATADRVR driver (www.ata-atapi.com).
</para>
</chapter>
</book>
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 12
EXTRAVERSION =-rc5
EXTRAVERSION =-rc6
NAME=Woozy Numbat
# *DOCUMENTATION*
......
......@@ -45,11 +45,13 @@ asmlinkage void ret_from_fork(void);
*/
void default_idle(void)
{
while(1) {
if (need_resched())
local_irq_disable();
while (!need_resched()) {
/* This stop will re-enable interrupts */
__asm__("stop #0x2000" : : : "cc");
schedule();
local_irq_disable();
}
local_irq_enable();
}
void (*idle)(void) = default_idle;
......@@ -63,7 +65,12 @@ void (*idle)(void) = default_idle;
void cpu_idle(void)
{
/* endless idle loop with no priority at all */
while (1) {
idle();
preempt_enable_no_resched();
schedule();
preempt_disable();
}
}
void machine_restart(char * __unused)
......
......@@ -619,7 +619,7 @@ _GLOBAL(flush_instruction_cache)
_GLOBAL(flush_icache_range)
BEGIN_FTR_SECTION
blr /* for 601, do nothing */
END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
li r5,L1_CACHE_LINE_SIZE-1
andc r3,r3,r5
subf r4,r3,r4
......@@ -736,7 +736,7 @@ _GLOBAL(flush_dcache_all)
_GLOBAL(__flush_dcache_icache)
BEGIN_FTR_SECTION
blr /* for 601, do nothing */
END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
rlwinm r3,r3,0,0,19 /* Get page base address */
li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */
mtctr r4
......@@ -764,7 +764,7 @@ END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
_GLOBAL(__flush_dcache_icache_phys)
BEGIN_FTR_SECTION
blr /* for 601, do nothing */
END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
mfmsr r10
rlwinm r0,r10,0,28,26 /* clear DR */
mtmsr r0
......
......@@ -1370,7 +1370,7 @@ static int __init prom_find_machine_type(void)
}
/* Default to pSeries. We need to know if we are running LPAR */
rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
if (!PHANDLE_VALID(rtas)) {
if (PHANDLE_VALID(rtas)) {
int x = prom_getproplen(rtas, "ibm,hypertas-functions");
if (x != PROM_ERROR) {
prom_printf("Hypertas detected, assuming LPAR !\n");
......
......@@ -28,6 +28,7 @@
//#include <linux/kernel_stat.h>
#include <linux/notifier.h>
#include <linux/cpu.h>
#include <linux/workqueue.h>
#include "appldata.h"
......@@ -133,9 +134,12 @@ static int appldata_interval = APPLDATA_CPU_INTERVAL;
static int appldata_timer_active;
/*
* Tasklet
* Work queue
*/
static struct tasklet_struct appldata_tasklet_struct;
static struct workqueue_struct *appldata_wq;
static void appldata_work_fn(void *data);
static DECLARE_WORK(appldata_work, appldata_work_fn, NULL);
/*
* Ops list
......@@ -144,11 +148,11 @@ static DEFINE_SPINLOCK(appldata_ops_lock);
static LIST_HEAD(appldata_ops_list);
/************************* timer, tasklet, DIAG ******************************/
/*************************** timer, work, DIAG *******************************/
/*
* appldata_timer_function()
*
* schedule tasklet and reschedule timer
* schedule work and reschedule timer
*/
static void appldata_timer_function(unsigned long data, struct pt_regs *regs)
{
......@@ -157,22 +161,22 @@ static void appldata_timer_function(unsigned long data, struct pt_regs *regs)
atomic_read(&appldata_expire_count));
if (atomic_dec_and_test(&appldata_expire_count)) {
atomic_set(&appldata_expire_count, num_online_cpus());
tasklet_schedule((struct tasklet_struct *) data);
queue_work(appldata_wq, (struct work_struct *) data);
}
}
/*
* appldata_tasklet_function()
* appldata_work_fn()
*
* call data gathering function for each (active) module
*/
static void appldata_tasklet_function(unsigned long data)
static void appldata_work_fn(void *data)
{
struct list_head *lh;
struct appldata_ops *ops;
int i;
P_DEBUG(" -= Tasklet =-\n");
P_DEBUG(" -= Work Queue =-\n");
i = 0;
spin_lock(&appldata_ops_lock);
list_for_each(lh, &appldata_ops_list) {
......@@ -231,7 +235,7 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer,
: "=d" (ry) : "d" (&(appldata_parameter_list)) : "cc");
return (int) ry;
}
/********************** timer, tasklet, DIAG <END> ***************************/
/************************ timer, work, DIAG <END> ****************************/
/****************************** /proc stuff **********************************/
......@@ -411,7 +415,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
struct list_head *lh;
found = 0;
spin_lock_bh(&appldata_ops_lock);
spin_lock(&appldata_ops_lock);
list_for_each(lh, &appldata_ops_list) {
tmp_ops = list_entry(lh, struct appldata_ops, list);
if (&tmp_ops->ctl_table[2] == ctl) {
......@@ -419,15 +423,15 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
}
}
if (!found) {
spin_unlock_bh(&appldata_ops_lock);
spin_unlock(&appldata_ops_lock);
return -ENODEV;
}
ops = ctl->data;
if (!try_module_get(ops->owner)) { // protect this function
spin_unlock_bh(&appldata_ops_lock);
spin_unlock(&appldata_ops_lock);
return -ENODEV;
}
spin_unlock_bh(&appldata_ops_lock);
spin_unlock(&appldata_ops_lock);
if (!*lenp || *ppos) {
*lenp = 0;
......@@ -451,10 +455,11 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
return -EFAULT;
}
spin_lock_bh(&appldata_ops_lock);
spin_lock(&appldata_ops_lock);
if ((buf[0] == '1') && (ops->active == 0)) {
if (!try_module_get(ops->owner)) { // protect tasklet
spin_unlock_bh(&appldata_ops_lock);
// protect work queue callback
if (!try_module_get(ops->owner)) {
spin_unlock(&appldata_ops_lock);
module_put(ops->owner);
return -ENODEV;
}
......@@ -485,7 +490,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
}
module_put(ops->owner);
}
spin_unlock_bh(&appldata_ops_lock);
spin_unlock(&appldata_ops_lock);
out:
*lenp = len;
*ppos += len;
......@@ -529,7 +534,7 @@ int appldata_register_ops(struct appldata_ops *ops)
}
memset(ops->ctl_table, 0, 4*sizeof(struct ctl_table));
spin_lock_bh(&appldata_ops_lock);
spin_lock(&appldata_ops_lock);
list_for_each(lh, &appldata_ops_list) {
tmp_ops = list_entry(lh, struct appldata_ops, list);
P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n",
......@@ -541,18 +546,18 @@ int appldata_register_ops(struct appldata_ops *ops)
APPLDATA_PROC_NAME_LENGTH) == 0) {
P_ERROR("Name \"%s\" already registered!\n", ops->name);
kfree(ops->ctl_table);
spin_unlock_bh(&appldata_ops_lock);
spin_unlock(&appldata_ops_lock);
return -EBUSY;
}
if (tmp_ops->ctl_nr == ops->ctl_nr) {
P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr);
kfree(ops->ctl_table);
spin_unlock_bh(&appldata_ops_lock);
spin_unlock(&appldata_ops_lock);
return -EBUSY;
}
}
list_add(&ops->list, &appldata_ops_list);
spin_unlock_bh(&appldata_ops_lock);
spin_unlock(&appldata_ops_lock);
ops->ctl_table[0].ctl_name = CTL_APPLDATA;
ops->ctl_table[0].procname = appldata_proc_name;
......@@ -583,12 +588,12 @@ int appldata_register_ops(struct appldata_ops *ops)
*/
void appldata_unregister_ops(struct appldata_ops *ops)
{
spin_lock_bh(&appldata_ops_lock);
spin_lock(&appldata_ops_lock);
unregister_sysctl_table(ops->sysctl_header);
list_del(&ops->list);
kfree(ops->ctl_table);
ops->ctl_table = NULL;
spin_unlock_bh(&appldata_ops_lock);
spin_unlock(&appldata_ops_lock);
P_INFO("%s-ops unregistered!\n", ops->name);
}
/********************** module-ops management <END> **************************/
......@@ -602,7 +607,7 @@ appldata_online_cpu(int cpu)
init_virt_timer(&per_cpu(appldata_timer, cpu));
per_cpu(appldata_timer, cpu).function = appldata_timer_function;
per_cpu(appldata_timer, cpu).data = (unsigned long)
&appldata_tasklet_struct;
&appldata_work;
atomic_inc(&appldata_expire_count);
spin_lock(&appldata_timer_lock);
__appldata_vtimer_setup(APPLDATA_MOD_TIMER);
......@@ -615,7 +620,7 @@ appldata_offline_cpu(int cpu)
del_virt_timer(&per_cpu(appldata_timer, cpu));
if (atomic_dec_and_test(&appldata_expire_count)) {
atomic_set(&appldata_expire_count, num_online_cpus());
tasklet_schedule(&appldata_tasklet_struct);
queue_work(appldata_wq, &appldata_work);
}
spin_lock(&appldata_timer_lock);
__appldata_vtimer_setup(APPLDATA_MOD_TIMER);
......@@ -648,7 +653,7 @@ static struct notifier_block __devinitdata appldata_nb = {
/*
* appldata_init()
*
* init timer and tasklet, register /proc entries
* init timer, register /proc entries
*/
static int __init appldata_init(void)
{
......@@ -657,6 +662,12 @@ static int __init appldata_init(void)
P_DEBUG("sizeof(parameter_list) = %lu\n",
sizeof(struct appldata_parameter_list));
appldata_wq = create_singlethread_workqueue("appldata");
if (!appldata_wq) {
P_ERROR("Could not create work queue\n");
return -ENOMEM;
}
for_each_online_cpu(i)
appldata_online_cpu(i);
......@@ -670,7 +681,6 @@ static int __init appldata_init(void)
appldata_table[1].de->owner = THIS_MODULE;
#endif
tasklet_init(&appldata_tasklet_struct, appldata_tasklet_function, 0);
P_DEBUG("Base interface initialized.\n");
return 0;
}
......@@ -678,7 +688,7 @@ static int __init appldata_init(void)
/*
* appldata_exit()
*
* stop timer and tasklet, unregister /proc entries
* stop timer, unregister /proc entries
*/
static void __exit appldata_exit(void)
{
......@@ -690,7 +700,7 @@ static void __exit appldata_exit(void)
/*
* ops list should be empty, but just in case something went wrong...
*/
spin_lock_bh(&appldata_ops_lock);
spin_lock(&appldata_ops_lock);
list_for_each(lh, &appldata_ops_list) {
ops = list_entry(lh, struct appldata_ops, list);
rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC,
......@@ -700,7 +710,7 @@ static void __exit appldata_exit(void)
"return code: %d\n", ops->name, rc);
}
}
spin_unlock_bh(&appldata_ops_lock);
spin_unlock(&appldata_ops_lock);
for_each_online_cpu(i)
appldata_offline_cpu(i);
......@@ -709,7 +719,7 @@ static void __exit appldata_exit(void)
unregister_sysctl_table(appldata_sysctl_header);
tasklet_kill(&appldata_tasklet_struct);
destroy_workqueue(appldata_wq);
P_DEBUG("... module unloaded!\n");
}
/**************************** init / exit <END> ******************************/
......
......@@ -68,7 +68,7 @@ struct appldata_mem_data {
u64 pgmajfault; /* page faults (major only) */
// <-- New in 2.6
} appldata_mem_data;
} __attribute__((packed)) appldata_mem_data;
static inline void appldata_debug_print(struct appldata_mem_data *mem_data)
......
......@@ -57,7 +57,7 @@ struct appldata_net_sum_data {
u64 rx_dropped; /* no space in linux buffers */
u64 tx_dropped; /* no space available in linux */
u64 collisions; /* collisions while transmitting */
} appldata_net_sum_data;
} __attribute__((packed)) appldata_net_sum_data;
static inline void appldata_print_debug(struct appldata_net_sum_data *net_data)
......
......@@ -49,7 +49,7 @@ struct appldata_os_per_cpu {
u32 per_cpu_softirq; /* ... spent in softirqs */
u32 per_cpu_iowait; /* ... spent while waiting for I/O */
// <-- New in 2.6
};
} __attribute__((packed));
struct appldata_os_data {
u64 timestamp;
......@@ -75,7 +75,7 @@ struct appldata_os_data {
/* per cpu data */
struct appldata_os_per_cpu os_cpu[0];
};
} __attribute__((packed));
static struct appldata_os_data *appldata_os_data;
......
......@@ -40,6 +40,7 @@
#include <asm/pgalloc.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
#ifdef CONFIG_S390_SUPPORT
#include "compat_ptrace.h"
......@@ -130,13 +131,19 @@ static int
peek_user(struct task_struct *child, addr_t addr, addr_t data)
{
struct user *dummy = NULL;
addr_t offset, tmp;
addr_t offset, tmp, mask;
/*
* Stupid gdb peeks/pokes the access registers in 64 bit with
* an alignment of 4. Programmers from hell...
*/
if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK)
mask = __ADDR_MASK;
#ifdef CONFIG_ARCH_S390X
if (addr >= (addr_t) &dummy->regs.acrs &&
addr < (addr_t) &dummy->regs.orig_gpr2)
mask = 3;
#endif
if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
return -EIO;
if (addr < (addr_t) &dummy->regs.acrs) {
......@@ -153,6 +160,16 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
* access registers are stored in the thread structure
*/
offset = addr - (addr_t) &dummy->regs.acrs;
#ifdef CONFIG_ARCH_S390X
/*
* Very special case: old & broken 64 bit gdb reading
* from acrs[15]. Result is a 64 bit value. Read the
* 32 bit acrs[15] value and shift it by 32. Sick...
*/
if (addr == (addr_t) &dummy->regs.acrs[15])
tmp = ((unsigned long) child->thread.acrs[15]) << 32;
else
#endif
tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset);
} else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
......@@ -167,6 +184,9 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
*/
offset = addr - (addr_t) &dummy->regs.fp_regs;
tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset);
if (addr == (addr_t) &dummy->regs.fp_regs.fpc)
tmp &= (unsigned long) FPC_VALID_MASK
<< (BITS_PER_LONG - 32);
} else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
/*
......@@ -191,13 +211,19 @@ static int
poke_user(struct task_struct *child, addr_t addr, addr_t data)
{
struct user *dummy = NULL;
addr_t offset;
addr_t offset, mask;
/*
* Stupid gdb peeks/pokes the access registers in 64 bit with
* an alignment of 4. Programmers from hell indeed...
*/
if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK)
mask = __ADDR_MASK;
#ifdef CONFIG_ARCH_S390X
if (addr >= (addr_t) &dummy->regs.acrs &&
addr < (addr_t) &dummy->regs.orig_gpr2)
mask = 3;
#endif
if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
return -EIO;
if (addr < (addr_t) &dummy->regs.acrs) {
......@@ -224,6 +250,17 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
* access registers are stored in the thread structure
*/
offset = addr - (addr_t) &dummy->regs.acrs;
#ifdef CONFIG_ARCH_S390X
/*
* Very special case: old & broken 64 bit gdb writing
* to acrs[15] with a 64 bit value. Ignore the lower
* half of the value and write the upper 32 bit to
* acrs[15]. Sick...
*/
if (addr == (addr_t) &dummy->regs.acrs[15])
child->thread.acrs[15] = (unsigned int) (data >> 32);
else
#endif
*(addr_t *)((addr_t) &child->thread.acrs + offset) = data;
} else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
......@@ -237,7 +274,8 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
* floating point regs. are stored in the thread structure
*/
if (addr == (addr_t) &dummy->regs.fp_regs.fpc &&
(data & ~FPC_VALID_MASK) != 0)
(data & ~((unsigned long) FPC_VALID_MASK
<< (BITS_PER_LONG - 32))) != 0)
return -EINVAL;
offset = addr - (addr_t) &dummy->regs.fp_regs;
*(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data;
......@@ -722,6 +760,13 @@ syscall_trace(struct pt_regs *regs, int entryexit)
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0));
/*
* If the debuffer has set an invalid system call number,
* we prepare to skip the system call restart handling.
*/
if (!entryexit && regs->gprs[2] >= NR_syscalls)
regs->trap = -1;
/*
* this isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the
......
......@@ -207,7 +207,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
* we are not in an interrupt and that there is a
* user context.
*/
if (user_address == 0 || in_interrupt() || !mm)
if (user_address == 0 || in_atomic() || !mm)
goto no_context;
/*
......
......@@ -39,7 +39,8 @@ ifeq ($(CONFIG_ATM_FORE200E_PCA),y)
fore_200e-objs += fore200e_pca_fw.o
# guess the target endianess to choose the right PCA-200E firmware image
ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y)
CONFIG_ATM_FORE200E_PCA_FW = $(shell if test -n "`$(CC) -E -dM $(src)/../../include/asm/byteorder.h | grep ' __LITTLE_ENDIAN '`"; then echo $(obj)/pca200e.bin; else echo $(obj)/pca200e_ecd.bin2; fi)
byteorder.h := include$(if $(patsubst $(srctree),,$(objtree)),2)/asm/byteorder.h
CONFIG_ATM_FORE200E_PCA_FW := $(obj)/pca200e$(if $(shell $(CC) -E -dM $(byteorder.h) | grep ' __LITTLE_ENDIAN '),.bin,_ecd.bin2)
endif
endif
......
......@@ -383,7 +383,6 @@ fore200e_shutdown(struct fore200e* fore200e)
switch(fore200e->state) {
case FORE200E_STATE_COMPLETE:
if (fore200e->stats)
kfree(fore200e->stats);
case FORE200E_STATE_IRQ:
......@@ -963,7 +962,6 @@ fore200e_tx_irq(struct fore200e* fore200e)
entry, txq->tail, entry->vc_map, entry->skb);
/* free copy of misaligned data */
if (entry->data)
kfree(entry->data);
/* remove DMA mapping */
......
......@@ -412,7 +412,6 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
init_one_failure:
if (atm_dev)
atm_dev_deregister(atm_dev);
if (he_dev)
kfree(he_dev);
pci_disable_device(pci_dev);
return err;
......@@ -2534,7 +2533,6 @@ he_open(struct atm_vcc *vcc)
open_failed:
if (err) {
if (he_vcc)
kfree(he_vcc);
clear_bit(ATM_VF_ADDR, &vcc->flags);
}
......
......@@ -676,10 +676,10 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
PRINTK("nicstar%d: RSQ base at 0x%x.\n", i, (u32) card->rsq.base);
/* Initialize SCQ0, the only VBR SCQ used */
card->scq1 = (scq_info *) NULL;
card->scq2 = (scq_info *) NULL;
card->scq1 = NULL;
card->scq2 = NULL;
card->scq0 = get_scq(VBR_SCQSIZE, NS_VRSCD0);
if (card->scq0 == (scq_info *) NULL)
if (card->scq0 == NULL)
{
printk("nicstar%d: can't get SCQ0.\n", i);
error = 12;
......@@ -993,24 +993,24 @@ static scq_info *get_scq(int size, u32 scd)
int i;
if (size != VBR_SCQSIZE && size != CBR_SCQSIZE)
return (scq_info *) NULL;
return NULL;
scq = (scq_info *) kmalloc(sizeof(scq_info), GFP_KERNEL);
if (scq == (scq_info *) NULL)
return (scq_info *) NULL;
if (scq == NULL)
return NULL;
scq->org = kmalloc(2 * size, GFP_KERNEL);
if (scq->org == NULL)
{
kfree(scq);
return (scq_info *) NULL;
return NULL;
}
scq->skb = (struct sk_buff **) kmalloc(sizeof(struct sk_buff *) *
(size / NS_SCQE_SIZE), GFP_KERNEL);
if (scq->skb == (struct sk_buff **) NULL)
if (scq->skb == NULL)
{
kfree(scq->org);
kfree(scq);
return (scq_info *) NULL;
return NULL;
}
scq->num_entries = size / NS_SCQE_SIZE;
scq->base = (ns_scqe *) ALIGN_ADDRESS(scq->org, size);
......@@ -1498,7 +1498,7 @@ static int ns_open(struct atm_vcc *vcc)
vc->cbr_scd = NS_FRSCD + frscdi * NS_FRSCD_SIZE;
scq = get_scq(CBR_SCQSIZE, vc->cbr_scd);
if (scq == (scq_info *) NULL)
if (scq == NULL)
{
PRINTK("nicstar%d: can't get fixed rate SCQ.\n", card->index);
card->scd2vc[frscdi] = NULL;
......
......@@ -902,7 +902,7 @@ static void close_tx(struct atm_vcc *vcc)
zatm_dev->tx_bw += vcc->qos.txtp.min_pcr;
dealloc_shaper(vcc->dev,zatm_vcc->shaper);
}
if (zatm_vcc->ring) kfree(zatm_vcc->ring);
kfree(zatm_vcc->ring);
}
......@@ -1339,11 +1339,8 @@ static int __init zatm_start(struct atm_dev *dev)
return 0;
out:
for (i = 0; i < NR_MBX; i++)
if (zatm_dev->mbx_start[i] != 0)
kfree((void *) zatm_dev->mbx_start[i]);
if (zatm_dev->rx_map != NULL)
kfree(zatm_dev->mbx_start[i]);
kfree(zatm_dev->rx_map);
if (zatm_dev->tx_map != NULL)
kfree(zatm_dev->tx_map);
free_irq(zatm_dev->irq, dev);
return error;
......
This diff is collapsed.
......@@ -1995,9 +1995,6 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status)
unsigned char ch, gdl;
int ignored = 0;
int cnt = 0;
unsigned char *cp;
char *fp;
int count;
int recv_room;
int max = 256;
unsigned long flags;
......@@ -2011,10 +2008,6 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status)
//return;
}
cp = tty->flip.char_buf;
fp = tty->flip.flag_buf;
count = 0;
// following add by Victor Yu. 09-02-2002
if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) {
......@@ -2041,12 +2034,10 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status)
}
while (gdl--) {
ch = inb(info->base + UART_RX);
count++;
*cp++ = ch;
*fp++ = 0;
tty_insert_flip_char(tty, ch, 0);
cnt++;
/*
if((count>=HI_WATER) && (info->stop_rx==0)){
if((cnt>=HI_WATER) && (info->stop_rx==0)){
mxser_stoprx(tty);
info->stop_rx=1;
break;
......@@ -2061,7 +2052,7 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status)
if (max-- < 0)
break;
/*
if((count>=HI_WATER) && (info->stop_rx==0)){
if((cnt>=HI_WATER) && (info->stop_rx==0)){
mxser_stoprx(tty);
info->stop_rx=1;
break;
......@@ -2078,36 +2069,33 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status)
if (++ignored > 100)
break;
} else {
count++;
char flag = 0;
if (*status & UART_LSR_SPECIAL) {
if (*status & UART_LSR_BI) {
*fp++ = TTY_BREAK;
flag = TTY_BREAK;
/* added by casper 1/11/2000 */
info->icount.brk++;
/* */
if (info->flags & ASYNC_SAK)
do_SAK(tty);
} else if (*status & UART_LSR_PE) {
*fp++ = TTY_PARITY;
flag = TTY_PARITY;
/* added by casper 1/11/2000 */
info->icount.parity++;
/* */
} else if (*status & UART_LSR_FE) {
*fp++ = TTY_FRAME;
flag = TTY_FRAME;
/* added by casper 1/11/2000 */
info->icount.frame++;
/* */
} else if (*status & UART_LSR_OE) {
*fp++ = TTY_OVERRUN;
flag = TTY_OVERRUN;
/* added by casper 1/11/2000 */
info->icount.overrun++;
/* */
} else
*fp++ = 0;
} else
*fp++ = 0;
*cp++ = ch;
}
}
tty_insert_flip_char(tty, ch, flag);
cnt++;
if (cnt >= recv_room) {
if (!info->ldisc_stop_rx) {
......@@ -2132,7 +2120,7 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status)
// above add by Victor Yu. 09-02-2002
} while (*status & UART_LSR_DR);
end_intr: // add by Victor Yu. 09-02-2002
end_intr: // add by Victor Yu. 09-02-2002
mxvar_log.rxcnt[info->port] += cnt;
info->mon_data.rxcnt += cnt;
......
......@@ -1274,6 +1274,9 @@ static int el3_close(struct net_device *dev)
spin_lock_irqsave(&lp->window_lock, flags);
update_stats(dev);
spin_unlock_irqrestore(&lp->window_lock, flags);
/* force interrupts off */
outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
}
link->open--;
......
......@@ -1585,8 +1585,8 @@ rtl8169_hw_start(struct net_device *dev)
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
RTL_W8(EarlyTxThres, EarlyTxThld);
/* For gigabit rtl8169, MTU + header + CRC + VLAN */
RTL_W16(RxMaxSize, tp->rx_buf_sz);
/* Low hurts. Let's disable the filtering. */
RTL_W16(RxMaxSize, 16383);
/* Set Rx Config register */
i = rtl8169_rx_config |
......@@ -2127,6 +2127,11 @@ rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
}
}
static inline int rtl8169_fragmented_frame(u32 status)
{
return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag);
}
static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
{
u32 opts1 = le32_to_cpu(desc->opts1);
......@@ -2177,27 +2182,41 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
while (rx_left > 0) {
unsigned int entry = cur_rx % NUM_RX_DESC;
struct RxDesc *desc = tp->RxDescArray + entry;
u32 status;
rmb();
status = le32_to_cpu(tp->RxDescArray[entry].opts1);
status = le32_to_cpu(desc->opts1);
if (status & DescOwn)
break;
if (status & RxRES) {
printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name);
printk(KERN_INFO "%s: Rx ERROR. status = %08x\n",
dev->name, status);
tp->stats.rx_errors++;
if (status & (RxRWT | RxRUNT))
tp->stats.rx_length_errors++;
if (status & RxCRC)
tp->stats.rx_crc_errors++;
rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
} else {
struct RxDesc *desc = tp->RxDescArray + entry;
struct sk_buff *skb = tp->Rx_skbuff[entry];
int pkt_size = (status & 0x00001FFF) - 4;
void (*pci_action)(struct pci_dev *, dma_addr_t,
size_t, int) = pci_dma_sync_single_for_device;
/*
* The driver does not support incoming fragmented
* frames. They are seen as a symptom of over-mtu
* sized frames.
*/
if (unlikely(rtl8169_fragmented_frame(status))) {
tp->stats.rx_dropped++;
tp->stats.rx_length_errors++;
rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
goto move_on;
}
rtl8169_rx_csum(skb, desc);
pci_dma_sync_single_for_cpu(tp->pci_dev,
......@@ -2224,7 +2243,7 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
tp->stats.rx_bytes += pkt_size;
tp->stats.rx_packets++;
}
move_on:
cur_rx++;
rx_left--;
}
......
......@@ -100,35 +100,8 @@ static int sh_debug; /* Debug flag */
#define SHAPER_BANNER "CymruNet Traffic Shaper BETA 0.04 for Linux 2.1\n"
/*
* Locking
*/
static int shaper_lock(struct shaper *sh)
{
/*
* Lock in an interrupt must fail
*/
while (test_and_set_bit(0, &sh->locked))
{
if (!in_interrupt())
sleep_on(&sh->wait_queue);
else
return 0;
}
return 1;
}
static void shaper_kick(struct shaper *sh);
static void shaper_unlock(struct shaper *sh)
{
clear_bit(0, &sh->locked);
wake_up(&sh->wait_queue);
shaper_kick(sh);
}
/*
* Compute clocks on a buffer
*/
......@@ -157,17 +130,15 @@ static void shaper_setspeed(struct shaper *shaper, int bitspersec)
* Throw a frame at a shaper.
*/
static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb)
static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct shaper *shaper = dev->priv;
struct sk_buff *ptr;
/*
* Get ready to work on this shaper. Lock may fail if its
* an interrupt and locked.
*/
if(!shaper_lock(shaper))
if (down_trylock(&shaper->sem))
return -1;
ptr=shaper->sendq.prev;
/*
......@@ -260,7 +231,8 @@ static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb)
dev_kfree_skb(ptr);
shaper->stats.collisions++;
}
shaper_unlock(shaper);
shaper_kick(shaper);
up(&shaper->sem);
return 0;
}
......@@ -297,8 +269,13 @@ static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb)
static void shaper_timer(unsigned long data)
{
struct shaper *sh=(struct shaper *)data;
shaper_kick(sh);
struct shaper *shaper = (struct shaper *)data;
if (!down_trylock(&shaper->sem)) {
shaper_kick(shaper);
up(&shaper->sem);
} else
mod_timer(&shaper->timer, jiffies);
}
/*
......@@ -310,19 +287,6 @@ static void shaper_kick(struct shaper *shaper)
{
struct sk_buff *skb;
/*
* Shaper unlock will kick
*/
if (test_and_set_bit(0, &shaper->locked))
{
if(sh_debug)
printk("Shaper locked.\n");
mod_timer(&shaper->timer, jiffies);
return;
}
/*
* Walk the list (may be empty)
*/
......@@ -364,8 +328,6 @@ static void shaper_kick(struct shaper *shaper)
if(skb!=NULL)
mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock);
clear_bit(0, &shaper->locked);
}
......@@ -376,14 +338,12 @@ static void shaper_kick(struct shaper *shaper)
static void shaper_flush(struct shaper *shaper)
{
struct sk_buff *skb;
if(!shaper_lock(shaper))
{
printk(KERN_ERR "shaper: shaper_flush() called by an irq!\n");
return;
}
down(&shaper->sem);
while((skb=skb_dequeue(&shaper->sendq))!=NULL)
dev_kfree_skb(skb);
shaper_unlock(shaper);
shaper_kick(shaper);
up(&shaper->sem);
}
/*
......@@ -426,13 +386,6 @@ static int shaper_close(struct net_device *dev)
* ARP and other resolutions and not before.
*/
static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct shaper *sh=dev->priv;
return shaper_qframe(sh, skb);
}
static struct net_device_stats *shaper_get_stats(struct net_device *dev)
{
struct shaper *sh=dev->priv;
......@@ -623,7 +576,6 @@ static void shaper_init_priv(struct net_device *dev)
init_timer(&sh->timer);
sh->timer.function=shaper_timer;
sh->timer.data=(unsigned long)sh;
init_waitqueue_head(&sh->wait_queue);
}
/*
......
......@@ -665,15 +665,6 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
return ata_pci_init_one(pdev, port_info, n_ports);
}
/**
* piix_init -
*
* LOCKING:
*
* RETURNS:
*
*/
static int __init piix_init(void)
{
int rc;
......@@ -689,13 +680,6 @@ static int __init piix_init(void)
return 0;
}
/**
* piix_exit -
*
* LOCKING:
*
*/
static void __exit piix_exit(void)
{
pci_unregister_driver(&piix_pci_driver);
......
This diff is collapsed.
......@@ -947,7 +947,7 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
}
/**
* ata_scsiop_noop -
* ata_scsiop_noop - Command handler that simply returns success.
* @args: device IDENTIFY data / SCSI command of interest.
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* @buflen: Response buffer length.
......
......@@ -507,6 +507,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
int ret, i;
unsigned int id, lun;
unsigned long serial;
unsigned long flags;
if (!CMD_SP(cmd))
return FAILED;
......@@ -519,7 +520,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
/* Check active list for command command. */
spin_unlock_irq(ha->host->host_lock);
spin_lock(&ha->hardware_lock);
spin_lock_irqsave(&ha->hardware_lock, flags);
for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
sp = ha->outstanding_cmds[i];
......@@ -534,7 +535,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
sp->state));
DEBUG3(qla2x00_print_scsi_cmd(cmd);)
spin_unlock(&ha->hardware_lock);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (qla2x00_abort_command(ha, sp)) {
DEBUG2(printk("%s(%ld): abort_command "
"mbx failed.\n", __func__, ha->host_no));
......@@ -543,20 +544,19 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
"mbx success.\n", __func__, ha->host_no));
ret = SUCCESS;
}
spin_lock(&ha->hardware_lock);
spin_lock_irqsave(&ha->hardware_lock, flags);
break;
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);
/* Wait for the command to be returned. */
if (ret == SUCCESS) {
spin_unlock(&ha->hardware_lock);
if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) {
qla_printk(KERN_ERR, ha,
"scsi(%ld:%d:%d): Abort handler timed out -- %lx "
"%x.\n", ha->host_no, id, lun, serial, ret);
}
spin_lock(&ha->hardware_lock);
}
spin_lock_irq(ha->host->host_lock);
......@@ -588,6 +588,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
int status;
srb_t *sp;
struct scsi_cmnd *cmd;
unsigned long flags;
status = 0;
......@@ -596,11 +597,11 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
* array
*/
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
spin_lock(&ha->hardware_lock);
spin_lock_irqsave(&ha->hardware_lock, flags);
sp = ha->outstanding_cmds[cnt];
if (sp) {
cmd = sp->cmd;
spin_unlock(&ha->hardware_lock);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (cmd->device->id == t) {
if (!qla2x00_eh_wait_on_command(ha, cmd)) {
status = 1;
......@@ -608,7 +609,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
}
}
} else {
spin_unlock(&ha->hardware_lock);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
}
return (status);
......@@ -740,6 +741,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha)
int status;
srb_t *sp;
struct scsi_cmnd *cmd;
unsigned long flags;
status = 1;
......@@ -748,17 +750,17 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha)
* array
*/
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
spin_lock(&ha->hardware_lock);
spin_lock_irqsave(&ha->hardware_lock, flags);
sp = ha->outstanding_cmds[cnt];
if (sp) {
cmd = sp->cmd;
spin_unlock(&ha->hardware_lock);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
status = qla2x00_eh_wait_on_command(ha, cmd);
if (status == 0)
break;
}
else {
spin_unlock(&ha->hardware_lock);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
}
return (status);
......
......@@ -1197,6 +1197,7 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
if (!starget)
return ERR_PTR(-ENOMEM);
get_device(&starget->dev);
down(&shost->scan_mutex);
res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata);
if (res != SCSI_SCAN_LUN_PRESENT)
......
......@@ -234,7 +234,7 @@ static inline const char *siu_type_name(struct uart_port *port)
return "DSIU";
}
return "unknown";
return NULL;
}
static unsigned int siu_tx_empty(struct uart_port *port)
......@@ -482,9 +482,6 @@ static irqreturn_t siu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
struct uart_port *port;
uint8_t iir, lsr;
if (dev_id == NULL)
return IRQ_NONE;
port = (struct uart_port *)dev_id;
iir = siu_read(port, UART_IIR);
......@@ -507,6 +504,9 @@ static int siu_startup(struct uart_port *port)
{
int retval;
if (port->membase == NULL)
return -ENODEV;
siu_clear_fifo(port);
(void)siu_read(port, UART_LSR);
......@@ -545,9 +545,6 @@ static void siu_shutdown(struct uart_port *port)
unsigned long flags;
uint8_t lcr;
if (port->membase == NULL)
return;
siu_write(port, UART_IER, 0);
spin_lock_irqsave(&port->lock, flags);
......@@ -802,53 +799,6 @@ static int siu_init_ports(void)
#ifdef CONFIG_SERIAL_VR41XX_CONSOLE
static void early_set_termios(struct uart_port *port, struct termios *new,
struct termios *old)
{
tcflag_t c_cflag;
uint8_t lcr;
unsigned int baud, quot;
c_cflag = new->c_cflag;
switch (c_cflag & CSIZE) {
case CS5:
lcr = UART_LCR_WLEN5;
break;
case CS6:
lcr = UART_LCR_WLEN6;
break;
case CS7:
lcr = UART_LCR_WLEN7;
break;
default:
lcr = UART_LCR_WLEN8;
break;
}
if (c_cflag & CSTOPB)
lcr |= UART_LCR_STOP;
if (c_cflag & PARENB)
lcr |= UART_LCR_PARITY;
if ((c_cflag & PARODD) != PARODD)
lcr |= UART_LCR_EPAR;
if (c_cflag & CMSPAR)
lcr |= UART_LCR_SPAR;
baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
quot = uart_get_divisor(port, baud);
siu_write(port, UART_LCR, lcr | UART_LCR_DLAB);
siu_write(port, UART_DLL, (uint8_t)quot);
siu_write(port, UART_DLM, (uint8_t)(quot >> 8));
siu_write(port, UART_LCR, lcr);
}
static struct uart_ops early_uart_ops = {
.set_termios = early_set_termios,
};
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
static void wait_for_xmitr(struct uart_port *port)
......@@ -915,7 +865,7 @@ static int siu_console_setup(struct console *con, char *options)
if (port->membase == NULL) {
if (port->mapbase == 0)
return -ENODEV;
port->membase = (unsigned char __iomem *)KSEG1ADDR(port->mapbase);
port->membase = ioremap(port->mapbase, siu_port_size(port));
}
vr41xx_select_siu_interface(SIU_INTERFACE_RS232C);
......@@ -949,7 +899,7 @@ static int __devinit siu_console_init(void)
for (i = 0; i < num; i++) {
port = &siu_uart_ports[i];
port->ops = &early_uart_ops;
port->ops = &siu_uart_ops;
}
register_console(&siu_console);
......@@ -994,9 +944,11 @@ static int siu_probe(struct device *dev)
port->dev = dev;
retval = uart_add_one_port(&siu_uart_driver, port);
if (retval)
if (retval < 0) {
port->dev = NULL;
break;
}
}
if (i == 0 && retval < 0) {
uart_unregister_driver(&siu_uart_driver);
......
......@@ -290,32 +290,30 @@ static ssize_t show_modalias(struct device *dev, char *buf)
{
struct usb_interface *intf;
struct usb_device *udev;
int len;
intf = to_usb_interface(dev);
udev = interface_to_usbdev(intf);
if (udev->descriptor.bDeviceClass == 0) {
struct usb_host_interface *alt = intf->cur_altsetting;
return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X\n",
len = sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic",
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct),
le16_to_cpu(udev->descriptor.bcdDevice),
udev->descriptor.bDeviceClass,
udev->descriptor.bDeviceSubClass,
udev->descriptor.bDeviceProtocol,
udev->descriptor.bDeviceProtocol);
buf += len;
if (udev->descriptor.bDeviceClass == 0) {
struct usb_host_interface *alt = intf->cur_altsetting;
return len + sprintf(buf, "%02Xisc%02Xip%02X\n",
alt->desc.bInterfaceClass,
alt->desc.bInterfaceSubClass,
alt->desc.bInterfaceProtocol);
} else {
return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic*isc*ip*\n",
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct),
le16_to_cpu(udev->descriptor.bcdDevice),
udev->descriptor.bDeviceClass,
udev->descriptor.bDeviceSubClass,
udev->descriptor.bDeviceProtocol);
return len + sprintf(buf, "*isc*ip*\n");
}
}
static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
......
......@@ -1315,6 +1315,8 @@ void hid_init_reports(struct hid_device *hid)
#define USB_DEVICE_ID_WACOM_INTUOS2 0x0040
#define USB_DEVICE_ID_WACOM_VOLITO 0x0060
#define USB_DEVICE_ID_WACOM_PTU 0x0003
#define USB_DEVICE_ID_WACOM_INTUOS3 0x00B0
#define USB_DEVICE_ID_WACOM_CINTIQ 0x003F
#define USB_VENDOR_ID_KBGEAR 0x084e
#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
......@@ -1401,6 +1403,7 @@ void hid_init_reports(struct hid_device *hid)
#define USB_VENDOR_ID_DELORME 0x1163
#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200
#define USB_VENDOR_ID_MCC 0x09db
#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076
......@@ -1412,6 +1415,12 @@ void hid_init_reports(struct hid_device *hid)
#define USB_VENDOR_ID_BTC 0x046e
#define USB_DEVICE_ID_BTC_KEYBOARD 0x5303
#define USB_VENDOR_ID_VERNIER 0x08f7
#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001
#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002
#define USB_DEVICE_ID_VERNIER_SKIP 0x0003
#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
/*
* Alphabetically sorted blacklist by quirk type.
......@@ -1437,6 +1446,7 @@ static struct hid_blacklist {
{ USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
......@@ -1456,6 +1466,10 @@ static struct hid_blacklist {
{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE },
......@@ -1481,6 +1495,10 @@ static struct hid_blacklist {
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
......
9.0.2
* Adding #ifdef to compile PWC before and after 2.6.5
9.0.1
9.0
8.12
* Implement motorized pan/tilt feature for Logitech QuickCam Orbit/Spere.
8.11.1
* Fix for PCVC720/40, would not be able to set videomode
* Fix for Samsung MPC models, appearantly they are based on a newer chipset
8.11
* 20 dev_hints (per request)
* Hot unplugging should be better, no more dangling pointers or memory leaks
* Added reserved Logitech webcam IDs
* Device now remembers size & fps between close()/open()
* Removed palette stuff altogether
8.10.1
* Added IDs for PCVC720K/40 and Creative Labs Webcam Pro
8.10
* Fixed ID for QuickCam Notebook pro
* Added GREALSIZE ioctl() call
* Fixed bug in case PWCX was not loaded and invalid size was set
8.9
* Merging with kernel 2.5.49
* Adding IDs for QuickCam Zoom & QuickCam Notebook
8.8
* Fixing 'leds' parameter
* Adding IDs for Logitech QuickCam Pro 4000
* Making URB init/cleanup a little nicer
8.7
* Incorporating changes in ioctl() parameter passing
* Also changes to URB mechanism
8.6
* Added ID's for Visionite VCS UM100 and UC300
* Removed YUV420-interlaced palette altogether (was confusing)
* Removed MIRROR stuff as it didn't work anyway
* Fixed a problem with the 'leds' parameter (wouldn't blink)
* Added ioctl()s for advanced features: 'extended' whitebalance ioctl()s,
CONTOUR, BACKLIGHT, FLICKER, DYNNOISE.
* VIDIOCGCAP.name now contains real camera model name instead of
'Philips xxx webcam'
* Added PROBE ioctl (see previous point & API doc)
8.5
* Adding IDs for Creative Labs Webcam 5
* Adding IDs for SOTEC CMS-001 webcam
* Solving possible hang in VIDIOCSYNC when unplugging the cam
* Forgot to return structure in VIDIOCPWCGAWB, oops
* Time interval for the LEDs are now in milliseconds
8.4
* Fixing power_save option for Vesta range
* Handling new error codes in ISOC callback
* Adding dev_hint module parameter, to specify /dev/videoX device nodes
8.3
* Adding Samsung C10 and C30 cameras
* Removing palette module parameter
* Fixed typo in ID of QuickCam 3000 Pro
* Adding LED settings (blinking while in use) for ToUCam cameras.
* Turns LED off when camera is not in use.
8.2
* Making module more silent when trace = 0
* Adding QuickCam 3000 Pro IDs
* Chrominance control for the Vesta cameras
* Hopefully fixed problems on machines with BIGMEM and > 1GB of RAM
* Included Oliver Neukem's lock_kernel() patch
* Allocates less memory for image buffers
* Adds ioctl()s for the whitebalancing
8.1
* Adding support for 750
* Adding V4L GAUDIO/SAUDIO/UNIT ioctl() calls
8.0
* 'damage control' after inclusion in 2.4.5.
* Changed wait-queue mechanism in read/mmap/poll according to the book.
* Included YUV420P palette.
* Changed interface to decompressor module.
* Cleaned up pwc structure a bit.
7.0
* Fixed bug in vcvt_420i_yuyv; extra variables on stack were misaligned.
* There is now a clear error message when an image size is selected that
is only supported using the decompressor, and the decompressor isn't
loaded.
* When the decompressor wasn't loaded, selecting large image size
would create skewed or double images.
6.3
* Introduced spinlocks for the buffer pointer manipulation; a number of
reports seem to suggest the down()/up() semaphores were the cause of
lockups, since they are not suitable for interrupt/user locking.
* Separated decompressor and core code into 2 modules.
6.2
* Non-integral image sizes are now padded with gray or black.
* Added SHUTTERSPEED ioctl().
* Fixed buglet in VIDIOCPWCSAGC; the function would always return an error,
even though the call succeeded.
* Added hotplug support for 2.4.*.
* Memory: the 645/646 uses less memory now.
6.1
* VIDIOCSPICT returns -EINVAL with invalid palettes.
* Added saturation control.
* Split decompressors from rest.
* Fixed bug that would reset the framerate to the default framerate if
the rate field was set to 0 (which is not what I intended, nl. do not
change the framerate!).
* VIDIOCPWCSCQUAL (setting compression quality) now takes effect immediately.
* Workaround for a bug in the 730 sensor.
......@@ -2765,7 +2765,7 @@ static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf)
}
/* expect bcdVersion 1.0, ignore */
if (memcmp(&desc->bGUID, blan_guid, 16)
&& memcmp(&desc->bGUID, blan_guid, 16) ) {
&& memcmp(&desc->bGUID, safe_guid, 16) ) {
/* hey, this one might _really_ be MDLM! */
dev_dbg (&intf->dev, "MDLM guid\n");
goto bad_desc;
......
......@@ -455,6 +455,17 @@ config USB_SERIAL_XIRCOM
To compile this driver as a module, choose M here: the
module will be called keyspan_pda.
config USB_SERIAL_OPTION
tristate "USB Option PCMCIA serial driver"
depends on USB_SERIAL && USB_OHCI_HCD && PCCARD
help
Say Y here if you want to use an Option card. This is a
GSM card, controlled by three serial ports which are connected
via an OHCI adapter located on a PC card.
To compile this driver as a module, choose M here: the
module will be called option.
config USB_SERIAL_OMNINET
tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)"
depends on USB_SERIAL && EXPERIMENTAL
......
......@@ -32,6 +32,7 @@ obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o
obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o
obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o
obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o
obj-$(CONFIG_USB_SERIAL_OPTION) += option.o
obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o
obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o
obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o
......
This diff is collapsed.
This diff is collapsed.
......@@ -862,6 +862,15 @@ UNUSUAL_DEV( 0x090a, 0x1001, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_BULK, NULL,
US_FL_NEED_OVERRIDE ),
/* Reported by Filippo Bardelli <filibard@libero.it>
* The device reports a subclass of RBC, which is wrong.
*/
UNUSUAL_DEV( 0x090a, 0x1050, 0x0100, 0x0100,
"Trumpion Microelectronics, Inc.",
"33520 USB Digital Voice Recorder",
US_SC_UFI, US_PR_DEVICE, NULL,
0),
/* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */
UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999,
"Trumpion",
......
This diff is collapsed.
......@@ -79,8 +79,11 @@ static int mpage_end_io_write(struct bio *bio, unsigned int bytes_done, int err)
if (--bvec >= bio->bi_io_vec)
prefetchw(&bvec->bv_page->flags);
if (!uptodate)
if (!uptodate){
SetPageError(page);
if (page->mapping)
set_bit(AS_EIO, &page->mapping->flags);
}
end_page_writeback(page);
} while (bvec >= bio->bi_io_vec);
bio_put(bio);
......
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.
......@@ -37,5 +37,4 @@ EXPORT_SYMBOL(in6_dev_finish_destroy);
EXPORT_SYMBOL(xfrm6_rcv);
#endif
EXPORT_SYMBOL(rt6_lookup);
EXPORT_SYMBOL(fl6_sock_lookup);
EXPORT_SYMBOL(ipv6_push_nfrag_opts);
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