Merge branch 'upstream-fixes' into upstream

This commit is contained in:
Jeff Garzik 2006-07-24 03:38:25 -04:00
commit 48cb37bd9e
242 changed files with 2039 additions and 1984 deletions

View File

@ -1676,10 +1676,8 @@ L: linux-kernel@vger.kernel.org
S: Maintained
LAPB module
P: Henner Eisen
M: eis@baty.hanse.de
L: linux-x25@vger.kernel.org
S: Maintained
S: Orphan
LASI 53c700 driver for PARISC
P: James E.J. Bottomley

View File

@ -273,7 +273,7 @@ startup_continue:
.Lbss_end: .long _end
.Lparmaddr: .long PARMAREA
.Lsccbaddr: .long .Lsccb
.align 4096
.org 0x12000
.Lsccb:
.hword 0x1000 # length, one page
.byte 0x00,0x00,0x00
@ -290,7 +290,7 @@ startup_continue:
.Lscpincr2:
.quad 0x00
.fill 3984,1,0
.align 4096
.org 0x13000
#ifdef CONFIG_SHARED_KERNEL
.org 0x100000

View File

@ -268,7 +268,7 @@ startup_continue:
.Lparmaddr:
.quad PARMAREA
.align 4096
.org 0x12000
.Lsccb:
.hword 0x1000 # length, one page
.byte 0x00,0x00,0x00
@ -285,7 +285,7 @@ startup_continue:
.Lscpincr2:
.quad 0x00
.fill 3984,1,0
.align 4096
.org 0x13000
#ifdef CONFIG_SHARED_KERNEL
.org 0x100000

View File

@ -877,31 +877,57 @@ static struct bin_attribute ipl_scp_data_attr = {
static decl_subsys(ipl, NULL, NULL);
static int ipl_register_fcp_files(void)
{
int rc;
rc = sysfs_create_group(&ipl_subsys.kset.kobj,
&ipl_fcp_attr_group);
if (rc)
goto out;
rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
&ipl_parameter_attr);
if (rc)
goto out_ipl_parm;
rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
&ipl_scp_data_attr);
if (!rc)
goto out;
sysfs_remove_bin_file(&ipl_subsys.kset.kobj, &ipl_parameter_attr);
out_ipl_parm:
sysfs_remove_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
out:
return rc;
}
static int __init
ipl_device_sysfs_register(void) {
int rc;
rc = firmware_register(&ipl_subsys);
if (rc)
return rc;
goto out;
switch (get_ipl_type()) {
case ipl_type_ccw:
sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_ccw_attr_group);
rc = sysfs_create_group(&ipl_subsys.kset.kobj,
&ipl_ccw_attr_group);
break;
case ipl_type_fcp:
sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
sysfs_create_bin_file(&ipl_subsys.kset.kobj,
&ipl_parameter_attr);
sysfs_create_bin_file(&ipl_subsys.kset.kobj,
&ipl_scp_data_attr);
rc = ipl_register_fcp_files();
break;
default:
sysfs_create_group(&ipl_subsys.kset.kobj,
&ipl_unknown_attr_group);
rc = sysfs_create_group(&ipl_subsys.kset.kobj,
&ipl_unknown_attr_group);
break;
}
return 0;
if (rc)
firmware_unregister(&ipl_subsys);
out:
return rc;
}
__initcall(ipl_device_sysfs_register);

View File

@ -15,6 +15,7 @@
#include <asm/page.h>
#include <asm/oplib.h>
#include <asm/prom.h>
#include <asm/smp.h>
#include <asm/system.h>
#include <asm/cpudata.h>
@ -34,12 +35,6 @@ static int check_cpu_node(int nd, int *cur_inst,
int (*compare)(int, int, void *), void *compare_arg,
int *prom_node, int *mid)
{
char node_str[128];
prom_getstring(nd, "device_type", node_str, sizeof(node_str));
if (strcmp(node_str, "cpu"))
return -ENODEV;
if (!compare(nd, *cur_inst, compare_arg)) {
if (prom_node)
*prom_node = nd;
@ -59,20 +54,14 @@ static int check_cpu_node(int nd, int *cur_inst,
static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg,
int *prom_node, int *mid)
{
int nd, cur_inst, err;
struct device_node *dp;
int cur_inst;
nd = prom_root_node;
cur_inst = 0;
err = check_cpu_node(nd, &cur_inst, compare, compare_arg,
prom_node, mid);
if (!err)
return 0;
nd = prom_getchild(nd);
while ((nd = prom_getsibling(nd)) != 0) {
err = check_cpu_node(nd, &cur_inst, compare, compare_arg,
prom_node, mid);
for_each_node_by_type(dp, "cpu") {
int err = check_cpu_node(dp->node, &cur_inst,
compare, compare_arg,
prom_node, mid);
if (!err)
return 0;
}

View File

@ -329,7 +329,7 @@ void handler_irq(int irq, struct pt_regs * regs)
disable_pil_irq(irq);
#ifdef CONFIG_SMP
/* Only rotate on lower priority IRQ's (scsi, ethernet, etc.). */
if(irq < 10)
if((sparc_cpu_model==sun4m) && (irq < 10))
smp4m_irq_rotate(cpu);
#endif
action = sparc_irq[irq].action;

View File

@ -596,14 +596,41 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
static int pil_to_sbus[] = {
0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0,
};
struct device_node *busp = dp->parent;
struct device_node *io_unit, *sbi = dp->parent;
struct linux_prom_registers *regs;
int board = of_getintprop_default(busp, "board#", 0);
int slot;
int board, slot;
while (sbi) {
if (!strcmp(sbi->name, "sbi"))
break;
sbi = sbi->parent;
}
if (!sbi)
goto build_resources;
regs = of_get_property(dp, "reg", NULL);
if (!regs)
goto build_resources;
slot = regs->which_io;
/* If SBI's parent is not io-unit or the io-unit lacks
* a "board#" property, something is very wrong.
*/
if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) {
printk("%s: Error, parent is not io-unit.\n",
sbi->full_name);
goto build_resources;
}
io_unit = sbi->parent;
board = of_getintprop_default(io_unit, "board#", -1);
if (board == -1) {
printk("%s: Error, lacks board# property.\n",
io_unit->full_name);
goto build_resources;
}
for (i = 0; i < op->num_irqs; i++) {
int this_irq = op->irqs[i];
int sbusl = pil_to_sbus[this_irq];
@ -617,6 +644,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
}
}
build_resources:
build_device_resources(op, parent);
op->dev.parent = parent;

View File

@ -444,6 +444,7 @@ static struct property * __init build_one_prop(phandle node, char *prev, char *s
static struct property *tmp = NULL;
struct property *p;
int len;
const char *name;
if (tmp) {
p = tmp;
@ -456,19 +457,21 @@ static struct property * __init build_one_prop(phandle node, char *prev, char *s
p->name = (char *) (p + 1);
if (special_name) {
strcpy(p->name, special_name);
p->length = special_len;
p->value = prom_early_alloc(special_len);
memcpy(p->value, special_val, special_len);
} else {
if (prev == NULL) {
prom_firstprop(node, p->name);
name = prom_firstprop(node, NULL);
} else {
prom_nextprop(node, prev, p->name);
name = prom_nextprop(node, prev, NULL);
}
if (strlen(p->name) == 0) {
if (strlen(name) == 0) {
tmp = p;
return NULL;
}
strcpy(p->name, name);
p->length = prom_getproplen(node, p->name);
if (p->length <= 0) {
p->length = 0;

View File

@ -87,6 +87,7 @@ void __cpuinit smp_store_cpu_info(int id)
void __init smp_cpus_done(unsigned int max_cpus)
{
extern void smp4m_smp_done(void);
extern void smp4d_smp_done(void);
unsigned long bogosum = 0;
int cpu, num;
@ -100,8 +101,34 @@ void __init smp_cpus_done(unsigned int max_cpus)
num, bogosum/(500000/HZ),
(bogosum/(5000/HZ))%100);
BUG_ON(sparc_cpu_model != sun4m);
smp4m_smp_done();
switch(sparc_cpu_model) {
case sun4:
printk("SUN4\n");
BUG();
break;
case sun4c:
printk("SUN4C\n");
BUG();
break;
case sun4m:
smp4m_smp_done();
break;
case sun4d:
smp4d_smp_done();
break;
case sun4e:
printk("SUN4E\n");
BUG();
break;
case sun4u:
printk("SUN4U\n");
BUG();
break;
default:
printk("UNKNOWN!\n");
BUG();
break;
};
}
void cpu_panic(void)
@ -267,9 +294,9 @@ int setup_profiling_timer(unsigned int multiplier)
void __init smp_prepare_cpus(unsigned int max_cpus)
{
extern void smp4m_boot_cpus(void);
extern void smp4d_boot_cpus(void);
int i, cpuid, extra;
BUG_ON(sparc_cpu_model != sun4m);
printk("Entering SMP Mode...\n");
extra = 0;
@ -283,7 +310,34 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
smp_store_cpu_info(boot_cpu_id);
smp4m_boot_cpus();
switch(sparc_cpu_model) {
case sun4:
printk("SUN4\n");
BUG();
break;
case sun4c:
printk("SUN4C\n");
BUG();
break;
case sun4m:
smp4m_boot_cpus();
break;
case sun4d:
smp4d_boot_cpus();
break;
case sun4e:
printk("SUN4E\n");
BUG();
break;
case sun4u:
printk("SUN4U\n");
BUG();
break;
default:
printk("UNKNOWN!\n");
BUG();
break;
};
}
/* Set this up early so that things like the scheduler can init
@ -323,9 +377,37 @@ void __init smp_prepare_boot_cpu(void)
int __cpuinit __cpu_up(unsigned int cpu)
{
extern int smp4m_boot_one_cpu(int);
int ret;
extern int smp4d_boot_one_cpu(int);
int ret=0;
ret = smp4m_boot_one_cpu(cpu);
switch(sparc_cpu_model) {
case sun4:
printk("SUN4\n");
BUG();
break;
case sun4c:
printk("SUN4C\n");
BUG();
break;
case sun4m:
ret = smp4m_boot_one_cpu(cpu);
break;
case sun4d:
ret = smp4d_boot_one_cpu(cpu);
break;
case sun4e:
printk("SUN4E\n");
BUG();
break;
case sun4u:
printk("SUN4U\n");
BUG();
break;
default:
printk("UNKNOWN!\n");
BUG();
break;
};
if (!ret) {
cpu_set(cpu, smp_commenced_mask);

View File

@ -237,7 +237,6 @@ EXPORT_SYMBOL(prom_node_has_property);
EXPORT_SYMBOL(prom_setprop);
EXPORT_SYMBOL(saved_command_line);
EXPORT_SYMBOL(prom_apply_obio_ranges);
EXPORT_SYMBOL(prom_getname);
EXPORT_SYMBOL(prom_feval);
EXPORT_SYMBOL(prom_getbool);
EXPORT_SYMBOL(prom_getstring);

View File

@ -43,15 +43,10 @@ extern ctxd_t *srmmu_ctx_table_phys;
extern void calibrate_delay(void);
extern volatile int smp_processors_ready;
extern int smp_num_cpus;
static int smp_highest_cpu;
extern volatile unsigned long cpu_callin_map[NR_CPUS];
extern cpuinfo_sparc cpu_data[NR_CPUS];
extern unsigned char boot_cpu_id;
extern int smp_activated;
extern volatile int __cpu_number_map[NR_CPUS];
extern volatile int __cpu_logical_map[NR_CPUS];
extern volatile unsigned long ipi_count;
extern volatile int smp_process_available;
extern cpumask_t smp_commenced_mask;
@ -144,6 +139,8 @@ void __init smp4d_callin(void)
spin_lock_irqsave(&sun4d_imsk_lock, flags);
cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */
spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
cpu_set(cpuid, cpu_online_map);
}
extern void init_IRQ(void);
@ -160,51 +157,24 @@ extern unsigned long trapbase_cpu3[];
void __init smp4d_boot_cpus(void)
{
int cpucount = 0;
int i, mid;
printk("Entering SMP Mode...\n");
if (boot_cpu_id)
current_set[0] = NULL;
local_irq_enable();
cpus_clear(cpu_present_map);
/* XXX This whole thing has to go. See sparc64. */
for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++)
cpu_set(mid, cpu_present_map);
SMP_PRINTK(("cpu_present_map %08lx\n", cpus_addr(cpu_present_map)[0]));
for(i=0; i < NR_CPUS; i++)
__cpu_number_map[i] = -1;
for(i=0; i < NR_CPUS; i++)
__cpu_logical_map[i] = -1;
__cpu_number_map[boot_cpu_id] = 0;
__cpu_logical_map[0] = boot_cpu_id;
current_thread_info()->cpu = boot_cpu_id;
smp_store_cpu_info(boot_cpu_id);
smp_setup_percpu_timer();
local_flush_cache_all();
if (cpu_find_by_instance(1, NULL, NULL))
return; /* Not an MP box. */
SMP_PRINTK(("Iterating over CPUs\n"));
for(i = 0; i < NR_CPUS; i++) {
if(i == boot_cpu_id)
continue;
}
if (cpu_isset(i, cpu_present_map)) {
int smp4d_boot_one_cpu(int i)
{
extern unsigned long sun4d_cpu_startup;
unsigned long *entry = &sun4d_cpu_startup;
struct task_struct *p;
int timeout;
int no;
int cpu_node;
cpu_find_by_instance(i, &cpu_node,NULL);
/* Cook up an idler for this guy. */
p = fork_idle(i);
cpucount++;
current_set[i] = task_thread_info(p);
for (no = 0; !cpu_find_by_instance(no, NULL, &mid)
&& mid != i; no++) ;
/*
* Initialize the contexts table
@ -216,9 +186,9 @@ void __init smp4d_boot_cpus(void)
smp_penguin_ctable.reg_size = 0;
/* whirrr, whirrr, whirrrrrrrrr... */
SMP_PRINTK(("Starting CPU %d at %p task %d node %08x\n", i, entry, cpucount, cpu_data(no).prom_node));
SMP_PRINTK(("Starting CPU %d at %p \n", i, entry));
local_flush_cache_all();
prom_startcpu(cpu_data(no).prom_node,
prom_startcpu(cpu_node,
&smp_penguin_ctable, 0, (char *)entry);
SMP_PRINTK(("prom_startcpu returned :)\n"));
@ -230,39 +200,30 @@ void __init smp4d_boot_cpus(void)
udelay(200);
}
if(cpu_callin_map[i]) {
/* Another "Red Snapper". */
__cpu_number_map[i] = cpucount;
__cpu_logical_map[cpucount] = i;
} else {
cpucount--;
printk("Processor %d is stuck.\n", i);
}
}
if(!(cpu_callin_map[i])) {
cpu_clear(i, cpu_present_map);
__cpu_number_map[i] = -1;
}
if (!(cpu_callin_map[i])) {
printk("Processor %d is stuck.\n", i);
return -ENODEV;
}
local_flush_cache_all();
if(cpucount == 0) {
printk("Error: only one Processor found.\n");
cpu_present_map = cpumask_of_cpu(hard_smp4d_processor_id());
} else {
unsigned long bogosum = 0;
return 0;
}
for_each_present_cpu(i) {
bogosum += cpu_data(i).udelay_val;
smp_highest_cpu = i;
void __init smp4d_smp_done(void)
{
int i, first;
int *prev;
/* setup cpu list for irq rotation */
first = 0;
prev = &first;
for (i = 0; i < NR_CPUS; i++)
if (cpu_online(i)) {
*prev = i;
prev = &cpu_data(i).next;
}
SMP_PRINTK(("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", cpucount + 1, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100));
printk("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n",
cpucount + 1,
bogosum/(500000/HZ),
(bogosum/(5000/HZ))%100);
smp_activated = 1;
smp_num_cpus = cpucount + 1;
}
*prev = first;
local_flush_cache_all();
/* Free unneeded trap tables */
ClearPageReserved(virt_to_page(trapbase_cpu1));
@ -334,7 +295,7 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
register int i;
mask = cpumask_of_cpu(hard_smp4d_processor_id());
cpus_andnot(mask, cpu_present_map, mask);
cpus_andnot(mask, cpu_online_map, mask);
for(i = 0; i <= high; i++) {
if (cpu_isset(i, mask)) {
ccall_info.processors_in[i] = 0;

View File

@ -465,21 +465,21 @@ sys_rt_sigaction(int sig,
asmlinkage int sys_getdomainname(char __user *name, int len)
{
int nlen;
int err = -EFAULT;
int nlen, err;
if (len < 0 || len > __NEW_UTS_LEN)
return -EINVAL;
down_read(&uts_sem);
nlen = strlen(system_utsname.domainname) + 1;
if (nlen < len)
len = nlen;
if (len > __NEW_UTS_LEN)
goto done;
if (copy_to_user(name, system_utsname.domainname, len))
goto done;
err = 0;
done:
err = -EFAULT;
if (!copy_to_user(name, system_utsname.domainname, len))
err = 0;
up_read(&uts_sem);
return err;
}

View File

@ -64,6 +64,7 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus)
sbus->iommu = (struct iommu_struct *)iounit;
iounit->page_table = xpt;
spin_lock_init(&iounit->lock);
for (xptend = iounit->page_table + (16 * PAGE_SIZE) / sizeof(iopte_t);
xpt < xptend;)

View File

@ -205,24 +205,6 @@ int prom_searchsiblings(int node_start, char *nodename)
return 0;
}
/* Gets name in the form prom v2+ uses it (name@x,yyyyy or name (if no reg)) */
int prom_getname (int node, char *buffer, int len)
{
int i;
struct linux_prom_registers reg[PROMREG_MAX];
i = prom_getproperty (node, "name", buffer, len);
if (i <= 0) return -1;
buffer [i] = 0;
len -= i;
i = prom_getproperty (node, "reg", (char *)reg, sizeof (reg));
if (i <= 0) return 0;
if (len < 11) return -1;
buffer = strchr (buffer, 0);
sprintf (buffer, "@%x,%x", reg[0].which_io, (uint)reg[0].phys_addr);
return 0;
}
/* Interal version of nextprop that does not alter return values. */
char * __prom_nextprop(int node, char * oprop)
{

View File

@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.18-rc1
# Wed Jul 12 14:00:58 2006
# Linux kernel version: 2.6.18-rc2
# Fri Jul 21 14:19:24 2006
#
CONFIG_SPARC=y
CONFIG_SPARC64=y
@ -36,6 +36,7 @@ CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
@ -1120,7 +1121,7 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CY7C63 is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
@ -1279,7 +1280,6 @@ CONFIG_RAMFS=y
# CONFIG_NFSD is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set

View File

@ -66,9 +66,6 @@ static int check_cpu_node(struct device_node *dp, int *cur_inst,
void *compare_arg,
struct device_node **dev_node, int *mid)
{
if (strcmp(dp->type, "cpu"))
return -ENODEV;
if (!compare(dp, *cur_inst, compare_arg)) {
if (dev_node)
*dev_node = dp;

View File

@ -542,9 +542,17 @@ static void __init build_device_resources(struct of_device *op,
/* Convert to num-cells. */
num_reg /= 4;
/* Conver to num-entries. */
/* Convert to num-entries. */
num_reg /= na + ns;
/* Prevent overruning the op->resources[] array. */
if (num_reg > PROMREG_MAX) {
printk(KERN_WARNING "%s: Too many regs (%d), "
"limiting to %d.\n",
op->node->full_name, num_reg, PROMREG_MAX);
num_reg = PROMREG_MAX;
}
for (index = 0; index < num_reg; index++) {
struct resource *r = &op->resource[index];
u32 addr[OF_MAX_ADDR_CELLS];
@ -650,8 +658,22 @@ apply_interrupt_map(struct device_node *dp, struct device_node *pp,
next:
imap += (na + 3);
}
if (i == imlen)
if (i == imlen) {
/* Psycho and Sabre PCI controllers can have 'interrupt-map'
* properties that do not include the on-board device
* interrupts. Instead, the device's 'interrupts' property
* is already a fully specified INO value.
*
* Handle this by deciding that, if we didn't get a
* match in the parent's 'interrupt-map', and the
* parent is an IRQ translater, then use the parent as
* our IRQ controller.
*/
if (pp->irq_trans)
return pp;
return NULL;
}
*irq_p = irq;
cp = of_find_node_by_phandle(handle);
@ -803,6 +825,14 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
op->num_irqs = 0;
}
/* Prevent overruning the op->irqs[] array. */
if (op->num_irqs > PROMINTR_MAX) {
printk(KERN_WARNING "%s: Too many irqs (%d), "
"limiting to %d.\n",
dp->full_name, op->num_irqs, PROMINTR_MAX);
op->num_irqs = PROMINTR_MAX;
}
build_device_resources(op, parent);
for (i = 0; i < op->num_irqs; i++)
op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]);

View File

@ -344,10 +344,12 @@ static unsigned long __psycho_onboard_imap_off[] = {
/*0x2f*/ PSYCHO_IMAP_CE,
/*0x30*/ PSYCHO_IMAP_A_ERR,
/*0x31*/ PSYCHO_IMAP_B_ERR,
/*0x32*/ PSYCHO_IMAP_PMGMT
/*0x32*/ PSYCHO_IMAP_PMGMT,
/*0x33*/ PSYCHO_IMAP_GFX,
/*0x34*/ PSYCHO_IMAP_EUPA,
};
#define PSYCHO_ONBOARD_IRQ_BASE 0x20
#define PSYCHO_ONBOARD_IRQ_LAST 0x32
#define PSYCHO_ONBOARD_IRQ_LAST 0x34
#define psycho_onboard_imap_offset(__ino) \
__psycho_onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE]
@ -529,6 +531,10 @@ static unsigned long __sabre_onboard_imap_off[] = {
/*0x2e*/ SABRE_IMAP_UE,
/*0x2f*/ SABRE_IMAP_CE,
/*0x30*/ SABRE_IMAP_PCIERR,
/*0x31*/ 0 /* reserved */,
/*0x32*/ 0 /* reserved */,
/*0x33*/ SABRE_IMAP_GFX,
/*0x34*/ SABRE_IMAP_EUPA,
};
#define SABRE_ONBOARD_IRQ_BASE 0x20
#define SABRE_ONBOARD_IRQ_LAST 0x30
@ -895,6 +901,8 @@ static unsigned long sysio_irq_offsets[] = {
SYSIO_IMAP_CE,
SYSIO_IMAP_SBERR,
SYSIO_IMAP_PMGMT,
SYSIO_IMAP_GFX,
SYSIO_IMAP_EUPA,
};
#undef bogon

View File

@ -254,7 +254,6 @@ EXPORT_SYMBOL(prom_getproperty);
EXPORT_SYMBOL(prom_node_has_property);
EXPORT_SYMBOL(prom_setprop);
EXPORT_SYMBOL(saved_command_line);
EXPORT_SYMBOL(prom_getname);
EXPORT_SYMBOL(prom_finddevice);
EXPORT_SYMBOL(prom_feval);
EXPORT_SYMBOL(prom_getbool);

View File

@ -701,21 +701,21 @@ extern void check_pending(int signum);
asmlinkage long sys_getdomainname(char __user *name, int len)
{
int nlen;
int err = -EFAULT;
int nlen, err;
if (len < 0 || len > __NEW_UTS_LEN)
return -EINVAL;
down_read(&uts_sem);
nlen = strlen(system_utsname.domainname) + 1;
if (nlen < len)
len = nlen;
if (len > __NEW_UTS_LEN)
goto done;
if (copy_to_user(name, system_utsname.domainname, len))
goto done;
err = 0;
done:
err = -EFAULT;
if (!copy_to_user(name, system_utsname.domainname, len))
err = 0;
up_read(&uts_sem);
return err;
}

View File

@ -193,91 +193,6 @@ prom_searchsiblings(int node_start, const char *nodename)
return 0;
}
/* Gets name in the {name@x,yyyyy|name (if no reg)} form */
int
prom_getname (int node, char *buffer, int len)
{
int i, sbus = 0;
int pci = 0, ebus = 0, ide = 0;
struct linux_prom_registers *reg;
struct linux_prom64_registers reg64[PROMREG_MAX];
for (sbus = prom_getparent (node); sbus; sbus = prom_getparent (sbus)) {
i = prom_getproperty (sbus, "name", buffer, len);
if (i > 0) {
buffer [i] = 0;
if (!strcmp (buffer, "sbus"))
goto getit;
}
}
if ((pci = prom_getparent (node))) {
i = prom_getproperty (pci, "name", buffer, len);
if (i > 0) {
buffer [i] = 0;
if (!strcmp (buffer, "pci"))
goto getit;
}
pci = 0;
}
if ((ebus = prom_getparent (node))) {
i = prom_getproperty (ebus, "name", buffer, len);
if (i > 0) {
buffer[i] = 0;
if (!strcmp (buffer, "ebus"))
goto getit;
}
ebus = 0;
}
if ((ide = prom_getparent (node))) {
i = prom_getproperty (ide, "name", buffer, len);
if (i > 0) {
buffer [i] = 0;
if (!strcmp (buffer, "ide"))
goto getit;
}
ide = 0;
}
getit:
i = prom_getproperty (node, "name", buffer, len);
if (i <= 0) {
buffer [0] = 0;
return -1;
}
buffer [i] = 0;
len -= i;
i = prom_getproperty (node, "reg", (char *)reg64, sizeof (reg64));
if (i <= 0) return 0;
if (len < 16) return -1;
buffer = strchr (buffer, 0);
if (sbus) {
reg = (struct linux_prom_registers *)reg64;
sprintf (buffer, "@%x,%x", reg[0].which_io, (uint)reg[0].phys_addr);
} else if (pci) {
int dev, fn;
reg = (struct linux_prom_registers *)reg64;
fn = (reg[0].which_io >> 8) & 0x07;
dev = (reg[0].which_io >> 11) & 0x1f;
if (fn)
sprintf (buffer, "@%x,%x", dev, fn);
else
sprintf (buffer, "@%x", dev);
} else if (ebus) {
reg = (struct linux_prom_registers *)reg64;
sprintf (buffer, "@%x,%x", reg[0].which_io, reg[0].phys_addr);
} else if (ide) {
reg = (struct linux_prom_registers *)reg64;
sprintf (buffer, "@%x,%x", reg[0].which_io, reg[0].phys_addr);
} else if (i == 4) { /* Happens on 8042's children on Ultra/PCI. */
reg = (struct linux_prom_registers *)reg64;
sprintf (buffer, "@%x", reg[0].which_io);
} else {
sprintf (buffer, "@%x,%x",
(unsigned int)(reg64[0].phys_addr >> 36),
(unsigned int)(reg64[0].phys_addr));
}
return 0;
}
/* Return the first property type for node 'node'.
* buffer should be at least 32B in length
*/

View File

@ -1174,8 +1174,12 @@ static void dcd_change(MGSLPC_INFO *info)
else
info->input_signal_events.dcd_down++;
#ifdef CONFIG_HDLC
if (info->netcount)
hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, info->netdev);
if (info->netcount) {
if (info->serial_signals & SerialSignal_DCD)
netif_carrier_on(info->netdev);
else
netif_carrier_off(info->netdev);
}
#endif
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
@ -4251,8 +4255,10 @@ static int hdlcdev_open(struct net_device *dev)
spin_lock_irqsave(&info->lock, flags);
get_signals(info);
spin_unlock_irqrestore(&info->lock, flags);
hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, dev);
if (info->serial_signals & SerialSignal_DCD)
netif_carrier_on(dev);
else
netif_carrier_off(dev);
return 0;
}

View File

@ -1344,8 +1344,12 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info )
} else
info->input_signal_events.dcd_down++;
#ifdef CONFIG_HDLC
if (info->netcount)
hdlc_set_carrier(status & MISCSTATUS_DCD, info->netdev);
if (info->netcount) {
if (status & MISCSTATUS_DCD)
netif_carrier_on(info->netdev);
else
netif_carrier_off(info->netdev);
}
#endif
}
if (status & MISCSTATUS_CTS_LATCHED)
@ -7844,8 +7848,10 @@ static int hdlcdev_open(struct net_device *dev)
spin_lock_irqsave(&info->irq_spinlock, flags);
usc_get_serial_signals(info);
spin_unlock_irqrestore(&info->irq_spinlock, flags);
hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, dev);
if (info->serial_signals & SerialSignal_DCD)
netif_carrier_on(dev);
else
netif_carrier_off(dev);
return 0;
}

View File

@ -1497,8 +1497,10 @@ static int hdlcdev_open(struct net_device *dev)
spin_lock_irqsave(&info->lock, flags);
get_signals(info);
spin_unlock_irqrestore(&info->lock, flags);
hdlc_set_carrier(info->signals & SerialSignal_DCD, dev);
if (info->signals & SerialSignal_DCD)
netif_carrier_on(dev);
else
netif_carrier_off(dev);
return 0;
}
@ -1997,8 +1999,12 @@ static void dcd_change(struct slgt_info *info)
info->input_signal_events.dcd_down++;
}
#ifdef CONFIG_HDLC
if (info->netcount)
hdlc_set_carrier(info->signals & SerialSignal_DCD, info->netdev);
if (info->netcount) {
if (info->signals & SerialSignal_DCD)
netif_carrier_on(info->netdev);
else
netif_carrier_off(info->netdev);
}
#endif
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);

View File

@ -1752,8 +1752,10 @@ static int hdlcdev_open(struct net_device *dev)
spin_lock_irqsave(&info->lock, flags);
get_signals(info);
spin_unlock_irqrestore(&info->lock, flags);
hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, dev);
if (info->serial_signals & SerialSignal_DCD)
netif_carrier_on(dev);
else
netif_carrier_off(dev);
return 0;
}
@ -2522,8 +2524,12 @@ void isr_io_pin( SLMP_INFO *info, u16 status )
} else
info->input_signal_events.dcd_down++;
#ifdef CONFIG_HDLC
if (info->netcount)
hdlc_set_carrier(status & SerialSignal_DCD, info->netdev);
if (info->netcount) {
if (status & SerialSignal_DCD)
netif_carrier_on(info->netdev);
else
netif_carrier_off(info->netdev);
}
#endif
}
if (status & MISCSTATUS_CTS_LATCHED)

View File

@ -239,6 +239,8 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
total_ticks = (unsigned int) cputime64_sub(cur_jiffies,
this_dbs_info->prev_cpu_wall);
this_dbs_info->prev_cpu_wall = cur_jiffies;
if (!total_ticks)
return;
/*
* Every sampling_rate, we check, if current idle time is less
* than 20% (default), then we try to increase frequency
@ -304,6 +306,9 @@ static void do_dbs_timer(void *data)
unsigned int cpu = smp_processor_id();
struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu);
if (!dbs_info->enable)
return;
dbs_check_cpu(dbs_info);
queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work,
usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
@ -319,11 +324,11 @@ static inline void dbs_timer_init(unsigned int cpu)
return;
}
static inline void dbs_timer_exit(unsigned int cpu)
static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
{
struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu);
cancel_rearming_delayed_workqueue(kondemand_wq, &dbs_info->work);
dbs_info->enable = 0;
cancel_delayed_work(&dbs_info->work);
flush_workqueue(kondemand_wq);
}
static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
@ -396,8 +401,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
case CPUFREQ_GOV_STOP:
mutex_lock(&dbs_mutex);
dbs_timer_exit(policy->cpu);
this_dbs_info->enable = 0;
dbs_timer_exit(this_dbs_info);
sysfs_remove_group(&policy->kobj, &dbs_attr_group);
dbs_enable--;
if (dbs_enable == 0)

View File

@ -828,7 +828,7 @@ static int __init ioat_init_module(void)
/* if forced, worst case is that rmmod hangs */
__unsafe(THIS_MODULE);
return pci_module_init(&ioat_pci_drv);
return pci_register_driver(&ioat_pci_drv);
}
module_init(ioat_init_module);

View File

@ -429,7 +429,7 @@ static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hd
if (fcmd->data) {
if (SCpnt->use_sg)
dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->buffer,
dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->request_buffer,
SCpnt->use_sg,
SCpnt->sc_data_direction);
else
@ -810,7 +810,7 @@ static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, i
SCpnt->request_bufflen,
SCpnt->sc_data_direction);
} else {
struct scatterlist *sg = (struct scatterlist *)SCpnt->buffer;
struct scatterlist *sg = (struct scatterlist *)SCpnt->request_buffer;
int nents;
FCD(("XXX: Use_sg %d %d\n", SCpnt->use_sg, sg->length))

View File

@ -48,10 +48,8 @@ config FUSION_SAS
List of supported controllers:
LSISAS1064
LSISAS1066
LSISAS1068
LSISAS1064E
LSISAS1066E
LSISAS1068E
config FUSION_MAX_SGE

View File

@ -9,7 +9,6 @@
#EXTRA_CFLAGS += -DMPT_DEBUG_EXIT
#EXTRA_CFLAGS += -DMPT_DEBUG_FAIL
#
# driver/module specifics...
#

View File

@ -436,8 +436,6 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
*/
if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
freereq = 0;
devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
ioc->name, pEvReply));
} else {
devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
ioc->name, pEvReply));
@ -678,19 +676,19 @@ int
mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
{
MPT_ADAPTER *ioc;
const struct pci_device_id *id;
if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
return -EINVAL;
}
MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
/* call per pci device probe entry point */
list_for_each_entry(ioc, &ioc_list, list) {
if(dd_cbfunc->probe) {
dd_cbfunc->probe(ioc->pcidev,
ioc->pcidev->driver->id_table);
}
id = ioc->pcidev->driver ?
ioc->pcidev->driver->id_table : NULL;
if (dd_cbfunc->probe)
dd_cbfunc->probe(ioc->pcidev, id);
}
return 0;
@ -1056,9 +1054,8 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
dinitprintk((MYIOC_s_INFO_FMT
"host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
ioc->name,
ioc->HostPageBuffer,
ioc->HostPageBuffer_dma,
ioc->name, ioc->HostPageBuffer,
(u32)ioc->HostPageBuffer_dma,
host_page_buffer_sz));
ioc->alloc_total += host_page_buffer_sz;
ioc->HostPageBuffer_sz = host_page_buffer_sz;
@ -1380,6 +1377,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
printk(KERN_WARNING MYNAM
": WARNING - %s did not initialize properly! (%d)\n",
ioc->name, r);
list_del(&ioc->list);
if (ioc->alt_ioc)
ioc->alt_ioc->alt_ioc = NULL;
@ -1762,9 +1760,9 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
* chips (mpt_adapter_disable,
* mpt_diag_reset)
*/
ioc->cached_fw = NULL;
ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
ioc->alt_ioc->cached_fw = NULL;
}
} else {
printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
@ -1885,7 +1883,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
/* FIXME? Examine results here? */
}
out:
out:
if ((ret != 0) && irq_allocated) {
free_irq(ioc->pci_irq, ioc);
if (mpt_msi_enable)
@ -2670,6 +2668,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
ioc->name, count));
ioc->aen_event_read_flag=0;
return r;
}
@ -2737,6 +2736,8 @@ mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
ioc->alloc_total += size;
ioc->alt_ioc->alloc_total -= size;
} else {
if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
ioc->alloc_total += size;
@ -3166,6 +3167,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
static int
mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
{
MPT_ADAPTER *iocp=NULL;
u32 diag0val;
u32 doorbell;
int hard_reset_done = 0;
@ -3301,17 +3303,23 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
/* FIXME? Examine results here? */
}
if (ioc->cached_fw) {
if (ioc->cached_fw)
iocp = ioc;
else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
iocp = ioc->alt_ioc;
if (iocp) {
/* If the DownloadBoot operation fails, the
* IOC will be left unusable. This is a fatal error
* case. _diag_reset will return < 0
*/
for (count = 0; count < 30; count ++) {
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
break;
}
dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n",
iocp->name, diag0val, count));
/* wait 1 sec */
if (sleepFlag == CAN_SLEEP) {
msleep (1000);
@ -3320,7 +3328,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
}
}
if ((count = mpt_downloadboot(ioc,
(MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
(MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
printk(KERN_WARNING MYNAM
": firmware downloadboot failure (%d)!\n", count);
}
@ -3907,18 +3915,18 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
if (sleepFlag == CAN_SLEEP) {
while (--cntdn) {
msleep (1);
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
break;
msleep (1);
count++;
}
} else {
while (--cntdn) {
mdelay (1);
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
break;
mdelay (1);
count++;
}
}
@ -4883,6 +4891,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
if (!pIoc4)
return;
ioc->alloc_total += iocpage4sz;
} else {
ioc4_dma = ioc->spi_data.IocPg4_dma;
iocpage4sz = ioc->spi_data.IocPg4Sz;
@ -4899,6 +4908,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
} else {
pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
ioc->spi_data.pIocPg4 = NULL;
ioc->alloc_total -= iocpage4sz;
}
}
@ -5030,19 +5040,18 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
EventAck_t *pAck;
if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK "
"request frame for Event=%x EventContext=%x EventData=%x!\n",
ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
le32_to_cpu(evnp->Data[0]));
dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
ioc->name,__FUNCTION__));
return -1;
}
memset(pAck, 0, sizeof(*pAck));
dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
pAck->Function = MPI_FUNCTION_EVENT_ACK;
pAck->ChainOffset = 0;
pAck->Reserved[0] = pAck->Reserved[1] = 0;
pAck->MsgFlags = 0;
pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
pAck->Event = evnp->Event;
pAck->EventContext = evnp->EventContext;
@ -5704,9 +5713,9 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
break;
case MPI_EVENT_EVENT_CHANGE:
if (evData0)
ds = "Events(ON) Change";
ds = "Events ON";
else
ds = "Events(OFF) Change";
ds = "Events OFF";
break;
case MPI_EVENT_INTEGRATED_RAID:
{
@ -5777,8 +5786,27 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
break;
case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
snprintf(evStr, EVENT_DESCR_STR_SZ,
"SAS Device Status Change: No Persistancy "
"Added: id=%d", id);
"SAS Device Status Change: No Persistancy: id=%d", id);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
snprintf(evStr, EVENT_DESCR_STR_SZ,
"SAS Device Status Change: Internal Device Reset : id=%d", id);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
snprintf(evStr, EVENT_DESCR_STR_SZ,
"SAS Device Status Change: Internal Task Abort : id=%d", id);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
snprintf(evStr, EVENT_DESCR_STR_SZ,
"SAS Device Status Change: Internal Abort Task Set : id=%d", id);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
snprintf(evStr, EVENT_DESCR_STR_SZ,
"SAS Device Status Change: Internal Clear Task Set : id=%d", id);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
snprintf(evStr, EVENT_DESCR_STR_SZ,
"SAS Device Status Change: Internal Query Task : id=%d", id);
break;
default:
snprintf(evStr, EVENT_DESCR_STR_SZ,
@ -6034,7 +6062,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
* @ioc: Pointer to MPT_ADAPTER structure
* @log_info: U32 LogInfo reply word from the IOC
*
* Refer to lsi/fc_log.h.
* Refer to lsi/mpi_log_fc.h.
*/
static void
mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
@ -6131,8 +6159,10 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
"Invalid SAS Address", /* 01h */
NULL, /* 02h */
"Invalid Page", /* 03h */
NULL, /* 04h */
"Task Terminated" /* 05h */
"Diag Message Error", /* 04h */
"Task Terminated", /* 05h */
"Enclosure Management", /* 06h */
"Target Mode" /* 07h */
};
static char *pl_code_str[] = {
NULL, /* 00h */
@ -6158,7 +6188,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
"IO Executed", /* 14h */
"Persistant Reservation Out Not Affiliation Owner", /* 15h */
"Open Transmit DMA Abort", /* 16h */
NULL, /* 17h */
"IO Device Missing Delay Retry", /* 17h */
NULL, /* 18h */
NULL, /* 19h */
NULL, /* 1Ah */
@ -6238,7 +6268,7 @@ static void
mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
{
u32 status = ioc_status & MPI_IOCSTATUS_MASK;
char *desc = "";
char *desc = NULL;
switch (status) {
case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
@ -6348,7 +6378,7 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
desc = "Others";
break;
}
if (desc != "")
if (desc != NULL)
printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
}
@ -6386,7 +6416,6 @@ EXPORT_SYMBOL(mpt_alloc_fw_memory);
EXPORT_SYMBOL(mpt_free_fw_memory);
EXPORT_SYMBOL(mptbase_sas_persist_operation);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* fusion_init - Fusion MPT base driver initialization routine.

View File

@ -75,8 +75,8 @@
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
#endif
#define MPT_LINUX_VERSION_COMMON "3.04.00"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.00"
#define MPT_LINUX_VERSION_COMMON "3.04.01"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.01"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
@ -307,8 +307,8 @@ typedef struct _SYSIF_REGS
u32 HostIndex; /* 50 Host Index register */
u32 Reserved4[15]; /* 54-8F */
u32 Fubar; /* 90 For Fubar usage */
u32 Reserved5[1050];/* 94-10F8 */
u32 Reset_1078; /* 10FC Reset 1078 */
u32 Reserved5[1050];/* 94-10F8 */
u32 Reset_1078; /* 10FC Reset 1078 */
} SYSIF_REGS;
/*
@ -363,6 +363,7 @@ typedef struct _VirtDevice {
#define MPT_TARGET_FLAGS_VALID_56 0x10
#define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20
#define MPT_TARGET_FLAGS_RAID_COMPONENT 0x40
#define MPT_TARGET_FLAGS_LED_ON 0x80
/*
* /proc/mpt interface
@ -634,7 +635,6 @@ typedef struct _MPT_ADAPTER
u16 handle;
int sas_index; /* index refrencing */
MPT_SAS_MGMT sas_mgmt;
int num_ports;
struct work_struct sas_persist_task;
struct work_struct fc_setup_reset_work;
@ -644,7 +644,6 @@ typedef struct _MPT_ADAPTER
struct work_struct fc_rescan_work;
char fc_rescan_work_q_name[KOBJ_NAME_LEN];
struct workqueue_struct *fc_rescan_work_q;
u8 port_serial_number;
} MPT_ADAPTER;
/*
@ -982,7 +981,7 @@ typedef struct _MPT_SCSI_HOST {
wait_queue_head_t scandv_waitq;
int scandv_wait_done;
long last_queue_full;
u8 mpt_pq_filter;
u16 tm_iocstatus;
} MPT_SCSI_HOST;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

View File

@ -2332,7 +2332,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* Prototype Routine for the HP HOST INFO command.
/* Prototype Routine for the HOST INFO command.
*
* Outputs: None.
* Return: 0 if successful
@ -2568,7 +2568,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* Prototype Routine for the HP TARGET INFO command.
/* Prototype Routine for the TARGET INFO command.
*
* Outputs: None.
* Return: 0 if successful

View File

@ -354,9 +354,6 @@ struct mpt_ioctl_command32 {
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* HP Specific IOCTL Defines and Structures
*/
#define CPQFCTS_IOC_MAGIC 'Z'
#define HP_IOC_MAGIC 'Z'
@ -364,8 +361,6 @@ struct mpt_ioctl_command32 {
#define HP_GETHOSTINFO1 _IOR(HP_IOC_MAGIC, 20, hp_host_info_rev0_t)
#define HP_GETTARGETINFO _IOR(HP_IOC_MAGIC, 21, hp_target_info_t)
/* All HP IOCTLs must include this header
*/
typedef struct _hp_header {
unsigned int iocnum;
unsigned int host;

View File

@ -77,10 +77,6 @@ MODULE_DESCRIPTION(my_NAME);
MODULE_LICENSE("GPL");
/* Command line args */
static int mpt_pq_filter = 0;
module_param(mpt_pq_filter, int, 0);
MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
#define MPTFC_DEV_LOSS_TMO (60)
static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */
module_param(mptfc_dev_loss_tmo, int, 0);
@ -513,8 +509,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
if (vtarget->num_luns == 0) {
vtarget->ioc_id = hd->ioc->id;
vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
MPT_TARGET_FLAGS_VALID_INQUIRY;
vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
hd->Targets[sdev->id] = vtarget;
}
@ -1129,13 +1124,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hd->timer.data = (unsigned long) hd;
hd->timer.function = mptscsih_timer_expired;
hd->mpt_pq_filter = mpt_pq_filter;
ddvprintk((MYIOC_s_INFO_FMT
"mpt_pq_filter %x\n",
ioc->name,
mpt_pq_filter));
init_waitqueue_head(&hd->scandv_waitq);
hd->scandv_wait_done = 0;
hd->last_queue_full = 0;

View File

@ -67,20 +67,19 @@
#define my_VERSION MPT_LINUX_VERSION_COMMON
#define MYNAM "mptsas"
/*
* Reserved channel for integrated raid
*/
#define MPTSAS_RAID_CHANNEL 1
MODULE_AUTHOR(MODULEAUTHOR);
MODULE_DESCRIPTION(my_NAME);
MODULE_LICENSE("GPL");
static int mpt_pq_filter;
module_param(mpt_pq_filter, int, 0);
MODULE_PARM_DESC(mpt_pq_filter,
"Enable peripheral qualifier filter: enable=1 "
"(default=0)");
static int mpt_pt_clear;
module_param(mpt_pt_clear, int, 0);
MODULE_PARM_DESC(mpt_pt_clear,
"Clear persistency table: enable=1 "
" Clear persistency table: enable=1 "
"(default=MPTSCSIH_PT_CLEAR=0)");
static int mptsasDoneCtx = -1;
@ -144,7 +143,6 @@ struct mptsas_devinfo {
* Specific details on ports, wide/narrow
*/
struct mptsas_portinfo_details{
u8 port_id; /* port number provided to transport */
u16 num_phys; /* number of phys belong to this port */
u64 phy_bitmask; /* TODO, extend support for 255 phys */
struct sas_rphy *rphy; /* transport layer rphy object */
@ -350,10 +348,10 @@ mptsas_port_delete(struct mptsas_portinfo_details * port_details)
port_info = port_details->port_info;
phy_info = port_info->phy_info;
dsaswideprintk((KERN_DEBUG "%s: [%p]: port=%02d num_phys=%02d "
dsaswideprintk((KERN_DEBUG "%s: [%p]: num_phys=%02d "
"bitmask=0x%016llX\n",
__FUNCTION__, port_details, port_details->port_id,
port_details->num_phys, port_details->phy_bitmask));
__FUNCTION__, port_details, port_details->num_phys,
port_details->phy_bitmask));
for (i = 0; i < port_info->num_phys; i++, phy_info++) {
if(phy_info->port_details != port_details)
@ -462,9 +460,8 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
* phy be removed by firmware events.
*/
dsaswideprintk((KERN_DEBUG
"%s: [%p]: port=%d deleting phy = %d\n",
__FUNCTION__, port_details,
port_details->port_id, i));
"%s: [%p]: deleting phy = %d\n",
__FUNCTION__, port_details, i));
port_details->num_phys--;
port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
@ -493,7 +490,6 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
goto out;
port_details->num_phys = 1;
port_details->port_info = port_info;
port_details->port_id = ioc->port_serial_number++;
if (phy_info->phy_id < 64 )
port_details->phy_bitmask |=
(1 << phy_info->phy_id);
@ -525,12 +521,8 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
mptsas_get_port(phy_info_cmp);
port_details->starget =
mptsas_get_starget(phy_info_cmp);
port_details->port_id =
phy_info_cmp->port_details->port_id;
port_details->num_phys =
phy_info_cmp->port_details->num_phys;
// port_info->port_serial_number--;
ioc->port_serial_number--;
if (!phy_info_cmp->port_details->num_phys)
kfree(phy_info_cmp->port_details);
} else
@ -554,11 +546,11 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
if (!port_details)
continue;
dsaswideprintk((KERN_DEBUG
"%s: [%p]: phy_id=%02d port_id=%02d num_phys=%02d "
"%s: [%p]: phy_id=%02d num_phys=%02d "
"bitmask=0x%016llX\n",
__FUNCTION__,
port_details, i, port_details->port_id,
port_details->num_phys, port_details->phy_bitmask));
port_details, i, port_details->num_phys,
port_details->phy_bitmask));
dsaswideprintk((KERN_DEBUG"\t\tport = %p rphy=%p\n",
port_details->port, port_details->rphy));
}
@ -651,16 +643,13 @@ mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
static int
mptsas_slave_configure(struct scsi_device *sdev)
{
struct Scsi_Host *host = sdev->host;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
/*
* RAID volumes placed beyond the last expected port.
* Ignore sending sas mode pages in that case..
*/
if (sdev->channel < hd->ioc->num_ports)
sas_read_port_mode_page(sdev);
if (sdev->channel == MPTSAS_RAID_CHANNEL)
goto out;
sas_read_port_mode_page(sdev);
out:
return mptscsih_slave_configure(sdev);
}
@ -689,10 +678,7 @@ mptsas_target_alloc(struct scsi_target *starget)
hd->Targets[target_id] = vtarget;
/*
* RAID volumes placed beyond the last expected port.
*/
if (starget->channel == hd->ioc->num_ports)
if (starget->channel == MPTSAS_RAID_CHANNEL)
goto out;
rphy = dev_to_rphy(starget->dev.parent);
@ -743,7 +729,7 @@ mptsas_target_destroy(struct scsi_target *starget)
if (!starget->hostdata)
return;
if (starget->channel == hd->ioc->num_ports)
if (starget->channel == MPTSAS_RAID_CHANNEL)
goto out;
rphy = dev_to_rphy(starget->dev.parent);
@ -783,10 +769,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
starget = scsi_target(sdev);
vdev->vtarget = starget->hostdata;
/*
* RAID volumes placed beyond the last expected port.
*/
if (sdev->channel == hd->ioc->num_ports)
if (sdev->channel == MPTSAS_RAID_CHANNEL)
goto out;
rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
@ -1608,11 +1591,7 @@ static int mptsas_probe_one_phy(struct device *dev,
if (phy_info->sas_port_add_phy) {
if (!port) {
port = sas_port_alloc(dev,
phy_info->port_details->port_id);
dsaswideprintk((KERN_DEBUG
"sas_port_alloc: port=%p dev=%p port_id=%d\n",
port, dev, phy_info->port_details->port_id));
port = sas_port_alloc_num(dev);
if (!port) {
error = -ENOMEM;
goto out;
@ -1625,6 +1604,9 @@ static int mptsas_probe_one_phy(struct device *dev,
goto out;
}
mptsas_set_port(phy_info, port);
dsaswideprintk((KERN_DEBUG
"sas_port_alloc: port=%p dev=%p port_id=%d\n",
port, dev, port->port_identifier));
}
dsaswideprintk((KERN_DEBUG "sas_port_add_phy: phy_id=%d\n",
phy_info->phy_id));
@ -1736,7 +1718,6 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
hba = NULL;
}
mutex_unlock(&ioc->sas_topology_mutex);
ioc->num_ports = port_info->num_phys;
for (i = 0; i < port_info->num_phys; i++) {
mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
@ -1939,7 +1920,8 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
expander_sas_address)
continue;
#ifdef MPT_DEBUG_SAS_WIDE
dev_printk(KERN_DEBUG, &port->dev, "delete\n");
dev_printk(KERN_DEBUG, &port->dev,
"delete port (%d)\n", port->port_identifier);
#endif
sas_port_delete(port);
mptsas_port_delete(phy_info->port_details);
@ -1984,7 +1966,7 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
goto out;
for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
scsi_add_device(ioc->sh, ioc->num_ports,
scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
}
out:
@ -2185,7 +2167,8 @@ mptsas_hotplug_work(void *arg)
ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
#ifdef MPT_DEBUG_SAS_WIDE
dev_printk(KERN_DEBUG, &port->dev, "delete\n");
dev_printk(KERN_DEBUG, &port->dev,
"delete port (%d)\n", port->port_identifier);
#endif
sas_port_delete(port);
mptsas_port_delete(phy_info->port_details);
@ -2289,35 +2272,26 @@ mptsas_hotplug_work(void *arg)
mptsas_set_rphy(phy_info, rphy);
break;
case MPTSAS_ADD_RAID:
sdev = scsi_device_lookup(
ioc->sh,
ioc->num_ports,
ev->id,
0);
sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
ev->id, 0);
if (sdev) {
scsi_device_put(sdev);
break;
}
printk(MYIOC_s_INFO_FMT
"attaching raid volume, channel %d, id %d\n",
ioc->name, ioc->num_ports, ev->id);
scsi_add_device(ioc->sh,
ioc->num_ports,
ev->id,
0);
ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0);
mpt_findImVolumes(ioc);
break;
case MPTSAS_DEL_RAID:
sdev = scsi_device_lookup(
ioc->sh,
ioc->num_ports,
ev->id,
0);
sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
ev->id, 0);
if (!sdev)
break;
printk(MYIOC_s_INFO_FMT
"removing raid volume, channel %d, id %d\n",
ioc->name, ioc->num_ports, ev->id);
ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
vdevice = sdev->hostdata;
vdevice->vtarget->deleted = 1;
mptsas_target_reset(ioc, vdevice->vtarget);
@ -2723,7 +2697,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hd->timer.data = (unsigned long) hd;
hd->timer.function = mptscsih_timer_expired;
hd->mpt_pq_filter = mpt_pq_filter;
ioc->sas_data.ptClear = mpt_pt_clear;
if (ioc->sas_data.ptClear==1) {
@ -2731,12 +2704,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
}
ddvprintk((MYIOC_s_INFO_FMT
"mpt_pq_filter %x mpt_pq_filter %x\n",
ioc->name,
mpt_pq_filter,
mpt_pq_filter));
init_waitqueue_head(&hd->scandv_waitq);
hd->scandv_wait_done = 0;
hd->last_queue_full = 0;

View File

@ -66,6 +66,7 @@
#include "mptbase.h"
#include "mptscsih.h"
#include "lsi/mpi_log_sas.h"
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#define my_NAME "Fusion MPT SCSI Host driver"
@ -127,7 +128,7 @@ static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
@ -497,6 +498,34 @@ mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
return SUCCESS;
} /* mptscsih_AddSGE() */
static void
mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
U32 SlotStatus)
{
MPT_FRAME_HDR *mf;
SEPRequest_t *SEPMsg;
if (ioc->bus_type == FC)
return;
if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
dfailprintk((MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
ioc->name,__FUNCTION__));
return;
}
SEPMsg = (SEPRequest_t *)mf;
SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
SEPMsg->Bus = vtarget->bus_id;
SEPMsg->TargetID = vtarget->target_id;
SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
SEPMsg->SlotStatus = SlotStatus;
devtverboseprintk((MYIOC_s_WARN_FMT
"Sending SEP cmd=%x id=%d bus=%d\n",
ioc->name, SlotStatus, SEPMsg->TargetID, SEPMsg->Bus));
mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptscsih_io_done - Main SCSI IO callback routine registered to
@ -520,6 +549,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
SCSIIORequest_t *pScsiReq;
SCSIIOReply_t *pScsiReply;
u16 req_idx, req_idx_MR;
VirtDevice *vdev;
VirtTarget *vtarget;
hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
@ -538,6 +569,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
}
sc = hd->ScsiLookup[req_idx];
hd->ScsiLookup[req_idx] = NULL;
if (sc == NULL) {
MPIHeader_t *hdr = (MPIHeader_t *)mf;
@ -553,6 +585,12 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
return 1;
}
if ((unsigned char *)mf != sc->host_scribble) {
mptscsih_freeChainBuffers(ioc, req_idx);
return 1;
}
sc->host_scribble = NULL;
sc->result = DID_OK << 16; /* Set default reply as OK */
pScsiReq = (SCSIIORequest_t *) mf;
pScsiReply = (SCSIIOReply_t *) mr;
@ -640,10 +678,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
hd->sel_timeout[pScsiReq->TargetID]++;
vdev = sc->device->hostdata;
if (!vdev)
break;
vtarget = vdev->vtarget;
if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
mptscsih_issue_sep_command(ioc, vtarget,
MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
}
break;
case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
if ( ioc->bus_type == SAS ) {
u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
log_info &=SAS_LOGINFO_MASK;
if (log_info == SAS_LOGINFO_NEXUS_LOSS) {
sc->result = (DID_BUS_BUSY << 16);
break;
}
}
}
/*
* Allow non-SAS & non-NEXUS_LOSS to drop into below code
*/
case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
/* Linux handles an unsolicited DID_RESET better
* than an unsolicited DID_ABORT.
@ -784,8 +848,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
sc->request_bufflen, sc->sc_data_direction);
}
hd->ScsiLookup[req_idx] = NULL;
sc->scsi_done(sc); /* Issue the command callback */
/* Free Chain buffers */
@ -827,9 +889,17 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
mf, SCpnt));
/* Free Chain buffers */
mptscsih_freeChainBuffers(ioc, ii);
/* Free Message frames */
mpt_free_msg_frame(ioc, mf);
if ((unsigned char *)mf != SCpnt->host_scribble)
continue;
/* Set status, free OS resources (SG DMA buffers)
* Do OS callback
* Free driver resources (chain, msg buffers)
*/
if (SCpnt->use_sg) {
pci_unmap_sg(ioc->pcidev,
@ -845,12 +915,6 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
SCpnt->result = DID_RESET << 16;
SCpnt->host_scribble = NULL;
/* Free Chain buffers */
mptscsih_freeChainBuffers(ioc, ii);
/* Free Message frames */
mpt_free_msg_frame(ioc, mf);
SCpnt->scsi_done(SCpnt); /* Issue the command callback */
}
}
@ -887,10 +951,10 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
if ((sc = hd->ScsiLookup[ii]) != NULL) {
mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
if (mf == NULL)
continue;
dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
continue;
@ -899,6 +963,8 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
hd->ScsiLookup[ii] = NULL;
mptscsih_freeChainBuffers(hd->ioc, ii);
mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
if ((unsigned char *)mf != sc->host_scribble)
continue;
if (sc->use_sg) {
pci_unmap_sg(hd->ioc->pcidev,
(struct scatterlist *) sc->request_buffer,
@ -1341,8 +1407,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
goto fail;
}
SCpnt->host_scribble = (unsigned char *)mf;
hd->ScsiLookup[my_idx] = SCpnt;
SCpnt->host_scribble = NULL;
mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
@ -1529,6 +1595,12 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
}
/*
* Check IOCStatus from TM reply message
*/
if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS)
rc = FAILED;
dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
return rc;
@ -1654,6 +1726,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
int scpnt_idx;
int retval;
VirtDevice *vdev;
ulong sn = SCpnt->serial_number;
/* If we can't locate our host adapter structure, return FAILED status.
*/
@ -1707,6 +1780,11 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
SCpnt->serial_number == sn) {
retval = FAILED;
}
printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
hd->ioc->name,
((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
@ -2023,6 +2101,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
hd->tm_iocstatus = iocstatus;
dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
/* Error? (anything non-zero?) */
@ -2401,6 +2480,13 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
ioc->eventContext++;
if (hd->ioc->pcidev->vendor ==
PCI_VENDOR_ID_IBM) {
mptscsih_issue_sep_command(hd->ioc,
vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
vdev->vtarget->tflags |=
MPT_TARGET_FLAGS_LED_ON;
}
}
}
} else {
@ -2409,7 +2495,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
}
}
static u32
static int
SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
{
MPT_SCSI_HOST *hd;

View File

@ -83,10 +83,6 @@ static int mpt_saf_te = MPTSCSIH_SAF_TE;
module_param(mpt_saf_te, int, 0);
MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=0)");
static int mpt_pq_filter = 0;
module_param(mpt_pq_filter, int, 0);
MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
static void mptspi_write_offset(struct scsi_target *, int);
static void mptspi_write_width(struct scsi_target *, int);
static int mptspi_write_spi_device_pg1(struct scsi_target *,
@ -1047,14 +1043,12 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hd->timer.function = mptscsih_timer_expired;
ioc->spi_data.Saf_Te = mpt_saf_te;
hd->mpt_pq_filter = mpt_pq_filter;
hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
ddvprintk((MYIOC_s_INFO_FMT
"saf_te %x mpt_pq_filter %x\n",
"saf_te %x\n",
ioc->name,
mpt_saf_te,
mpt_pq_filter));
mpt_saf_te));
ioc->spi_data.noQas = 0;
init_waitqueue_head(&hd->scandv_waitq);

View File

@ -132,6 +132,7 @@ static int __init dummy_init_module(void)
for (i = 0; i < numdummies && !err; i++)
err = dummy_init_one(i);
if (err) {
i--;
while (--i >= 0)
dummy_free_one(i);
}

View File

@ -110,6 +110,9 @@ struct e1000_adapter;
#define E1000_MIN_RXD 80
#define E1000_MAX_82544_RXD 4096
/* this is the size past which hardware will drop packets when setting LPE=0 */
#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
/* Supported Rx Buffer Sizes */
#define E1000_RXBUFFER_128 128 /* Used for packet split */
#define E1000_RXBUFFER_256 256 /* Used for packet split */

View File

@ -36,7 +36,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
#else
#define DRIVERNAPI "-NAPI"
#endif
#define DRV_VERSION "7.1.9-k2"DRIVERNAPI
#define DRV_VERSION "7.1.9-k4"DRIVERNAPI
char e1000_driver_version[] = DRV_VERSION;
static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
@ -1068,7 +1068,7 @@ e1000_sw_init(struct e1000_adapter *adapter)
pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
adapter->rx_buffer_len = MAXIMUM_ETHERNET_FRAME_SIZE;
adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
adapter->rx_ps_bsize0 = E1000_RXBUFFER_128;
hw->max_frame_size = netdev->mtu +
ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
@ -3148,7 +3148,6 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
adapter->rx_buffer_len = E1000_RXBUFFER_16384;
/* adjust allocation if LPE protects us, and we aren't using SBP */
#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
if (!adapter->hw.tbi_compatibility_on &&
((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) ||
(max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
@ -3387,8 +3386,8 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
E1000_WRITE_REG(hw, IMC, ~0);
E1000_WRITE_FLUSH(hw);
}
if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0])))
__netif_rx_schedule(&adapter->polling_netdev[0]);
if (likely(netif_rx_schedule_prep(netdev)))
__netif_rx_schedule(netdev);
else
e1000_irq_enable(adapter);
#else
@ -3431,34 +3430,26 @@ e1000_clean(struct net_device *poll_dev, int *budget)
{
struct e1000_adapter *adapter;
int work_to_do = min(*budget, poll_dev->quota);
int tx_cleaned = 0, i = 0, work_done = 0;
int tx_cleaned = 0, work_done = 0;
/* Must NOT use netdev_priv macro here. */
adapter = poll_dev->priv;
/* Keep link state information with original netdev */
if (!netif_carrier_ok(adapter->netdev))
if (!netif_carrier_ok(poll_dev))
goto quit_polling;
while (poll_dev != &adapter->polling_netdev[i]) {
i++;
BUG_ON(i == adapter->num_rx_queues);
/* e1000_clean is called per-cpu. This lock protects
* tx_ring[0] from being cleaned by multiple cpus
* simultaneously. A failure obtaining the lock means
* tx_ring[0] is currently being cleaned anyway. */
if (spin_trylock(&adapter->tx_queue_lock)) {
tx_cleaned = e1000_clean_tx_irq(adapter,
&adapter->tx_ring[0]);
spin_unlock(&adapter->tx_queue_lock);
}
if (likely(adapter->num_tx_queues == 1)) {
/* e1000_clean is called per-cpu. This lock protects
* tx_ring[0] from being cleaned by multiple cpus
* simultaneously. A failure obtaining the lock means
* tx_ring[0] is currently being cleaned anyway. */
if (spin_trylock(&adapter->tx_queue_lock)) {
tx_cleaned = e1000_clean_tx_irq(adapter,
&adapter->tx_ring[0]);
spin_unlock(&adapter->tx_queue_lock);
}
} else
tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[i]);
adapter->clean_rx(adapter, &adapter->rx_ring[i],
adapter->clean_rx(adapter, &adapter->rx_ring[0],
&work_done, work_to_do);
*budget -= work_done;
@ -3466,7 +3457,7 @@ e1000_clean(struct net_device *poll_dev, int *budget)
/* If no Tx and not enough Rx work done, exit the polling mode */
if ((!tx_cleaned && (work_done == 0)) ||
!netif_running(adapter->netdev)) {
!netif_running(poll_dev)) {
quit_polling:
netif_rx_complete(poll_dev);
e1000_irq_enable(adapter);
@ -3681,6 +3672,9 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
length = le16_to_cpu(rx_desc->length);
/* adjust length to remove Ethernet CRC */
length -= 4;
if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
/* All receives must fit into a single buffer */
E1000_DBG("%s: Receive packet consumed multiple"
@ -3885,8 +3879,9 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
pci_dma_sync_single_for_device(pdev,
ps_page_dma->ps_page_dma[0],
PAGE_SIZE, PCI_DMA_FROMDEVICE);
/* remove the CRC */
l1 -= 4;
skb_put(skb, l1);
length += l1;
goto copydone;
} /* if */
}
@ -3905,6 +3900,10 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
skb->truesize += length;
}
/* strip the ethernet crc, problem is we're using pages now so
* this whole operation can get a little cpu intensive */
pskb_trim(skb, skb->len - 4);
copydone:
e1000_rx_checksum(adapter, staterr,
le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb);
@ -4752,6 +4751,7 @@ static void
e1000_netpoll(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
disable_irq(adapter->pdev->irq);
e1000_intr(adapter->pdev->irq, netdev, NULL);
e1000_clean_tx_irq(adapter, adapter->tx_ring);

View File

@ -271,6 +271,7 @@ static int __init ifb_init_module(void)
for (i = 0; i < numifbs && !err; i++)
err = ifb_init_one(i);
if (err) {
i--;
while (--i >= 0)
ifb_free_one(i);
}

View File

@ -50,7 +50,7 @@
#include "sky2.h"
#define DRV_NAME "sky2"
#define DRV_VERSION "1.4"
#define DRV_VERSION "1.5"
#define PFX DRV_NAME " "
/*
@ -2204,9 +2204,6 @@ static int sky2_poll(struct net_device *dev0, int *budget)
int work_done = 0;
u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
if (!~status)
goto out;
if (status & Y2_IS_HW_ERR)
sky2_hw_intr(hw);
@ -2243,7 +2240,7 @@ static int sky2_poll(struct net_device *dev0, int *budget)
if (sky2_more_work(hw))
return 1;
out:
netif_rx_complete(dev0);
sky2_read32(hw, B0_Y2_SP_LISR);

View File

@ -84,7 +84,7 @@ MODULE_DEVICE_TABLE(pci, spider_net_pci_tbl);
*
* returns the content of the specified SMMIO register.
*/
static u32
static inline u32
spider_net_read_reg(struct spider_net_card *card, u32 reg)
{
u32 value;
@ -101,7 +101,7 @@ spider_net_read_reg(struct spider_net_card *card, u32 reg)
* @reg: register to write to
* @value: value to write into the specified SMMIO register
*/
static void
static inline void
spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value)
{
value = cpu_to_le32(value);
@ -259,39 +259,10 @@ spider_net_get_mac_address(struct net_device *netdev)
*
* returns the status as in the dmac_cmd_status field of the descriptor
*/
static enum spider_net_descr_status
static inline int
spider_net_get_descr_status(struct spider_net_descr *descr)
{
u32 cmd_status;
cmd_status = descr->dmac_cmd_status;
cmd_status >>= SPIDER_NET_DESCR_IND_PROC_SHIFT;
/* no need to mask out any bits, as cmd_status is 32 bits wide only
* (and unsigned) */
return cmd_status;
}
/**
* spider_net_set_descr_status -- sets the status of a descriptor
* @descr: descriptor to change
* @status: status to set in the descriptor
*
* changes the status to the specified value. Doesn't change other bits
* in the status
*/
static void
spider_net_set_descr_status(struct spider_net_descr *descr,
enum spider_net_descr_status status)
{
u32 cmd_status;
/* read the status */
cmd_status = descr->dmac_cmd_status;
/* clean the upper 4 bits */
cmd_status &= SPIDER_NET_DESCR_IND_PROC_MASKO;
/* add the status to it */
cmd_status |= ((u32)status)<<SPIDER_NET_DESCR_IND_PROC_SHIFT;
/* and write it back */
descr->dmac_cmd_status = cmd_status;
return descr->dmac_cmd_status & SPIDER_NET_DESCR_IND_PROC_MASK;
}
/**
@ -328,24 +299,23 @@ spider_net_free_chain(struct spider_net_card *card,
static int
spider_net_init_chain(struct spider_net_card *card,
struct spider_net_descr_chain *chain,
struct spider_net_descr *start_descr, int no)
struct spider_net_descr *start_descr,
int direction, int no)
{
int i;
struct spider_net_descr *descr;
dma_addr_t buf;
atomic_set(&card->rx_chain_refill,0);
descr = start_descr;
memset(descr, 0, sizeof(*descr) * no);
/* set up the hardware pointers in each descriptor */
for (i=0; i<no; i++, descr++) {
spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE);
descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE;
buf = pci_map_single(card->pdev, descr,
SPIDER_NET_DESCR_SIZE,
PCI_DMA_BIDIRECTIONAL);
direction);
if (buf == DMA_ERROR_CODE)
goto iommu_error;
@ -360,10 +330,11 @@ spider_net_init_chain(struct spider_net_card *card,
start_descr->prev = descr-1;
descr = start_descr;
for (i=0; i < no; i++, descr++) {
descr->next_descr_addr = descr->next->bus_addr;
}
if (direction == PCI_DMA_FROMDEVICE)
for (i=0; i < no; i++, descr++)
descr->next_descr_addr = descr->next->bus_addr;
spin_lock_init(&chain->lock);
chain->head = start_descr;
chain->tail = start_descr;
@ -375,7 +346,7 @@ spider_net_init_chain(struct spider_net_card *card,
if (descr->bus_addr)
pci_unmap_single(card->pdev, descr->bus_addr,
SPIDER_NET_DESCR_SIZE,
PCI_DMA_BIDIRECTIONAL);
direction);
return -ENOMEM;
}
@ -396,7 +367,7 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card)
dev_kfree_skb(descr->skb);
pci_unmap_single(card->pdev, descr->buf_addr,
SPIDER_NET_MAX_FRAME,
PCI_DMA_BIDIRECTIONAL);
PCI_DMA_FROMDEVICE);
}
descr = descr->next;
}
@ -446,15 +417,16 @@ spider_net_prepare_rx_descr(struct spider_net_card *card,
skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset);
/* io-mmu-map the skb */
buf = pci_map_single(card->pdev, descr->skb->data,
SPIDER_NET_MAX_FRAME, PCI_DMA_BIDIRECTIONAL);
SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE);
descr->buf_addr = buf;
if (buf == DMA_ERROR_CODE) {
dev_kfree_skb_any(descr->skb);
if (netif_msg_rx_err(card) && net_ratelimit())
pr_err("Could not iommu-map rx buffer\n");
spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE);
descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE;
} else {
descr->dmac_cmd_status = SPIDER_NET_DMAC_RX_CARDOWNED;
descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED |
SPIDER_NET_DMAC_NOINTR_COMPLETE;
}
return error;
@ -468,7 +440,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card,
* chip by writing to the appropriate register. DMA is enabled in
* spider_net_enable_rxdmac.
*/
static void
static inline void
spider_net_enable_rxchtails(struct spider_net_card *card)
{
/* assume chain is aligned correctly */
@ -483,7 +455,7 @@ spider_net_enable_rxchtails(struct spider_net_card *card)
* spider_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
* in the GDADMACCNTR register
*/
static void
static inline void
spider_net_enable_rxdmac(struct spider_net_card *card)
{
wmb();
@ -500,23 +472,24 @@ spider_net_enable_rxdmac(struct spider_net_card *card)
static void
spider_net_refill_rx_chain(struct spider_net_card *card)
{
struct spider_net_descr_chain *chain;
chain = &card->rx_chain;
struct spider_net_descr_chain *chain = &card->rx_chain;
unsigned long flags;
/* one context doing the refill (and a second context seeing that
* and omitting it) is ok. If called by NAPI, we'll be called again
* as spider_net_decode_one_descr is called several times. If some
* interrupt calls us, the NAPI is about to clean up anyway. */
if (atomic_inc_return(&card->rx_chain_refill) == 1)
while (spider_net_get_descr_status(chain->head) ==
SPIDER_NET_DESCR_NOT_IN_USE) {
if (spider_net_prepare_rx_descr(card, chain->head))
break;
chain->head = chain->head->next;
}
if (!spin_trylock_irqsave(&chain->lock, flags))
return;
atomic_dec(&card->rx_chain_refill);
while (spider_net_get_descr_status(chain->head) ==
SPIDER_NET_DESCR_NOT_IN_USE) {
if (spider_net_prepare_rx_descr(card, chain->head))
break;
chain->head = chain->head->next;
}
spin_unlock_irqrestore(&chain->lock, flags);
}
/**
@ -553,111 +526,6 @@ spider_net_alloc_rx_skbs(struct spider_net_card *card)
return result;
}
/**
* spider_net_release_tx_descr - processes a used tx descriptor
* @card: card structure
* @descr: descriptor to release
*
* releases a used tx descriptor (unmapping, freeing of skb)
*/
static void
spider_net_release_tx_descr(struct spider_net_card *card,
struct spider_net_descr *descr)
{
struct sk_buff *skb;
/* unmap the skb */
skb = descr->skb;
pci_unmap_single(card->pdev, descr->buf_addr, skb->len,
PCI_DMA_BIDIRECTIONAL);
dev_kfree_skb_any(skb);
/* set status to not used */
spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE);
}
/**
* spider_net_release_tx_chain - processes sent tx descriptors
* @card: adapter structure
* @brutal: if set, don't care about whether descriptor seems to be in use
*
* returns 0 if the tx ring is empty, otherwise 1.
*
* spider_net_release_tx_chain releases the tx descriptors that spider has
* finished with (if non-brutal) or simply release tx descriptors (if brutal).
* If some other context is calling this function, we return 1 so that we're
* scheduled again (if we were scheduled) and will not loose initiative.
*/
static int
spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
{
struct spider_net_descr_chain *tx_chain = &card->tx_chain;
enum spider_net_descr_status status;
if (atomic_inc_return(&card->tx_chain_release) != 1) {
atomic_dec(&card->tx_chain_release);
return 1;
}
for (;;) {
status = spider_net_get_descr_status(tx_chain->tail);
switch (status) {
case SPIDER_NET_DESCR_CARDOWNED:
if (!brutal)
goto out;
/* fallthrough, if we release the descriptors
* brutally (then we don't care about
* SPIDER_NET_DESCR_CARDOWNED) */
case SPIDER_NET_DESCR_RESPONSE_ERROR:
case SPIDER_NET_DESCR_PROTECTION_ERROR:
case SPIDER_NET_DESCR_FORCE_END:
if (netif_msg_tx_err(card))
pr_err("%s: forcing end of tx descriptor "
"with status x%02x\n",
card->netdev->name, status);
card->netdev_stats.tx_dropped++;
break;
case SPIDER_NET_DESCR_COMPLETE:
card->netdev_stats.tx_packets++;
card->netdev_stats.tx_bytes +=
tx_chain->tail->skb->len;
break;
default: /* any other value (== SPIDER_NET_DESCR_NOT_IN_USE) */
goto out;
}
spider_net_release_tx_descr(card, tx_chain->tail);
tx_chain->tail = tx_chain->tail->next;
}
out:
atomic_dec(&card->tx_chain_release);
netif_wake_queue(card->netdev);
if (status == SPIDER_NET_DESCR_CARDOWNED)
return 1;
return 0;
}
/**
* spider_net_cleanup_tx_ring - cleans up the TX ring
* @card: card structure
*
* spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use
* interrupts to cleanup our TX ring) and returns sent packets to the stack
* by freeing them
*/
static void
spider_net_cleanup_tx_ring(struct spider_net_card *card)
{
if ( (spider_net_release_tx_chain(card, 0)) &&
(card->netdev->flags & IFF_UP) ) {
mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER);
}
}
/**
* spider_net_get_multicast_hash - generates hash for multicast filter table
* @addr: multicast address
@ -760,97 +628,6 @@ spider_net_disable_rxdmac(struct spider_net_card *card)
SPIDER_NET_DMA_RX_FEND_VALUE);
}
/**
* spider_net_stop - called upon ifconfig down
* @netdev: interface device structure
*
* always returns 0
*/
int
spider_net_stop(struct net_device *netdev)
{
struct spider_net_card *card = netdev_priv(netdev);
tasklet_kill(&card->rxram_full_tl);
netif_poll_disable(netdev);
netif_carrier_off(netdev);
netif_stop_queue(netdev);
del_timer_sync(&card->tx_timer);
/* disable/mask all interrupts */
spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
/* free_irq(netdev->irq, netdev);*/
free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev);
spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
SPIDER_NET_DMA_TX_FEND_VALUE);
/* turn off DMA, force end */
spider_net_disable_rxdmac(card);
/* release chains */
spider_net_release_tx_chain(card, 1);
spider_net_free_chain(card, &card->tx_chain);
spider_net_free_chain(card, &card->rx_chain);
return 0;
}
/**
* spider_net_get_next_tx_descr - returns the next available tx descriptor
* @card: device structure to get descriptor from
*
* returns the address of the next descriptor, or NULL if not available.
*/
static struct spider_net_descr *
spider_net_get_next_tx_descr(struct spider_net_card *card)
{
/* check, if head points to not-in-use descr */
if ( spider_net_get_descr_status(card->tx_chain.head) ==
SPIDER_NET_DESCR_NOT_IN_USE ) {
return card->tx_chain.head;
} else {
return NULL;
}
}
/**
* spider_net_set_txdescr_cmdstat - sets the tx descriptor command field
* @descr: descriptor structure to fill out
* @skb: packet to consider
*
* fills out the command and status field of the descriptor structure,
* depending on hardware checksum settings.
*/
static void
spider_net_set_txdescr_cmdstat(struct spider_net_descr *descr,
struct sk_buff *skb)
{
/* make sure the other fields in the descriptor are written */
wmb();
if (skb->ip_summed != CHECKSUM_HW) {
descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS;
return;
}
/* is packet ip?
* if yes: tcp? udp? */
if (skb->protocol == htons(ETH_P_IP)) {
if (skb->nh.iph->protocol == IPPROTO_TCP)
descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_TCPCS;
else if (skb->nh.iph->protocol == IPPROTO_UDP)
descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_UDPCS;
else /* the stack should checksum non-tcp and non-udp
packets on his own: NETIF_F_IP_CSUM */
descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS;
}
}
/**
* spider_net_prepare_tx_descr - fill tx descriptor with skb data
* @card: card structure
@ -864,13 +641,12 @@ spider_net_set_txdescr_cmdstat(struct spider_net_descr *descr,
*/
static int
spider_net_prepare_tx_descr(struct spider_net_card *card,
struct spider_net_descr *descr,
struct sk_buff *skb)
{
struct spider_net_descr *descr = card->tx_chain.head;
dma_addr_t buf;
buf = pci_map_single(card->pdev, skb->data,
skb->len, PCI_DMA_BIDIRECTIONAL);
buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
if (buf == DMA_ERROR_CODE) {
if (netif_msg_tx_err(card) && net_ratelimit())
pr_err("could not iommu-map packet (%p, %i). "
@ -880,10 +656,101 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
descr->buf_addr = buf;
descr->buf_size = skb->len;
descr->next_descr_addr = 0;
descr->skb = skb;
descr->data_status = 0;
spider_net_set_txdescr_cmdstat(descr,skb);
descr->dmac_cmd_status =
SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS;
if (skb->protocol == htons(ETH_P_IP))
switch (skb->nh.iph->protocol) {
case IPPROTO_TCP:
descr->dmac_cmd_status |= SPIDER_NET_DMAC_TCP;
break;
case IPPROTO_UDP:
descr->dmac_cmd_status |= SPIDER_NET_DMAC_UDP;
break;
}
descr->prev->next_descr_addr = descr->bus_addr;
return 0;
}
/**
* spider_net_release_tx_descr - processes a used tx descriptor
* @card: card structure
* @descr: descriptor to release
*
* releases a used tx descriptor (unmapping, freeing of skb)
*/
static inline void
spider_net_release_tx_descr(struct spider_net_card *card)
{
struct spider_net_descr *descr = card->tx_chain.tail;
struct sk_buff *skb;
card->tx_chain.tail = card->tx_chain.tail->next;
descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE;
/* unmap the skb */
skb = descr->skb;
pci_unmap_single(card->pdev, descr->buf_addr, skb->len,
PCI_DMA_TODEVICE);
dev_kfree_skb_any(skb);
}
/**
* spider_net_release_tx_chain - processes sent tx descriptors
* @card: adapter structure
* @brutal: if set, don't care about whether descriptor seems to be in use
*
* returns 0 if the tx ring is empty, otherwise 1.
*
* spider_net_release_tx_chain releases the tx descriptors that spider has
* finished with (if non-brutal) or simply release tx descriptors (if brutal).
* If some other context is calling this function, we return 1 so that we're
* scheduled again (if we were scheduled) and will not loose initiative.
*/
static int
spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
{
struct spider_net_descr_chain *chain = &card->tx_chain;
int status;
spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR);
while (chain->tail != chain->head) {
status = spider_net_get_descr_status(chain->tail);
switch (status) {
case SPIDER_NET_DESCR_COMPLETE:
card->netdev_stats.tx_packets++;
card->netdev_stats.tx_bytes += chain->tail->skb->len;
break;
case SPIDER_NET_DESCR_CARDOWNED:
if (!brutal)
return 1;
/* fallthrough, if we release the descriptors
* brutally (then we don't care about
* SPIDER_NET_DESCR_CARDOWNED) */
case SPIDER_NET_DESCR_RESPONSE_ERROR:
case SPIDER_NET_DESCR_PROTECTION_ERROR:
case SPIDER_NET_DESCR_FORCE_END:
if (netif_msg_tx_err(card))
pr_err("%s: forcing end of tx descriptor "
"with status x%02x\n",
card->netdev->name, status);
card->netdev_stats.tx_errors++;
break;
default:
card->netdev_stats.tx_dropped++;
return 1;
}
spider_net_release_tx_descr(card);
}
return 0;
}
@ -896,18 +763,32 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
* spider_net_kick_tx_dma writes the current tx chain head as start address
* of the tx descriptor chain and enables the transmission DMA engine
*/
static void
spider_net_kick_tx_dma(struct spider_net_card *card,
struct spider_net_descr *descr)
static inline void
spider_net_kick_tx_dma(struct spider_net_card *card)
{
/* this is the only descriptor in the output chain.
* Enable TX DMA */
struct spider_net_descr *descr;
spider_net_write_reg(card, SPIDER_NET_GDTDCHA,
descr->bus_addr);
if (spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR) &
SPIDER_NET_TX_DMA_EN)
goto out;
spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
SPIDER_NET_DMA_TX_VALUE);
descr = card->tx_chain.tail;
for (;;) {
if (spider_net_get_descr_status(descr) ==
SPIDER_NET_DESCR_CARDOWNED) {
spider_net_write_reg(card, SPIDER_NET_GDTDCHA,
descr->bus_addr);
spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
SPIDER_NET_DMA_TX_VALUE);
break;
}
if (descr == card->tx_chain.head)
break;
descr = descr->next;
}
out:
mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER);
}
/**
@ -915,47 +796,69 @@ spider_net_kick_tx_dma(struct spider_net_card *card,
* @skb: packet to send out
* @netdev: interface device structure
*
* returns 0 on success, <0 on failure
* returns 0 on success, !0 on failure
*/
static int
spider_net_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct spider_net_card *card = netdev_priv(netdev);
struct spider_net_descr *descr;
struct spider_net_descr_chain *chain = &card->tx_chain;
struct spider_net_descr *descr = chain->head;
unsigned long flags;
int result;
spin_lock_irqsave(&chain->lock, flags);
spider_net_release_tx_chain(card, 0);
descr = spider_net_get_next_tx_descr(card);
if (!descr)
goto error;
result = spider_net_prepare_tx_descr(card, descr, skb);
if (result)
goto error;
card->tx_chain.head = card->tx_chain.head->next;
if (spider_net_get_descr_status(descr->prev) !=
SPIDER_NET_DESCR_CARDOWNED) {
/* make sure the current descriptor is in memory. Then
* kicking it on again makes sense, if the previous is not
* card-owned anymore. Check the previous descriptor twice
* to omit an mb() in heavy traffic cases */
mb();
if (spider_net_get_descr_status(descr->prev) !=
SPIDER_NET_DESCR_CARDOWNED)
spider_net_kick_tx_dma(card, descr);
if (chain->head->next == chain->tail->prev) {
card->netdev_stats.tx_dropped++;
result = NETDEV_TX_LOCKED;
goto out;
}
mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER);
if (spider_net_get_descr_status(descr) != SPIDER_NET_DESCR_NOT_IN_USE) {
result = NETDEV_TX_LOCKED;
goto out;
}
return NETDEV_TX_OK;
if (spider_net_prepare_tx_descr(card, skb) != 0) {
card->netdev_stats.tx_dropped++;
result = NETDEV_TX_BUSY;
goto out;
}
error:
card->netdev_stats.tx_dropped++;
return NETDEV_TX_BUSY;
result = NETDEV_TX_OK;
spider_net_kick_tx_dma(card);
card->tx_chain.head = card->tx_chain.head->next;
out:
spin_unlock_irqrestore(&chain->lock, flags);
netif_wake_queue(netdev);
return result;
}
/**
* spider_net_cleanup_tx_ring - cleans up the TX ring
* @card: card structure
*
* spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use
* interrupts to cleanup our TX ring) and returns sent packets to the stack
* by freeing them
*/
static void
spider_net_cleanup_tx_ring(struct spider_net_card *card)
{
unsigned long flags;
spin_lock_irqsave(&card->tx_chain.lock, flags);
if ((spider_net_release_tx_chain(card, 0) != 0) &&
(card->netdev->flags & IFF_UP))
spider_net_kick_tx_dma(card);
spin_unlock_irqrestore(&card->tx_chain.lock, flags);
}
/**
@ -1002,7 +905,7 @@ spider_net_pass_skb_up(struct spider_net_descr *descr,
/* unmap descriptor */
pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME,
PCI_DMA_BIDIRECTIONAL);
PCI_DMA_FROMDEVICE);
/* the cases we'll throw away the packet immediately */
if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) {
@ -1067,14 +970,11 @@ spider_net_pass_skb_up(struct spider_net_descr *descr,
static int
spider_net_decode_one_descr(struct spider_net_card *card, int napi)
{
enum spider_net_descr_status status;
struct spider_net_descr *descr;
struct spider_net_descr_chain *chain;
struct spider_net_descr_chain *chain = &card->rx_chain;
struct spider_net_descr *descr = chain->tail;
int status;
int result;
chain = &card->rx_chain;
descr = chain->tail;
status = spider_net_get_descr_status(descr);
if (status == SPIDER_NET_DESCR_CARDOWNED) {
@ -1103,7 +1003,7 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi)
card->netdev->name, status);
card->netdev_stats.rx_dropped++;
pci_unmap_single(card->pdev, descr->buf_addr,
SPIDER_NET_MAX_FRAME, PCI_DMA_BIDIRECTIONAL);
SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE);
dev_kfree_skb_irq(descr->skb);
goto refill;
}
@ -1119,7 +1019,7 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi)
/* ok, we've got a packet in descr */
result = spider_net_pass_skb_up(descr, card, napi);
refill:
spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE);
descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE;
/* change the descriptor state: */
if (!napi)
spider_net_refill_rx_chain(card);
@ -1290,21 +1190,6 @@ spider_net_set_mac(struct net_device *netdev, void *p)
return 0;
}
/**
* spider_net_enable_txdmac - enables a TX DMA controller
* @card: card structure
*
* spider_net_enable_txdmac enables the TX DMA controller by setting the
* descriptor chain tail address
*/
static void
spider_net_enable_txdmac(struct spider_net_card *card)
{
/* assume chain is aligned correctly */
spider_net_write_reg(card, SPIDER_NET_GDTDCHA,
card->tx_chain.tail->bus_addr);
}
/**
* spider_net_handle_rxram_full - cleans up RX ring upon RX RAM full interrupt
* @card: card structure
@ -1653,7 +1538,6 @@ spider_net_enable_card(struct spider_net_card *card)
{ SPIDER_NET_GMRWOLCTRL, 0 },
{ SPIDER_NET_GTESTMD, 0x10000000 },
{ SPIDER_NET_GTTQMSK, 0x00400040 },
{ SPIDER_NET_GTESTMD, 0 },
{ SPIDER_NET_GMACINTEN, 0 },
@ -1692,9 +1576,6 @@ spider_net_enable_card(struct spider_net_card *card)
spider_net_write_reg(card, SPIDER_NET_GRXDMAEN, SPIDER_NET_WOL_VALUE);
/* set chain tail adress for TX chain */
spider_net_enable_txdmac(card);
spider_net_write_reg(card, SPIDER_NET_GMACLENLMT,
SPIDER_NET_LENLMT_VALUE);
spider_net_write_reg(card, SPIDER_NET_GMACMODE,
@ -1709,6 +1590,9 @@ spider_net_enable_card(struct spider_net_card *card)
SPIDER_NET_INT1_MASK_VALUE);
spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK,
SPIDER_NET_INT2_MASK_VALUE);
spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
SPIDER_NET_GDTDCEIDIS);
}
/**
@ -1728,10 +1612,12 @@ spider_net_open(struct net_device *netdev)
result = -ENOMEM;
if (spider_net_init_chain(card, &card->tx_chain,
card->descr, tx_descriptors))
card->descr,
PCI_DMA_TODEVICE, tx_descriptors))
goto alloc_tx_failed;
if (spider_net_init_chain(card, &card->rx_chain,
card->descr + tx_descriptors, rx_descriptors))
card->descr + tx_descriptors,
PCI_DMA_FROMDEVICE, rx_descriptors))
goto alloc_rx_failed;
/* allocate rx skbs */
@ -1938,7 +1824,7 @@ spider_net_workaround_rxramfull(struct spider_net_card *card)
/* empty sequencer data */
for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS;
sequencer++) {
spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT +
spider_net_write_reg(card, SPIDER_NET_GSnPRGADR +
sequencer * 8, 0x0);
for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) {
spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT +
@ -1954,6 +1840,49 @@ spider_net_workaround_rxramfull(struct spider_net_card *card)
SPIDER_NET_CKRCTRL_STOP_VALUE);
}
/**
* spider_net_stop - called upon ifconfig down
* @netdev: interface device structure
*
* always returns 0
*/
int
spider_net_stop(struct net_device *netdev)
{
struct spider_net_card *card = netdev_priv(netdev);
tasklet_kill(&card->rxram_full_tl);
netif_poll_disable(netdev);
netif_carrier_off(netdev);
netif_stop_queue(netdev);
del_timer_sync(&card->tx_timer);
/* disable/mask all interrupts */
spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
/* free_irq(netdev->irq, netdev);*/
free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev);
spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
SPIDER_NET_DMA_TX_FEND_VALUE);
/* turn off DMA, force end */
spider_net_disable_rxdmac(card);
/* release chains */
if (spin_trylock(&card->tx_chain.lock)) {
spider_net_release_tx_chain(card, 1);
spin_unlock(&card->tx_chain.lock);
}
spider_net_free_chain(card, &card->tx_chain);
spider_net_free_chain(card, &card->rx_chain);
return 0;
}
/**
* spider_net_tx_timeout_task - task scheduled by the watchdog timeout
* function (to be called not under interrupt status)
@ -1982,7 +1911,7 @@ spider_net_tx_timeout_task(void *data)
goto out;
spider_net_open(netdev);
spider_net_kick_tx_dma(card, card->tx_chain.head);
spider_net_kick_tx_dma(card);
netif_device_attach(netdev);
out:
@ -2065,7 +1994,6 @@ spider_net_setup_netdev(struct spider_net_card *card)
pci_set_drvdata(card->pdev, netdev);
atomic_set(&card->tx_chain_release,0);
card->rxram_full_tl.data = (unsigned long) card;
card->rxram_full_tl.func =
(void (*)(unsigned long)) spider_net_handle_rxram_full;
@ -2079,7 +2007,7 @@ spider_net_setup_netdev(struct spider_net_card *card)
spider_net_setup_netdev_ops(netdev);
netdev->features = NETIF_F_HW_CSUM;
netdev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX;
/* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
* NETIF_F_HW_VLAN_FILTER */

View File

@ -208,7 +208,10 @@ extern char spider_net_driver_name[];
#define SPIDER_NET_DMA_RX_VALUE 0x80000000
#define SPIDER_NET_DMA_RX_FEND_VALUE 0x00030003
/* to set TX_DMA_EN */
#define SPIDER_NET_DMA_TX_VALUE 0x80000000
#define SPIDER_NET_TX_DMA_EN 0x80000000
#define SPIDER_NET_GDTDCEIDIS 0x00000002
#define SPIDER_NET_DMA_TX_VALUE SPIDER_NET_TX_DMA_EN | \
SPIDER_NET_GDTDCEIDIS
#define SPIDER_NET_DMA_TX_FEND_VALUE 0x00030003
/* SPIDER_NET_UA_DESCR_VALUE is OR'ed with the unicast address */
@ -329,55 +332,23 @@ enum spider_net_int2_status {
(~SPIDER_NET_TXINT) & \
(~SPIDER_NET_RXINT) )
#define SPIDER_NET_GPREXEC 0x80000000
#define SPIDER_NET_GPRDAT_MASK 0x0000ffff
#define SPIDER_NET_GPREXEC 0x80000000
#define SPIDER_NET_GPRDAT_MASK 0x0000ffff
/* descriptor bits
*
* 1010 descriptor ready
* 0 descr in middle of chain
* 000 fixed to 0
*
* 0 no interrupt on completion
* 000 fixed to 0
* 1 no ipsec processing
* 1 last descriptor for this frame
* 00 no checksum
* 10 tcp checksum
* 11 udp checksum
*
* 00 fixed to 0
* 0 fixed to 0
* 0 no interrupt on response errors
* 0 no interrupt on invalid descr
* 0 no interrupt on dma process termination
* 0 no interrupt on descr chain end
* 0 no interrupt on descr complete
*
* 000 fixed to 0
* 0 response error interrupt status
* 0 invalid descr status
* 0 dma termination status
* 0 descr chain end status
* 0 descr complete status */
#define SPIDER_NET_DMAC_CMDSTAT_NOCS 0xa00c0000
#define SPIDER_NET_DMAC_CMDSTAT_TCPCS 0xa00e0000
#define SPIDER_NET_DMAC_CMDSTAT_UDPCS 0xa00f0000
#define SPIDER_NET_DESCR_IND_PROC_SHIFT 28
#define SPIDER_NET_DESCR_IND_PROC_MASKO 0x0fffffff
#define SPIDER_NET_DMAC_NOINTR_COMPLETE 0x00800000
#define SPIDER_NET_DMAC_NOCS 0x00040000
#define SPIDER_NET_DMAC_TCP 0x00020000
#define SPIDER_NET_DMAC_UDP 0x00030000
#define SPIDER_NET_TXDCEST 0x08000000
/* descr ready, descr is in middle of chain, get interrupt on completion */
#define SPIDER_NET_DMAC_RX_CARDOWNED 0xa0800000
enum spider_net_descr_status {
SPIDER_NET_DESCR_COMPLETE = 0x00, /* used in rx and tx */
SPIDER_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */
SPIDER_NET_DESCR_PROTECTION_ERROR = 0x02, /* used in rx and tx */
SPIDER_NET_DESCR_FRAME_END = 0x04, /* used in rx */
SPIDER_NET_DESCR_FORCE_END = 0x05, /* used in rx and tx */
SPIDER_NET_DESCR_CARDOWNED = 0x0a, /* used in rx and tx */
SPIDER_NET_DESCR_NOT_IN_USE /* any other value */
};
#define SPIDER_NET_DESCR_IND_PROC_MASK 0xF0000000
#define SPIDER_NET_DESCR_COMPLETE 0x00000000 /* used in rx and tx */
#define SPIDER_NET_DESCR_RESPONSE_ERROR 0x10000000 /* used in rx and tx */
#define SPIDER_NET_DESCR_PROTECTION_ERROR 0x20000000 /* used in rx and tx */
#define SPIDER_NET_DESCR_FRAME_END 0x40000000 /* used in rx */
#define SPIDER_NET_DESCR_FORCE_END 0x50000000 /* used in rx and tx */
#define SPIDER_NET_DESCR_CARDOWNED 0xA0000000 /* used in rx and tx */
#define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000
struct spider_net_descr {
/* as defined by the hardware */
@ -398,7 +369,7 @@ struct spider_net_descr {
} __attribute__((aligned(32)));
struct spider_net_descr_chain {
/* we walk from tail to head */
spinlock_t lock;
struct spider_net_descr *head;
struct spider_net_descr *tail;
};
@ -453,8 +424,6 @@ struct spider_net_card {
struct spider_net_descr_chain tx_chain;
struct spider_net_descr_chain rx_chain;
atomic_t rx_chain_refill;
atomic_t tx_chain_release;
struct net_device_stats netdev_stats;

View File

@ -3255,12 +3255,7 @@ static void __devexit happy_meal_pci_remove(struct pci_dev *pdev)
}
static struct pci_device_id happymeal_pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_SUN,
.device = PCI_DEVICE_ID_SUN_HAPPYMEAL,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ PCI_DEVICE(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_HAPPYMEAL) },
{ } /* Terminating entry */
};
@ -3275,7 +3270,7 @@ static struct pci_driver hme_pci_driver = {
static int __init happy_meal_pci_init(void)
{
return pci_module_init(&hme_pci_driver);
return pci_register_driver(&hme_pci_driver);
}
static void happy_meal_pci_exit(void)

View File

@ -197,7 +197,6 @@ static int c101_open(struct net_device *dev)
sca_out(IE0_TXINT, MSCI0_OFFSET + IE0, port);
set_carrier(port);
printk(KERN_DEBUG "0x%X\n", sca_in(MSCI1_OFFSET + ST3, port));
/* enable MSCI1 CDCD interrupt */
sca_out(IE1_CDCD, MSCI1_OFFSET + IE1, port);
@ -449,4 +448,5 @@ module_exit(c101_cleanup);
MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
MODULE_DESCRIPTION("Moxa C101 serial port driver");
MODULE_LICENSE("GPL v2");
module_param(hw, charp, 0444); /* hw=irq,ram:irq,... */
module_param(hw, charp, 0444);
MODULE_PARM_DESC(hw, "irq,ram:irq,...");

View File

@ -107,6 +107,7 @@ int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
dev->hard_header = NULL;
dev->type = ARPHRD_PPP;
dev->addr_len = 0;
netif_dormant_off(dev);
return 0;
}

View File

@ -82,6 +82,7 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr)
dev->type = ARPHRD_RAWHDLC;
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
dev->addr_len = 0;
netif_dormant_off(dev);
return 0;
}

View File

@ -100,6 +100,7 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
dev->tx_queue_len = old_qlen;
memcpy(dev->dev_addr, "\x00\x01", 2);
get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2);
netif_dormant_off(dev);
return 0;
}

View File

@ -212,6 +212,7 @@ int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr)
dev->hard_header = NULL;
dev->type = ARPHRD_X25;
dev->addr_len = 0;
netif_dormant_off(dev);
return 0;
}

View File

@ -564,4 +564,5 @@ module_exit(n2_cleanup);
MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
MODULE_DESCRIPTION("RISCom/N2 serial port driver");
MODULE_LICENSE("GPL v2");
module_param(hw, charp, 0444); /* hw=io,irq,ram,ports:io,irq,... */
module_param(hw, charp, 0444);
MODULE_PARM_DESC(hw, "io,irq,ram,ports:io,irq,...");

View File

@ -304,6 +304,7 @@ static int __init xpram_setup_sizes(unsigned long pages)
{
unsigned long mem_needed;
unsigned long mem_auto;
unsigned long long size;
int mem_auto_no;
int i;
@ -321,9 +322,19 @@ static int __init xpram_setup_sizes(unsigned long pages)
mem_needed = 0;
mem_auto_no = 0;
for (i = 0; i < xpram_devs; i++) {
if (sizes[i])
xpram_sizes[i] =
(memparse(sizes[i], &sizes[i]) + 3) & -4UL;
if (sizes[i]) {
size = simple_strtoull(sizes[i], &sizes[i], 0);
switch (sizes[i][0]) {
case 'g':
case 'G':
size <<= 20;
break;
case 'm':
case 'M':
size <<= 10;
}
xpram_sizes[i] = (size + 3) & -4UL;
}
if (xpram_sizes[i])
mem_needed += xpram_sizes[i];
else

View File

@ -1106,10 +1106,10 @@ raw3270_delete_device(struct raw3270 *rp)
/* Remove from device chain. */
mutex_lock(&raw3270_mutex);
if (rp->clttydev)
if (rp->clttydev && !IS_ERR(rp->clttydev))
class_device_destroy(class3270,
MKDEV(IBM_TTY3270_MAJOR, rp->minor));
if (rp->cltubdev)
if (rp->cltubdev && !IS_ERR(rp->cltubdev))
class_device_destroy(class3270,
MKDEV(IBM_FS3270_MAJOR, rp->minor));
list_del_init(&rp->list);
@ -1173,21 +1173,37 @@ static struct attribute_group raw3270_attr_group = {
.attrs = raw3270_attrs,
};
static void
raw3270_create_attributes(struct raw3270 *rp)
static int raw3270_create_attributes(struct raw3270 *rp)
{
//FIXME: check return code
sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
rp->clttydev =
class_device_create(class3270, NULL,
MKDEV(IBM_TTY3270_MAJOR, rp->minor),
&rp->cdev->dev, "tty%s",
rp->cdev->dev.bus_id);
rp->cltubdev =
class_device_create(class3270, NULL,
MKDEV(IBM_FS3270_MAJOR, rp->minor),
&rp->cdev->dev, "tub%s",
rp->cdev->dev.bus_id);
int rc;
rc = sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
if (rc)
goto out;
rp->clttydev = class_device_create(class3270, NULL,
MKDEV(IBM_TTY3270_MAJOR, rp->minor),
&rp->cdev->dev, "tty%s",
rp->cdev->dev.bus_id);
if (IS_ERR(rp->clttydev)) {
rc = PTR_ERR(rp->clttydev);
goto out_ttydev;
}
rp->cltubdev = class_device_create(class3270, NULL,
MKDEV(IBM_FS3270_MAJOR, rp->minor),
&rp->cdev->dev, "tub%s",
rp->cdev->dev.bus_id);
if (!IS_ERR(rp->cltubdev))
goto out;
rc = PTR_ERR(rp->cltubdev);
class_device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
out_ttydev:
sysfs_remove_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
out:
return rc;
}
/*
@ -1255,7 +1271,9 @@ raw3270_set_online (struct ccw_device *cdev)
rc = raw3270_reset_device(rp);
if (rc)
goto failure;
raw3270_create_attributes(rp);
rc = raw3270_create_attributes(rp);
if (rc)
goto failure;
set_bit(RAW3270_FLAGS_READY, &rp->flags);
mutex_lock(&raw3270_mutex);
list_for_each_entry(np, &raw3270_notifier, list)

View File

@ -76,14 +76,22 @@ struct tape_class_device *register_tape_dev(
device,
"%s", tcd->device_name
);
sysfs_create_link(
rc = PTR_ERR(tcd->class_device);
if (rc)
goto fail_with_cdev;
rc = sysfs_create_link(
&device->kobj,
&tcd->class_device->kobj,
tcd->mode_name
);
if (rc)
goto fail_with_class_device;
return tcd;
fail_with_class_device:
class_device_destroy(tape_class, tcd->char_device->dev);
fail_with_cdev:
cdev_del(tcd->char_device);

View File

@ -543,20 +543,24 @@ int
tape_generic_probe(struct ccw_device *cdev)
{
struct tape_device *device;
int ret;
device = tape_alloc_device();
if (IS_ERR(device))
return -ENODEV;
PRINT_INFO("tape device %s found\n", cdev->dev.bus_id);
ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
if (ret) {
tape_put_device(device);
PRINT_ERR("probe failed for tape device %s\n", cdev->dev.bus_id);
return ret;
}
cdev->dev.driver_data = device;
cdev->handler = __tape_do_irq;
device->cdev = cdev;
device->cdev_id = busid_to_int(cdev->dev.bus_id);
cdev->handler = __tape_do_irq;
ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
return 0;
PRINT_INFO("tape device %s found\n", cdev->dev.bus_id);
return ret;
}
static inline void

View File

@ -1068,6 +1068,7 @@ cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr,
if (count) {
interval = cmb_data->last_update -
cdev->private->cmb_start_time;
interval = (interval * 1000) >> 12;
interval /= count;
} else
interval = -1;

View File

@ -2686,9 +2686,17 @@ static struct attribute_group ctc_attr_group = {
static int
ctc_add_attributes(struct device *dev)
{
device_create_file(dev, &dev_attr_loglevel);
device_create_file(dev, &dev_attr_stats);
return 0;
int rc;
rc = device_create_file(dev, &dev_attr_loglevel);
if (rc)
goto out;
rc = device_create_file(dev, &dev_attr_stats);
if (!rc)
goto out;
device_remove_file(dev, &dev_attr_loglevel);
out:
return rc;
}
static void
@ -2901,7 +2909,12 @@ ctc_new_device(struct ccwgroup_device *cgdev)
goto out;
}
ctc_add_attributes(&cgdev->dev);
if (ctc_add_attributes(&cgdev->dev)) {
ctc_netdev_unregister(dev);
dev->priv = NULL;
ctc_free_netdevice(dev, 1);
goto out;
}
strlcpy(privptr->fsm->name, dev->name, sizeof (privptr->fsm->name));

View File

@ -8451,10 +8451,11 @@ __qeth_reboot_event_card(struct device *dev, void *data)
static int
qeth_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
{
int ret;
driver_for_each_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
__qeth_reboot_event_card);
return NOTIFY_DONE;
ret = driver_for_each_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
__qeth_reboot_event_card);
return ret ? NOTIFY_BAD : NOTIFY_DONE;
}

View File

@ -233,7 +233,7 @@ static void __init build_one_sbus(struct device_node *dp, int num_sbus)
sbus->ofdev.node = dp;
sbus->ofdev.dev.parent = NULL;
sbus->ofdev.dev.bus = &sbus_bus_type;
strcpy(sbus->ofdev.dev.bus_id, dp->path_component_name);
sprintf(sbus->ofdev.dev.bus_id, "sbus%d", num_sbus);
if (of_device_register(&sbus->ofdev) != 0)
printk(KERN_DEBUG "sbus: device registration error for %s!\n",

View File

@ -3451,12 +3451,12 @@ create_cmd (Scsi_Cmnd *cmd) {
for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4,
cmd_dataout += 4, ++i) {
u32 vbuf = cmd->use_sg
? (u32)page_address(((struct scatterlist *)cmd->buffer)[i].page)+
((struct scatterlist *)cmd->buffer)[i].offset
? (u32)page_address(((struct scatterlist *)cmd->request_buffer)[i].page)+
((struct scatterlist *)cmd->request_buffer)[i].offset
: (u32)(cmd->request_buffer);
u32 bbuf = virt_to_bus((void *)vbuf);
u32 count = cmd->use_sg ?
((struct scatterlist *)cmd->buffer)[i].length :
((struct scatterlist *)cmd->request_buffer)[i].length :
cmd->request_bufflen;
/*
@ -5417,7 +5417,7 @@ insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
if ((buffers = cmd->use_sg)) {
for (offset = 0,
segment = (struct scatterlist *) cmd->buffer;
segment = (struct scatterlist *) cmd->request_buffer;
buffers && !((found = ((ptr >= (char *)page_address(segment->page)+segment->offset) &&
(ptr < ((char *)page_address(segment->page)+segment->offset+segment->length)))));
--buffers, offset += segment->length, ++segment)

View File

@ -911,7 +911,7 @@ static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp)
sp->SCp.ptr =
(char *) virt_to_phys(sp->request_buffer);
} else {
sp->SCp.buffer = (struct scatterlist *) sp->buffer;
sp->SCp.buffer = (struct scatterlist *) sp->request_buffer;
sp->SCp.buffers_residual = sp->use_sg - 1;
sp->SCp.this_residual = sp->SCp.buffer->length;
if (esp->dma_mmu_get_scsi_sgl)

View File

@ -114,7 +114,7 @@ MODULE_DESCRIPTION("NCR Dual700 SCSI Driver");
MODULE_LICENSE("GPL");
module_param(NCR_D700, charp, 0);
static __u8 __initdata id_array[2*(MCA_MAX_SLOT_NR + 1)] =
static __u8 __devinitdata id_array[2*(MCA_MAX_SLOT_NR + 1)] =
{ [0 ... 2*(MCA_MAX_SLOT_NR + 1)-1] = 7 };
#ifdef MODULE
@ -173,7 +173,7 @@ struct NCR_D700_private {
char pad;
};
static int
static int __devinit
NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq,
int slot, u32 region, int differential)
{
@ -243,7 +243,7 @@ NCR_D700_intr(int irq, void *data, struct pt_regs *regs)
* essentially connectecd to the MCA bus independently, it is easier
* to set them up as two separate host adapters, rather than one
* adapter with two channels */
static int
static int __devinit
NCR_D700_probe(struct device *dev)
{
struct NCR_D700_private *p;
@ -329,7 +329,7 @@ NCR_D700_probe(struct device *dev)
for (i = 0; i < 2; i++) {
int err;
if ((err = NCR_D700_probe_one(p, i, slot, irq,
if ((err = NCR_D700_probe_one(p, i, irq, slot,
offset_addr + (0x80 * i),
differential)) != 0)
printk("D700: SIOP%d: probe failed, error = %d\n",
@ -349,7 +349,7 @@ NCR_D700_probe(struct device *dev)
return 0;
}
static void
static void __devexit
NCR_D700_remove_one(struct Scsi_Host *host)
{
scsi_remove_host(host);
@ -359,7 +359,7 @@ NCR_D700_remove_one(struct Scsi_Host *host)
release_region(host->base, 64);
}
static int
static int __devexit
NCR_D700_remove(struct device *dev)
{
struct NCR_D700_private *p = dev_get_drvdata(dev);
@ -380,7 +380,7 @@ static struct mca_driver NCR_D700_driver = {
.name = "NCR_D700",
.bus = &mca_bus_type,
.probe = NCR_D700_probe,
.remove = NCR_D700_remove,
.remove = __devexit_p(NCR_D700_remove),
},
};

View File

@ -551,6 +551,11 @@ struct aha152x_hostdata {
struct aha152x_scdata {
Scsi_Cmnd *next; /* next sc in queue */
struct semaphore *sem; /* semaphore to block on */
unsigned char cmd_len;
unsigned char cmnd[MAX_COMMAND_SIZE];
unsigned short use_sg;
unsigned request_bufflen;
void *request_buffer;
};
@ -1006,11 +1011,20 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int p
return FAILED;
}
} else {
struct aha152x_scdata *sc;
SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC);
if(SCpnt->host_scribble==0) {
printk(ERR_LEAD "allocation failed\n", CMDINFO(SCpnt));
return FAILED;
}
sc = SCDATA(SCpnt);
memcpy(sc->cmnd, SCpnt->cmnd, sizeof(sc->cmnd));
sc->request_buffer = SCpnt->request_buffer;
sc->request_bufflen = SCpnt->request_bufflen;
sc->use_sg = SCpnt->use_sg;
sc->cmd_len = SCpnt->cmd_len;
}
SCNEXT(SCpnt) = NULL;
@ -1165,6 +1179,10 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
DECLARE_MUTEX_LOCKED(sem);
struct timer_list timer;
int ret, issued, disconnected;
unsigned char old_cmd_len = SCpnt->cmd_len;
unsigned short old_use_sg = SCpnt->use_sg;
void *old_buffer = SCpnt->request_buffer;
unsigned old_bufflen = SCpnt->request_bufflen;
unsigned long flags;
#if defined(AHA152X_DEBUG)
@ -1199,10 +1217,10 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
down(&sem);
del_timer(&timer);
SCpnt->cmd_len = SCpnt->old_cmd_len;
SCpnt->use_sg = SCpnt->old_use_sg;
SCpnt->request_buffer = SCpnt->buffer;
SCpnt->request_bufflen = SCpnt->bufflen;
SCpnt->cmd_len = old_cmd_len;
SCpnt->use_sg = old_use_sg;
SCpnt->request_buffer = old_buffer;
SCpnt->request_bufflen = old_bufflen;
DO_LOCK(flags);
@ -1565,6 +1583,9 @@ static void busfree_run(struct Scsi_Host *shpnt)
#endif
if(DONE_SC->SCp.phase & check_condition) {
struct scsi_cmnd *cmd = HOSTDATA(shpnt)->done_SC;
struct aha152x_scdata *sc = SCDATA(cmd);
#if 0
if(HOSTDATA(shpnt)->debug & debug_eh) {
printk(ERR_LEAD "received sense: ", CMDINFO(DONE_SC));
@ -1573,13 +1594,13 @@ static void busfree_run(struct Scsi_Host *shpnt)
#endif
/* restore old command */
memcpy((void *) DONE_SC->cmnd, (void *) DONE_SC->data_cmnd, sizeof(DONE_SC->data_cmnd));
DONE_SC->request_buffer = DONE_SC->buffer;
DONE_SC->request_bufflen = DONE_SC->bufflen;
DONE_SC->use_sg = DONE_SC->old_use_sg;
DONE_SC->cmd_len = DONE_SC->old_cmd_len;
memcpy(cmd->cmnd, sc->cmnd, sizeof(sc->cmnd));
cmd->request_buffer = sc->request_buffer;
cmd->request_bufflen = sc->request_bufflen;
cmd->use_sg = sc->use_sg;
cmd->cmd_len = sc->cmd_len;
DONE_SC->SCp.Status = 0x02;
cmd->SCp.Status = 0x02;
HOSTDATA(shpnt)->commands--;
if (!HOSTDATA(shpnt)->commands)

View File

@ -7289,7 +7289,7 @@ ahd_reset_cmds_pending(struct ahd_softc *ahd)
ahd->flags &= ~AHD_UPDATE_PEND_CMDS;
}
void
static void
ahd_done_with_status(struct ahd_softc *ahd, struct scb *scb, uint32_t status)
{
cam_status ostat;

View File

@ -242,25 +242,6 @@ ahd_print_path(struct ahd_softc *ahd, struct scb *scb)
*/
static uint32_t aic79xx_no_reset;
/*
* Certain PCI motherboards will scan PCI devices from highest to lowest,
* others scan from lowest to highest, and they tend to do all kinds of
* strange things when they come into contact with PCI bridge chips. The
* net result of all this is that the PCI card that is actually used to boot
* the machine is very hard to detect. Most motherboards go from lowest
* PCI slot number to highest, and the first SCSI controller found is the
* one you boot from. The only exceptions to this are when a controller
* has its BIOS disabled. So, we by default sort all of our SCSI controllers
* from lowest PCI slot number to highest PCI slot number. We also force
* all controllers with their BIOS disabled to the end of the list. This
* works on *almost* all computers. Where it doesn't work, we have this
* option. Setting this option to non-0 will reverse the order of the sort
* to highest first, then lowest, but will still leave cards with their BIOS
* disabled at the very end. That should fix everyone up unless there are
* really strange cirumstances.
*/
static uint32_t aic79xx_reverse_scan;
/*
* Should we force EXTENDED translation on a controller.
* 0 == Use whatever is in the SEEPROM or default to off
@ -350,7 +331,6 @@ MODULE_PARM_DESC(aic79xx,
" periodically to prevent tag starvation.\n"
" This may be required by some older disk\n"
" or drives/RAID arrays.\n"
" reverse_scan Sort PCI devices highest Bus/Slot to lowest\n"
" tag_info:<tag_str> Set per-target tag depth\n"
" global_tag_depth:<int> Global tag depth for all targets on all buses\n"
" slewrate:<slewrate_list>Set the signal slew rate (0-15).\n"
@ -1031,7 +1011,6 @@ aic79xx_setup(char *s)
#ifdef AHD_DEBUG
{ "debug", &ahd_debug },
#endif
{ "reverse_scan", &aic79xx_reverse_scan },
{ "periodic_otag", &aic79xx_periodic_otag },
{ "pci_parity", &aic79xx_pci_parity },
{ "seltime", &aic79xx_seltime },

View File

@ -353,7 +353,6 @@ MODULE_PARM_DESC(aic7xxx,
" periodically to prevent tag starvation.\n"
" This may be required by some older disk\n"
" drives or RAID arrays.\n"
" reverse_scan Sort PCI devices highest Bus/Slot to lowest\n"
" tag_info:<tag_str> Set per-target tag depth\n"
" global_tag_depth:<int> Global tag depth for every target\n"
" on every bus\n"

View File

@ -507,7 +507,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd *cmd)
*/
if (cmd->use_sg) {
cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
cmd->SCp.buffers_residual = cmd->use_sg - 1;
cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page)+
cmd->SCp.buffer->offset;

View File

@ -5,6 +5,7 @@
* Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002)
* by D. Gilbert and aeb (20020609)
* Additions for SPC-3 T10/1416-D Rev 21 22 Sept 2004, D. Gilbert 20041025
* Update to SPC-4 T10/1713-D Rev 5a, 14 June 2006, D. Gilbert 20060702
*/
#include <linux/blkdev.h>
@ -36,55 +37,56 @@ static const char * cdb_byte0_names[] = {
/* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense",
/* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL,
"Reasssign Blocks",
/* 08-0d */ "Read (6)", NULL, "Write (6)", "Seek (6)", NULL, NULL,
/* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL,
/* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry",
/* 13-16 */ "Verify (6)", "Recover Buffered Data", "Mode Select (6)",
"Reserve (6)",
/* 17-1a */ "Release (6)", "Copy", "Erase", "Mode Sense (6)",
/* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)",
"Reserve(6)",
/* 17-1a */ "Release(6)", "Copy", "Erase", "Mode Sense(6)",
/* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic",
/* 1e-1f */ "Prevent/Allow Medium Removal", NULL,
/* 20-22 */ NULL, NULL, NULL,
/* 23-28 */ "Read Format Capacities", "Set Window",
"Read Capacity (10)", NULL, NULL, "Read (10)",
/* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase (10)",
"Read Capacity(10)", NULL, NULL, "Read(10)",
/* 29-2d */ "Read Generation", "Write(10)", "Seek(10)", "Erase(10)",
"Read updated block",
/* 2e-31 */ "Write Verify (10)", "Verify (10)", "Search High", "Search Equal",
/* 2e-31 */ "Write Verify(10)", "Verify(10)", "Search High", "Search Equal",
/* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position",
/* 35-37 */ "Synchronize Cache (10)", "Lock/Unlock Cache (10)",
/* 35-37 */ "Synchronize Cache(10)", "Lock/Unlock Cache(10)",
"Read Defect Data(10)",
/* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer",
"Read Buffer",
/* 3d-3f */ "Update Block", "Read Long (10)", "Write Long (10)",
/* 40-41 */ "Change Definition", "Write Same (10)",
/* 3d-3f */ "Update Block", "Read Long(10)", "Write Long(10)",
/* 40-41 */ "Change Definition", "Write Same(10)",
/* 42-48 */ "Read sub-channel", "Read TOC/PMA/ATIP", "Read density support",
"Play audio (10)", "Get configuration", "Play audio msf",
"Play audio(10)", "Get configuration", "Play audio msf",
"Play audio track/index",
/* 49-4f */ "Play track relative (10)", "Get event status notification",
/* 49-4f */ "Play track relative(10)", "Get event status notification",
"Pause/resume", "Log Select", "Log Sense", "Stop play/scan",
NULL,
/* 50-55 */ "Xdwrite", "Xpwrite, Read disk info", "Xdread, Read track info",
"Reserve track", "Send OPC info", "Mode Select (10)",
/* 56-5b */ "Reserve (10)", "Release (10)", "Repair track", "Read master cue",
"Mode Sense (10)", "Close track/session",
"Reserve track", "Send OPC info", "Mode Select(10)",
/* 56-5b */ "Reserve(10)", "Release(10)", "Repair track", "Read master cue",
"Mode Sense(10)", "Close track/session",
/* 5c-5f */ "Read buffer capacity", "Send cue sheet", "Persistent reserve in",
"Persistent reserve out",
/* 60-67 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 68-6f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 70-77 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 78-7f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Variable length",
/* 80-84 */ "Xdwrite (16)", "Rebuild (16)", "Regenerate (16)", "Extended copy",
/* 80-84 */ "Xdwrite(16)", "Rebuild(16)", "Regenerate(16)", "Extended copy",
"Receive copy results",
/* 85-89 */ "Memory Export In (16)", "Access control in", "Access control out",
"Read (16)", "Memory Export Out (16)",
/* 8a-8f */ "Write (16)", NULL, "Read attributes", "Write attributes",
"Write and verify (16)", "Verify (16)",
/* 90-94 */ "Pre-fetch (16)", "Synchronize cache (16)",
"Lock/unlock cache (16)", "Write same (16)", NULL,
/* 85-89 */ "ATA command pass through(16)", "Access control in",
"Access control out", "Read(16)", "Memory Export Out(16)",
/* 8a-8f */ "Write(16)", NULL, "Read attributes", "Write attributes",
"Write and verify(16)", "Verify(16)",
/* 90-94 */ "Pre-fetch(16)", "Synchronize cache(16)",
"Lock/unlock cache(16)", "Write same(16)", NULL,
/* 95-99 */ NULL, NULL, NULL, NULL, NULL,
/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in (16)",
"Service action out (16)",
/* a0-a5 */ "Report luns", "Blank", "Send event", "Maintenance in",
"Maintenance out", "Move medium/play audio(12)",
/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in(16)",
"Service action out(16)",
/* a0-a5 */ "Report luns", "ATA command pass through(12)/Blank",
"Security protocol in", "Maintenance in", "Maintenance out",
"Move medium/play audio(12)",
/* a6-a9 */ "Exchange medium", "Move medium attached", "Read(12)",
"Play track relative(12)",
/* aa-ae */ "Write(12)", NULL, "Erase(12), Get Performance",
@ -92,12 +94,12 @@ static const char * cdb_byte0_names[] = {
/* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)",
/* b2-b4 */ "Search data low(12)", "Set limits(12)",
"Read element status attached",
/* b5-b6 */ "Request volume element address", "Send volume tag, set streaming",
/* b5-b6 */ "Security protocol out", "Send volume tag, set streaming",
/* b7-b9 */ "Read defect data(12)", "Read element status", "Read CD msf",
/* ba-bc */ "Redundancy group (in), Scan",
"Redundancy group (out), Set cd-rom speed", "Spare in, Play cd",
/* bd-bf */ "Spare out, Mechanism status", "Volume set in, Read cd",
"Volume set out, Send DVD structure",
"Redundancy group (out), Set cd-rom speed", "Spare (in), Play cd",
/* bd-bf */ "Spare (out), Mechanism status", "Volume set (in), Read cd",
"Volume set (out), Send DVD structure",
};
struct value_name_pair {
@ -112,6 +114,7 @@ static const struct value_name_pair maint_in_arr[] = {
{0xc, "Report supported operation codes"},
{0xd, "Report supported task management functions"},
{0xe, "Report priority"},
{0xf, "Report timestamp"},
};
#define MAINT_IN_SZ ARRAY_SIZE(maint_in_arr)
@ -120,6 +123,7 @@ static const struct value_name_pair maint_out_arr[] = {
{0xa, "Set target port groups"},
{0xb, "Change aliases"},
{0xe, "Set priority"},
{0xe, "Set timestamp"},
};
#define MAINT_OUT_SZ ARRAY_SIZE(maint_out_arr)
@ -427,6 +431,7 @@ static struct error_info additional[] =
{0x001A, "Rewind operation in progress"},
{0x001B, "Set capacity operation in progress"},
{0x001C, "Verify operation in progress"},
{0x001D, "ATA pass through information available"},
{0x0100, "No index/sector signal"},
@ -438,7 +443,7 @@ static struct error_info additional[] =
{0x0400, "Logical unit not ready, cause not reportable"},
{0x0401, "Logical unit is in process of becoming ready"},
{0x0402, "Logical unit not ready, initializing cmd. required"},
{0x0402, "Logical unit not ready, initializing command required"},
{0x0403, "Logical unit not ready, manual intervention required"},
{0x0404, "Logical unit not ready, format in progress"},
{0x0405, "Logical unit not ready, rebuild in progress"},
@ -478,6 +483,9 @@ static struct error_info additional[] =
{0x0B00, "Warning"},
{0x0B01, "Warning - specified temperature exceeded"},
{0x0B02, "Warning - enclosure degraded"},
{0x0B03, "Warning - background self-test failed"},
{0x0B04, "Warning - background pre-scan detected medium error"},
{0x0B05, "Warning - background medium scan detected medium error"},
{0x0C00, "Write error"},
{0x0C01, "Write error - recovered with auto reallocation"},
@ -493,6 +501,7 @@ static struct error_info additional[] =
{0x0C0B, "Auxiliary memory write error"},
{0x0C0C, "Write error - unexpected unsolicited data"},
{0x0C0D, "Write error - not enough unsolicited data"},
{0x0C0F, "Defects in error window"},
{0x0D00, "Error detected by third party temporary initiator"},
{0x0D01, "Third party device failure"},
@ -504,11 +513,12 @@ static struct error_info additional[] =
{0x0E00, "Invalid information unit"},
{0x0E01, "Information unit too short"},
{0x0E02, "Information unit too long"},
{0x0E03, "Invalid field in command information unit"},
{0x1000, "Id CRC or ECC error"},
{0x1001, "Data block guard check failed"},
{0x1002, "Data block application tag check failed"},
{0x1003, "Data block reference tag check failed"},
{0x1001, "Logical block guard check failed"},
{0x1002, "Logical block application tag check failed"},
{0x1003, "Logical block reference tag check failed"},
{0x1100, "Unrecovered read error"},
{0x1101, "Read retries exhausted"},
@ -530,6 +540,7 @@ static struct error_info additional[] =
{0x1111, "Read error - loss of streaming"},
{0x1112, "Auxiliary memory read error"},
{0x1113, "Read error - failed retransmission request"},
{0x1114, "Read error - lba marked bad by application client"},
{0x1200, "Address mark not found for id field"},
@ -610,11 +621,14 @@ static struct error_info additional[] =
{0x2100, "Logical block address out of range"},
{0x2101, "Invalid element address"},
{0x2102, "Invalid address for write"},
{0x2103, "Invalid write crossing layer jump"},
{0x2200, "Illegal function (use 20 00, 24 00, or 26 00)"},
{0x2400, "Invalid field in cdb"},
{0x2401, "CDB decryption error"},
{0x2402, "Obsolete"},
{0x2403, "Obsolete"},
{0x2404, "Security audit value frozen"},
{0x2405, "Security working key frozen"},
{0x2406, "Nonce not unique"},
@ -637,7 +651,10 @@ static struct error_info additional[] =
{0x260C, "Invalid operation for copy source or destination"},
{0x260D, "Copy segment granularity violation"},
{0x260E, "Invalid parameter while port is enabled"},
{0x260F, "Invalid data-out buffer integrity"},
{0x260F, "Invalid data-out buffer integrity check value"},
{0x2610, "Data decryption key fail limit reached"},
{0x2611, "Incomplete key-associated data set"},
{0x2612, "Vendor specific key reference not found"},
{0x2700, "Write protected"},
{0x2701, "Hardware write protected"},
@ -649,6 +666,7 @@ static struct error_info additional[] =
{0x2800, "Not ready to ready change, medium may have changed"},
{0x2801, "Import or export element accessed"},
{0x2802, "Format-layer may have changed"},
{0x2900, "Power on, reset, or bus device reset occurred"},
{0x2901, "Power on occurred"},
@ -669,6 +687,11 @@ static struct error_info additional[] =
{0x2A07, "Implicit asymmetric access state transition failed"},
{0x2A08, "Priority changed"},
{0x2A09, "Capacity data has changed"},
{0x2A10, "Timestamp changed"},
{0x2A11, "Data encryption parameters changed by another i_t nexus"},
{0x2A12, "Data encryption parameters changed by vendor specific "
"event"},
{0x2A13, "Data encryption key instance counter has changed"},
{0x2B00, "Copy cannot execute since host cannot disconnect"},
@ -690,6 +713,7 @@ static struct error_info additional[] =
{0x2E00, "Insufficient time for operation"},
{0x2F00, "Commands cleared by another initiator"},
{0x2F01, "Commands cleared by power loss notification"},
{0x3000, "Incompatible medium installed"},
{0x3001, "Cannot read medium - unknown format"},
@ -702,7 +726,8 @@ static struct error_info additional[] =
{0x3008, "Cannot write - application code mismatch"},
{0x3009, "Current session not fixated for append"},
{0x300A, "Cleaning request rejected"},
{0x300C, "WORM medium, overwrite attempted"},
{0x300C, "WORM medium - overwrite attempted"},
{0x300D, "WORM medium - integrity check"},
{0x3010, "Medium not formatted"},
{0x3100, "Medium format corrupted"},
@ -790,6 +815,9 @@ static struct error_info additional[] =
{0x3F0F, "Echo buffer overwritten"},
{0x3F10, "Medium loadable"},
{0x3F11, "Medium auxiliary memory accessible"},
{0x3F12, "iSCSI IP address added"},
{0x3F13, "iSCSI IP address removed"},
{0x3F14, "iSCSI IP address changed"},
/*
* {0x40NN, "Ram failure"},
* {0x40NN, "Diagnostic failure on component nn"},
@ -799,6 +827,7 @@ static struct error_info additional[] =
{0x4300, "Message error"},
{0x4400, "Internal target failure"},
{0x4471, "ATA device failed set features"},
{0x4500, "Select or reselect failure"},
@ -807,9 +836,10 @@ static struct error_info additional[] =
{0x4700, "Scsi parity error"},
{0x4701, "Data phase CRC error detected"},
{0x4702, "Scsi parity error detected during st data phase"},
{0x4703, "Information unit CRC error detected"},
{0x4703, "Information unit iuCRC error detected"},
{0x4704, "Asynchronous information protection error detected"},
{0x4705, "Protocol service CRC error"},
{0x4706, "Phy test function in progress"},
{0x477f, "Some commands cleared by iSCSI Protocol event"},
{0x4800, "Initiator detected error message received"},
@ -844,6 +874,8 @@ static struct error_info additional[] =
{0x5300, "Media load or eject failed"},
{0x5301, "Unload tape failure"},
{0x5302, "Medium removal prevented"},
{0x5303, "Medium removal prevented by data transfer element"},
{0x5304, "Medium thread or unthread failure"},
{0x5400, "Scsi to host system interface failure"},
@ -855,6 +887,7 @@ static struct error_info additional[] =
{0x5505, "Insufficient access control resources"},
{0x5506, "Auxiliary memory out of space"},
{0x5507, "Quota error"},
{0x5508, "Maximum number of supplemental decryption keys exceeded"},
{0x5700, "Unable to recover table-of-contents"},
@ -1004,6 +1037,7 @@ static struct error_info additional[] =
{0x6708, "Assign failure occurred"},
{0x6709, "Multiply assigned logical unit"},
{0x670A, "Set target port groups command failed"},
{0x670B, "ATA device feature not enabled"},
{0x6800, "Logical unit not configured"},
@ -1030,6 +1064,8 @@ static struct error_info additional[] =
{0x6F03, "Read of scrambled sector without authentication"},
{0x6F04, "Media region code is mismatched to logical unit region"},
{0x6F05, "Drive region must be permanent/region reset count error"},
{0x6F06, "Insufficient block count for binding nonce recording"},
{0x6F07, "Conflict in binding nonce recording"},
/*
* {0x70NN, "Decompression exception short algorithm id of nn"},
*/
@ -1041,6 +1077,8 @@ static struct error_info additional[] =
{0x7203, "Session fixation error - incomplete track in session"},
{0x7204, "Empty or partially written reserved track"},
{0x7205, "No more track reservations allowed"},
{0x7206, "RMZ extension is not allowed"},
{0x7207, "No more test zone extensions are allowed"},
{0x7300, "Cd control error"},
{0x7301, "Power calibration area almost full"},
@ -1049,6 +1087,18 @@ static struct error_info additional[] =
{0x7304, "Program memory area update failure"},
{0x7305, "Program memory area is full"},
{0x7306, "RMA/PMA is almost full"},
{0x7310, "Current power calibration area almost full"},
{0x7311, "Current power calibration area is full"},
{0x7317, "RDZ is full"},
{0x7400, "Security error"},
{0x7401, "Unable to decrypt data"},
{0x7402, "Unencrypted data encountered while decrypting"},
{0x7403, "Incorrect data encryption key"},
{0x7404, "Cryptographic integrity validation failed"},
{0x7405, "Error decrypting data"},
{0x7471, "Logical unit access not authorized"},
{0, NULL}
};

View File

@ -1397,7 +1397,7 @@ static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
sp->SCp.ptr = NULL;
}
} else {
sp->SCp.buffer = (struct scatterlist *) sp->buffer;
sp->SCp.buffer = (struct scatterlist *) sp->request_buffer;
sp->SCp.buffers_residual = sbus_map_sg(esp->sdev,
sp->SCp.buffer,
sp->use_sg,
@ -1410,7 +1410,7 @@ static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
static void esp_release_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
{
if (sp->use_sg) {
sbus_unmap_sg(esp->sdev, sp->buffer, sp->use_sg,
sbus_unmap_sg(esp->sdev, sp->request_buffer, sp->use_sg,
sp->sc_data_direction);
} else if (sp->request_bufflen) {
sbus_unmap_single(esp->sdev,

View File

@ -81,7 +81,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
int rc;
single_host_data = hostdata;
rc = viopath_open(viopath_hostLp, viomajorsubtype_scsi, 0);
rc = viopath_open(viopath_hostLp, viomajorsubtype_scsi, max_requests);
if (rc < 0) {
printk("viopath_open failed with rc %d in open_event_path\n",
rc);

View File

@ -238,6 +238,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
if (rc == 2) {
/* Adapter is good, but other end is not ready */
printk(KERN_WARNING "ibmvscsi: Partner adapter not ready\n");
retrc = 0;
} else if (rc != 0) {
printk(KERN_WARNING "ibmvscsi: Error %d opening adapter\n", rc);
goto reg_crq_failed;

View File

@ -257,7 +257,7 @@ static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
{
int sz = sp->use_sg - 1;
struct scatterlist *sg = (struct scatterlist *)sp->buffer;
struct scatterlist *sg = (struct scatterlist *)sp->request_buffer;
while(sz >= 0) {
vdma_free(sg[sz].dma_address);

View File

@ -21,10 +21,12 @@
struct lpfc_sli2_slim;
#define LPFC_MAX_TARGET 256 /* max targets supported */
#define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els req */
#define LPFC_MAX_NS_RETRY 3 /* max NameServer retries */
#define LPFC_MAX_TARGET 256 /* max number of targets supported */
#define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els
requests */
#define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact
the NameServer before giving up. */
#define LPFC_DFT_HBA_Q_DEPTH 2048 /* max cmds per hba */
#define LPFC_LC_HBA_Q_DEPTH 1024 /* max cmds per low cost hba */
#define LPFC_LP101_HBA_Q_DEPTH 128 /* max cmds per low cost hba */
@ -41,7 +43,6 @@ struct lpfc_sli2_slim;
(( (u64)(high)<<16 ) << 16)|( (u64)(low))))
/* Provide maximum configuration definitions. */
#define LPFC_DRVR_TIMEOUT 16 /* driver iocb timeout value in sec */
#define MAX_FCP_TARGET 256 /* max num of FCP targets supported */
#define FC_MAX_ADPTMSG 64
#define MAX_HBAEVT 32

View File

@ -219,9 +219,19 @@ lpfc_issue_lip(struct Scsi_Host *host)
return -ENOMEM;
memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
lpfc_init_link(phba, pmboxq, phba->cfg_topology, phba->cfg_link_speed);
pmboxq->mb.mbxCommand = MBX_DOWN_LINK;
pmboxq->mb.mbxOwner = OWN_HOST;
mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
if ((mbxstatus == MBX_SUCCESS) && (pmboxq->mb.mbxStatus == 0)) {
memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
lpfc_init_link(phba, pmboxq, phba->cfg_topology,
phba->cfg_link_speed);
mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq,
phba->fc_ratov * 2);
}
if (mbxstatus == MBX_TIMEOUT)
pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
else
@ -233,6 +243,47 @@ lpfc_issue_lip(struct Scsi_Host *host)
return 0;
}
static int
lpfc_selective_reset(struct lpfc_hba *phba)
{
struct completion online_compl;
int status = 0;
init_completion(&online_compl);
lpfc_workq_post_event(phba, &status, &online_compl,
LPFC_EVT_OFFLINE);
wait_for_completion(&online_compl);
if (status != 0)
return -EIO;
init_completion(&online_compl);
lpfc_workq_post_event(phba, &status, &online_compl,
LPFC_EVT_ONLINE);
wait_for_completion(&online_compl);
if (status != 0)
return -EIO;
return 0;
}
static ssize_t
lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count)
{
struct Scsi_Host *host = class_to_shost(cdev);
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
int status = -EINVAL;
if (strncmp(buf, "selective", sizeof("selective") - 1) == 0)
status = lpfc_selective_reset(phba);
if (status == 0)
return strlen(buf);
else
return status;
}
static ssize_t
lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf)
{
@ -241,45 +292,6 @@ lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf)
return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
}
static ssize_t
lpfc_board_online_show(struct class_device *cdev, char *buf)
{
struct Scsi_Host *host = class_to_shost(cdev);
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
if (phba->fc_flag & FC_OFFLINE_MODE)
return snprintf(buf, PAGE_SIZE, "0\n");
else
return snprintf(buf, PAGE_SIZE, "1\n");
}
static ssize_t
lpfc_board_online_store(struct class_device *cdev, const char *buf,
size_t count)
{
struct Scsi_Host *host = class_to_shost(cdev);
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
struct completion online_compl;
int val=0, status=0;
if (sscanf(buf, "%d", &val) != 1)
return -EINVAL;
init_completion(&online_compl);
if (val)
lpfc_workq_post_event(phba, &status, &online_compl,
LPFC_EVT_ONLINE);
else
lpfc_workq_post_event(phba, &status, &online_compl,
LPFC_EVT_OFFLINE);
wait_for_completion(&online_compl);
if (!status)
return strlen(buf);
else
return -EIO;
}
static ssize_t
lpfc_board_mode_show(struct class_device *cdev, char *buf)
{
@ -532,10 +544,9 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,
NULL);
static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
NULL);
static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
lpfc_board_online_show, lpfc_board_online_store);
static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
lpfc_board_mode_show, lpfc_board_mode_store);
static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);
static int lpfc_poll = 0;
module_param(lpfc_poll, int, 0);
@ -695,12 +706,12 @@ LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
"during discovery");
/*
# lpfc_max_luns: maximum number of LUNs per target driver will support
# Value range is [1,32768]. Default value is 256.
# NOTE: The SCSI layer will scan each target for this many luns
# lpfc_max_luns: maximum allowed LUN.
# Value range is [0,65535]. Default value is 255.
# NOTE: The SCSI layer might probe all allowed LUN on some old targets.
*/
LPFC_ATTR_R(max_luns, 256, 1, 32768,
"Maximum number of LUNs per target driver will support");
LPFC_ATTR_R(max_luns, 255, 0, 65535,
"Maximum allowed LUN");
/*
# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
@ -739,8 +750,8 @@ struct class_device_attribute *lpfc_host_attrs[] = {
&class_device_attr_lpfc_max_luns,
&class_device_attr_nport_evt_cnt,
&class_device_attr_management_version,
&class_device_attr_board_online,
&class_device_attr_board_mode,
&class_device_attr_issue_reset,
&class_device_attr_lpfc_poll,
&class_device_attr_lpfc_poll_tmo,
NULL,

View File

@ -147,6 +147,7 @@ int lpfc_sli_hba_setup(struct lpfc_hba *);
int lpfc_sli_hba_down(struct lpfc_hba *);
int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
int lpfc_sli_handle_mb_event(struct lpfc_hba *);
int lpfc_sli_flush_mbox_queue(struct lpfc_hba *);
int lpfc_sli_handle_slow_ring_event(struct lpfc_hba *,
struct lpfc_sli_ring *, uint32_t);
void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);

View File

@ -648,33 +648,32 @@ lpfc_more_plogi(struct lpfc_hba * phba)
}
static struct lpfc_nodelist *
lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp,
struct lpfc_nodelist *ndlp)
{
struct lpfc_nodelist *new_ndlp;
struct lpfc_dmabuf *pcmd, *prsp;
uint32_t *lp;
struct serv_parm *sp;
uint8_t name[sizeof (struct lpfc_name)];
uint32_t rc;
pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
prsp = (struct lpfc_dmabuf *) pcmd->list.next;
lp = (uint32_t *) prsp->virt;
sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
memset(name, 0, sizeof (struct lpfc_name));
/* Now we to find out if the NPort we are logging into, matches the WWPN
* we have for that ndlp. If not, we have some work to do.
*/
new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName);
memset(name, 0, sizeof (struct lpfc_name));
rc = memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name));
if (!rc || (new_ndlp == ndlp)) {
if (new_ndlp == ndlp)
return ndlp;
}
if (!new_ndlp) {
rc =
memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name));
if (!rc)
return ndlp;
new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
if (!new_ndlp)
return ndlp;
@ -683,17 +682,21 @@ lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
}
lpfc_unreg_rpi(phba, new_ndlp);
new_ndlp->nlp_prev_state = ndlp->nlp_state;
new_ndlp->nlp_DID = ndlp->nlp_DID;
new_ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
lpfc_nlp_list(phba, new_ndlp, NLP_PLOGI_LIST);
new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
new_ndlp->nlp_state = ndlp->nlp_state;
lpfc_nlp_list(phba, new_ndlp, ndlp->nlp_flag & NLP_LIST_MASK);
/* Move this back to NPR list */
lpfc_unreg_rpi(phba, ndlp);
ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
ndlp->nlp_state = NLP_STE_NPR_NODE;
lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) {
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
}
else {
lpfc_unreg_rpi(phba, ndlp);
ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
ndlp->nlp_state = NLP_STE_NPR_NODE;
lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
}
return new_ndlp;
}
@ -703,6 +706,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
{
IOCB_t *irsp;
struct lpfc_nodelist *ndlp;
struct lpfc_dmabuf *prsp;
int disc, rc, did, type;
@ -769,7 +773,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
}
} else {
/* Good status, call state machine */
ndlp = lpfc_plogi_confirm_nport(phba, cmdiocb, ndlp);
prsp = list_entry(((struct lpfc_dmabuf *)
cmdiocb->context2)->list.next,
struct lpfc_dmabuf, list);
ndlp = lpfc_plogi_confirm_nport(phba, prsp, ndlp);
rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb,
NLP_EVT_CMPL_PLOGI);
}
@ -3282,10 +3289,9 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
} else
lpfc_sli_release_iocbq(phba, piocb);
}
if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) {
phba->els_tmofunc.expires = jiffies + HZ * timeout;
add_timer(&phba->els_tmofunc);
}
if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt)
mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout);
spin_unlock_irq(phba->host->host_lock);
}
@ -3442,6 +3448,8 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) {
ndlp->nlp_type |= NLP_FABRIC;
}
ndlp->nlp_state = NLP_STE_UNUSED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
}
phba->fc_stat.elsRcvFrame++;
@ -3463,13 +3471,14 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
rjt_err = 1;
break;
}
ndlp = lpfc_plogi_confirm_nport(phba, mp, ndlp);
lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI);
break;
case ELS_CMD_FLOGI:
phba->fc_stat.elsRcvFLOGI++;
lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode);
if (newnode) {
mempool_free( ndlp, phba->nlp_mem_pool);
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
}
break;
case ELS_CMD_LOGO:
@ -3492,7 +3501,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
phba->fc_stat.elsRcvRSCN++;
lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode);
if (newnode) {
mempool_free( ndlp, phba->nlp_mem_pool);
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
}
break;
case ELS_CMD_ADISC:
@ -3535,28 +3544,28 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
phba->fc_stat.elsRcvLIRR++;
lpfc_els_rcv_lirr(phba, elsiocb, ndlp);
if (newnode) {
mempool_free( ndlp, phba->nlp_mem_pool);
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
}
break;
case ELS_CMD_RPS:
phba->fc_stat.elsRcvRPS++;
lpfc_els_rcv_rps(phba, elsiocb, ndlp);
if (newnode) {
mempool_free( ndlp, phba->nlp_mem_pool);
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
}
break;
case ELS_CMD_RPL:
phba->fc_stat.elsRcvRPL++;
lpfc_els_rcv_rpl(phba, elsiocb, ndlp);
if (newnode) {
mempool_free( ndlp, phba->nlp_mem_pool);
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
}
break;
case ELS_CMD_RNID:
phba->fc_stat.elsRcvRNID++;
lpfc_els_rcv_rnid(phba, elsiocb, ndlp);
if (newnode) {
mempool_free( ndlp, phba->nlp_mem_pool);
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
}
break;
default:
@ -3568,7 +3577,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
"%d:0115 Unknown ELS command x%x received from "
"NPORT x%x\n", phba->brd_no, cmd, did);
if (newnode) {
mempool_free( ndlp, phba->nlp_mem_pool);
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
}
break;
}

View File

@ -1084,7 +1084,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
fc_remote_port_rolechg(rport, rport_ids.roles);
if ((rport->scsi_target_id != -1) &&
(rport->scsi_target_id < MAX_FCP_TARGET)) {
(rport->scsi_target_id < LPFC_MAX_TARGET)) {
ndlp->nlp_sid = rport->scsi_target_id;
}
@ -1313,7 +1313,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
if ((rport_add == mapped) &&
((!nlp->rport) ||
(nlp->rport->scsi_target_id == -1) ||
(nlp->rport->scsi_target_id >= MAX_FCP_TARGET))) {
(nlp->rport->scsi_target_id >= LPFC_MAX_TARGET))) {
nlp->nlp_state = NLP_STE_UNMAPPED_NODE;
spin_lock_irq(phba->host->host_lock);
nlp->nlp_flag |= NLP_TGT_NO_SCSIID;

View File

@ -71,6 +71,7 @@ lpfc_config_port_prep(struct lpfc_hba * phba)
uint16_t offset = 0;
static char licensed[56] =
"key unlock for use with gnu public licensed code only\0";
static int init_key = 1;
pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!pmb) {
@ -82,10 +83,13 @@ lpfc_config_port_prep(struct lpfc_hba * phba)
phba->hba_state = LPFC_INIT_MBX_CMDS;
if (lpfc_is_LC_HBA(phba->pcidev->device)) {
uint32_t *ptext = (uint32_t *) licensed;
if (init_key) {
uint32_t *ptext = (uint32_t *) licensed;
for (i = 0; i < 56; i += sizeof (uint32_t), ptext++)
*ptext = cpu_to_be32(*ptext);
for (i = 0; i < 56; i += sizeof (uint32_t), ptext++)
*ptext = cpu_to_be32(*ptext);
init_key = 0;
}
lpfc_read_nv(phba, pmb);
memset((char*)mb->un.varRDnvp.rsvd3, 0,
@ -405,19 +409,26 @@ lpfc_config_port_post(struct lpfc_hba * phba)
}
/* MBOX buffer will be freed in mbox compl */
i = 0;
return (0);
}
static int
lpfc_discovery_wait(struct lpfc_hba *phba)
{
int i = 0;
while ((phba->hba_state != LPFC_HBA_READY) ||
(phba->num_disc_nodes) || (phba->fc_prli_sent) ||
((phba->fc_map_cnt == 0) && (i<2)) ||
(psli->sli_flag & LPFC_SLI_MBOX_ACTIVE)) {
(phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE)) {
/* Check every second for 30 retries. */
i++;
if (i > 30) {
break;
return -ETIMEDOUT;
}
if ((i >= 15) && (phba->hba_state <= LPFC_LINK_DOWN)) {
/* The link is down. Set linkdown timeout */
break;
return -ETIMEDOUT;
}
/* Delay for 1 second to give discovery time to complete. */
@ -425,12 +436,7 @@ lpfc_config_port_post(struct lpfc_hba * phba)
}
/* Since num_disc_nodes keys off of PLOGI, delay a bit to let
* any potential PRLIs to flush thru the SLI sub-system.
*/
msleep(50);
return (0);
return 0;
}
/************************************************************************/
@ -1339,7 +1345,8 @@ lpfc_offline(struct lpfc_hba * phba)
struct lpfc_sli_ring *pring;
struct lpfc_sli *psli;
unsigned long iflag;
int i = 0;
int i;
int cnt = 0;
if (!phba)
return 0;
@ -1348,17 +1355,27 @@ lpfc_offline(struct lpfc_hba * phba)
return 0;
psli = &phba->sli;
pring = &psli->ring[psli->fcp_ring];
lpfc_linkdown(phba);
lpfc_sli_flush_mbox_queue(phba);
/* The linkdown event takes 30 seconds to timeout. */
while (pring->txcmplq_cnt) {
mdelay(10);
if (i++ > 3000)
break;
for (i = 0; i < psli->num_rings; i++) {
pring = &psli->ring[i];
/* The linkdown event takes 30 seconds to timeout. */
while (pring->txcmplq_cnt) {
mdelay(10);
if (cnt++ > 3000) {
lpfc_printf_log(phba,
KERN_WARNING, LOG_INIT,
"%d:0466 Outstanding IO when "
"bringing Adapter offline\n",
phba->brd_no);
break;
}
}
}
/* stop all timers associated with this hba */
lpfc_stop_timer(phba);
phba->work_hba_events = 0;
@ -1639,6 +1656,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
goto out_free_irq;
}
lpfc_discovery_wait(phba);
if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
spin_lock_irq(phba->host->host_lock);
lpfc_poll_start_timer(phba);

View File

@ -133,6 +133,11 @@ lpfc_mem_free(struct lpfc_hba * phba)
pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
pci_pool_destroy(phba->lpfc_mbuf_pool);
/* Free the iocb lookup array */
kfree(psli->iocbq_lookup);
psli->iocbq_lookup = NULL;
}
void *

View File

@ -1110,6 +1110,17 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,
phba->brd_no,
did, mb->mbxStatus, phba->hba_state);
/*
* If RegLogin failed due to lack of HBA resources do not
* retry discovery.
*/
if (mb->mbxStatus == MBXERR_RPI_FULL) {
ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
ndlp->nlp_state = NLP_STE_UNUSED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
return ndlp->nlp_state;
}
/* Put ndlp in npr list set plogi timer for 1 sec */
mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
spin_lock_irq(phba->host->host_lock);

View File

@ -153,22 +153,6 @@ static void
lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
{
unsigned long iflag = 0;
/*
* There are only two special cases to consider. (1) the scsi command
* requested scatter-gather usage or (2) the scsi command allocated
* a request buffer, but did not request use_sg. There is a third
* case, but it does not require resource deallocation.
*/
if ((psb->seg_cnt > 0) && (psb->pCmd->use_sg)) {
dma_unmap_sg(&phba->pcidev->dev, psb->pCmd->request_buffer,
psb->seg_cnt, psb->pCmd->sc_data_direction);
} else {
if ((psb->nonsg_phys) && (psb->pCmd->request_bufflen)) {
dma_unmap_single(&phba->pcidev->dev, psb->nonsg_phys,
psb->pCmd->request_bufflen,
psb->pCmd->sc_data_direction);
}
}
spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
psb->pCmd = NULL;
@ -281,6 +265,27 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd)
return 0;
}
static void
lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
{
/*
* There are only two special cases to consider. (1) the scsi command
* requested scatter-gather usage or (2) the scsi command allocated
* a request buffer, but did not request use_sg. There is a third
* case, but it does not require resource deallocation.
*/
if ((psb->seg_cnt > 0) && (psb->pCmd->use_sg)) {
dma_unmap_sg(&phba->pcidev->dev, psb->pCmd->request_buffer,
psb->seg_cnt, psb->pCmd->sc_data_direction);
} else {
if ((psb->nonsg_phys) && (psb->pCmd->request_bufflen)) {
dma_unmap_single(&phba->pcidev->dev, psb->nonsg_phys,
psb->pCmd->request_bufflen,
psb->pCmd->sc_data_direction);
}
}
}
static void
lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd)
{
@ -454,6 +459,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
cmd->scsi_done(cmd);
if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
lpfc_release_scsi_buf(phba, lpfc_cmd);
return;
}
@ -511,6 +517,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
}
}
lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
lpfc_release_scsi_buf(phba, lpfc_cmd);
}
@ -609,6 +616,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd,
static int
lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
struct lpfc_scsi_buf *lpfc_cmd,
unsigned int lun,
uint8_t task_mgmt_cmd)
{
struct lpfc_sli *psli;
@ -627,8 +635,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
piocb = &piocbq->iocb;
fcp_cmnd = lpfc_cmd->fcp_cmnd;
int_to_scsilun(lpfc_cmd->pCmd->device->lun,
&lpfc_cmd->fcp_cmnd->fcp_lun);
int_to_scsilun(lun, &lpfc_cmd->fcp_cmnd->fcp_lun);
fcp_cmnd->fcpCntl2 = task_mgmt_cmd;
piocb->ulpCommand = CMD_FCP_ICMND64_CR;
@ -655,14 +662,16 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
static int
lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba,
unsigned tgt_id, struct lpfc_rport_data *rdata)
unsigned tgt_id, unsigned int lun,
struct lpfc_rport_data *rdata)
{
struct lpfc_iocbq *iocbq;
struct lpfc_iocbq *iocbqrsp;
int ret;
lpfc_cmd->rdata = rdata;
ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET);
ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun,
FCP_TARGET_RESET);
if (!ret)
return FAILED;
@ -822,6 +831,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
return 0;
out_host_busy_free_buf:
lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
lpfc_release_scsi_buf(phba, lpfc_cmd);
out_host_busy:
return SCSI_MLQUEUE_HOST_BUSY;
@ -969,12 +979,12 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
if (lpfc_cmd == NULL)
goto out;
lpfc_cmd->pCmd = cmnd;
lpfc_cmd->timeout = 60;
lpfc_cmd->scsi_hba = phba;
lpfc_cmd->rdata = rdata;
ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_LUN_RESET);
ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, cmnd->device->lun,
FCP_LUN_RESET);
if (!ret)
goto out_free_scsi_buf;
@ -1001,7 +1011,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
cmd_status = iocbqrsp->iocb.ulpStatus;
lpfc_sli_release_iocbq(phba, iocbqrsp);
lpfc_release_scsi_buf(phba, lpfc_cmd);
/*
* All outstanding txcmplq I/Os should have been aborted by the device.
@ -1040,6 +1049,8 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
}
out_free_scsi_buf:
lpfc_release_scsi_buf(phba, lpfc_cmd);
lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
"%d:0713 SCSI layer issued LUN reset (%d, %d) "
"Data: x%x x%x x%x\n",
@ -1070,7 +1081,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
/* The lpfc_cmd storage is reused. Set all loop invariants. */
lpfc_cmd->timeout = 60;
lpfc_cmd->pCmd = cmnd;
lpfc_cmd->scsi_hba = phba;
/*
@ -1078,7 +1088,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
* targets known to the driver. Should any target reset
* fail, this routine returns failure to the midlayer.
*/
for (i = 0; i < MAX_FCP_TARGET; i++) {
for (i = 0; i < LPFC_MAX_TARGET; i++) {
/* Search the mapped list for this target ID */
match = 0;
list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
@ -1090,8 +1100,8 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
if (!match)
continue;
ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba,
i, ndlp->rport->dd_data);
ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, i, cmnd->device->lun,
ndlp->rport->dd_data);
if (ret != SUCCESS) {
lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
"%d:0713 Bus Reset on target %d failed\n",

View File

@ -191,35 +191,12 @@ static int
lpfc_sli_ringtxcmpl_put(struct lpfc_hba * phba,
struct lpfc_sli_ring * pring, struct lpfc_iocbq * piocb)
{
uint16_t iotag;
list_add_tail(&piocb->list, &pring->txcmplq);
pring->txcmplq_cnt++;
if (unlikely(pring->ringno == LPFC_ELS_RING))
mod_timer(&phba->els_tmofunc,
jiffies + HZ * (phba->fc_ratov << 1));
if (pring->fast_lookup) {
/* Setup fast lookup based on iotag for completion */
iotag = piocb->iocb.ulpIoTag;
if (iotag && (iotag < pring->fast_iotag))
*(pring->fast_lookup + iotag) = piocb;
else {
/* Cmd ring <ringno> put: iotag <iotag> greater then
configured max <fast_iotag> wd0 <icmd> */
lpfc_printf_log(phba,
KERN_ERR,
LOG_SLI,
"%d:0316 Cmd ring %d put: iotag x%x "
"greater then configured max x%x "
"wd0 x%x\n",
phba->brd_no,
pring->ringno, iotag,
pring->fast_iotag,
*(((uint32_t *)(&piocb->iocb)) + 7));
}
}
return (0);
}
@ -601,7 +578,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba)
/* Stray Mailbox Interrupt, mbxCommand <cmd> mbxStatus
<status> */
lpfc_printf_log(phba,
KERN_ERR,
KERN_WARNING,
LOG_MBOX | LOG_SLI,
"%d:0304 Stray Mailbox Interrupt "
"mbxCommand x%x mbxStatus x%x\n",
@ -1570,8 +1547,8 @@ lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask)
void lpfc_reset_barrier(struct lpfc_hba * phba)
{
uint32_t * resp_buf;
uint32_t * mbox_buf;
uint32_t __iomem *resp_buf;
uint32_t __iomem *mbox_buf;
volatile uint32_t mbox;
uint32_t hc_copy;
int i;
@ -1587,7 +1564,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba)
* Tell the other part of the chip to suspend temporarily all
* its DMA activity.
*/
resp_buf = (uint32_t *)phba->MBslimaddr;
resp_buf = phba->MBslimaddr;
/* Disable the error attention */
hc_copy = readl(phba->HCregaddr);
@ -1605,7 +1582,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba)
((MAILBOX_t *)&mbox)->mbxOwner = OWN_CHIP;
writel(BARRIER_TEST_PATTERN, (resp_buf + 1));
mbox_buf = (uint32_t *)phba->MBslimaddr;
mbox_buf = phba->MBslimaddr;
writel(mbox, mbox_buf);
for (i = 0;
@ -1805,7 +1782,7 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba)
skip_post = 0;
word0 = 0; /* This is really setting up word1 */
}
to_slim = (uint8_t *) phba->MBslimaddr + sizeof (uint32_t);
to_slim = phba->MBslimaddr + sizeof (uint32_t);
writel(*(uint32_t *) mb, to_slim);
readl(to_slim); /* flush */
@ -2659,8 +2636,6 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
INIT_LIST_HEAD(&(pring->txq));
kfree(pring->fast_lookup);
pring->fast_lookup = NULL;
}
spin_unlock_irqrestore(phba->host->host_lock, flags);
@ -3110,6 +3085,24 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
return retval;
}
int
lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba)
{
int i = 0;
while (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE && !phba->stopped) {
if (i++ > LPFC_MBOX_TMO * 1000)
return 1;
if (lpfc_sli_handle_mb_event(phba) == 0)
i = 0;
msleep(1);
}
return (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) ? 1 : 0;
}
irqreturn_t
lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs)
{

View File

@ -135,8 +135,6 @@ struct lpfc_sli_ring {
uint32_t fast_iotag; /* max fastlookup based iotag */
uint32_t iotag_ctr; /* keeps track of the next iotag to use */
uint32_t iotag_max; /* max iotag value to use */
struct lpfc_iocbq ** fast_lookup; /* array of IOCB ptrs indexed by
iotag */
struct list_head txq;
uint16_t txq_cnt; /* current length of queue */
uint16_t txq_max; /* max length */

View File

@ -18,7 +18,7 @@
* included with this package. *
*******************************************************************/
#define LPFC_DRIVER_VERSION "8.1.6"
#define LPFC_DRIVER_VERSION "8.1.7"
#define LPFC_DRIVER_NAME "lpfc"

View File

@ -378,7 +378,7 @@ static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd)
int nseg;
total = 0;
scl = (struct scatterlist *) cmd->buffer;
scl = (struct scatterlist *) cmd->request_buffer;
nseg = pci_map_sg(state->pdev, scl, cmd->use_sg,
cmd->sc_data_direction);
for (i = 0; i < nseg; ++i) {

View File

@ -1268,7 +1268,7 @@ static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd)
if (cmd->use_sg > 0) {
int nseg;
total = 0;
scl = (struct scatterlist *) cmd->buffer;
scl = (struct scatterlist *) cmd->request_buffer;
off = ms->data_ptr;
nseg = pci_map_sg(ms->pdev, scl, cmd->use_sg,
cmd->sc_data_direction);

View File

@ -169,8 +169,6 @@ int __init pluto_detect(struct scsi_host_template *tpnt)
SCpnt->request->rq_status = RQ_SCSI_BUSY;
SCpnt->done = pluto_detect_done;
SCpnt->bufflen = 256;
SCpnt->buffer = fcs[i].inquiry;
SCpnt->request_bufflen = 256;
SCpnt->request_buffer = fcs[i].inquiry;
PLD(("set up %d %08lx\n", i, (long)SCpnt))

View File

@ -874,7 +874,7 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
if (Cmnd->use_sg) {
int sg_count;
sg = (struct scatterlist *) Cmnd->buffer;
sg = (struct scatterlist *) Cmnd->request_buffer;
sg_count = sbus_map_sg(qpti->sdev, sg, Cmnd->use_sg, Cmnd->sc_data_direction);
ds = cmd->dataseg;
@ -1278,7 +1278,7 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti)
if (Cmnd->use_sg) {
sbus_unmap_sg(qpti->sdev,
(struct scatterlist *)Cmnd->buffer,
(struct scatterlist *)Cmnd->request_buffer,
Cmnd->use_sg,
Cmnd->sc_data_direction);
} else {

View File

@ -346,7 +346,7 @@ void scsi_log_send(struct scsi_cmnd *cmd)
if (level > 3) {
printk(KERN_INFO "buffer = 0x%p, bufflen = %d,"
" done = 0x%p, queuecommand 0x%p\n",
cmd->buffer, cmd->bufflen,
cmd->request_buffer, cmd->request_bufflen,
cmd->done,
sdev->host->hostt->queuecommand);
@ -661,11 +661,6 @@ void __scsi_done(struct scsi_cmnd *cmd)
*/
int scsi_retry_command(struct scsi_cmnd *cmd)
{
/*
* Restore the SCSI command state.
*/
scsi_setup_cmd_retry(cmd);
/*
* Zero the sense information from the last time we tried
* this command.
@ -711,10 +706,6 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
"Notifying upper driver of completion "
"(result %x)\n", cmd->result));
/*
* We can get here with use_sg=0, causing a panic in the upper level
*/
cmd->use_sg = cmd->old_use_sg;
cmd->done(cmd);
}
EXPORT_SYMBOL(scsi_finish_command);

View File

@ -286,7 +286,7 @@ static int inquiry_evpd_83(unsigned char * arr, int target_dev_id,
int dev_id_num, const char * dev_id_str,
int dev_id_str_len);
static int inquiry_evpd_88(unsigned char * arr, int target_dev_id);
static void do_create_driverfs_files(void);
static int do_create_driverfs_files(void);
static void do_remove_driverfs_files(void);
static int sdebug_add_adapter(void);
@ -2487,19 +2487,22 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp,
DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show,
sdebug_add_host_store);
static void do_create_driverfs_files(void)
static int do_create_driverfs_files(void)
{
driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
int ret;
ret = driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
return ret;
}
static void do_remove_driverfs_files(void)
@ -2522,6 +2525,7 @@ static int __init scsi_debug_init(void)
unsigned int sz;
int host_to_add;
int k;
int ret;
if (scsi_debug_dev_size_mb < 1)
scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */
@ -2560,12 +2564,32 @@ static int __init scsi_debug_init(void)
if (scsi_debug_num_parts > 0)
sdebug_build_parts(fake_storep);
init_all_queued();
ret = device_register(&pseudo_primary);
if (ret < 0) {
printk(KERN_WARNING "scsi_debug: device_register error: %d\n",
ret);
goto free_vm;
}
ret = bus_register(&pseudo_lld_bus);
if (ret < 0) {
printk(KERN_WARNING "scsi_debug: bus_register error: %d\n",
ret);
goto dev_unreg;
}
ret = driver_register(&sdebug_driverfs_driver);
if (ret < 0) {
printk(KERN_WARNING "scsi_debug: driver_register error: %d\n",
ret);
goto bus_unreg;
}
ret = do_create_driverfs_files();
if (ret < 0) {
printk(KERN_WARNING "scsi_debug: driver_create_file error: %d\n",
ret);
goto del_files;
}
device_register(&pseudo_primary);
bus_register(&pseudo_lld_bus);
driver_register(&sdebug_driverfs_driver);
do_create_driverfs_files();
init_all_queued();
sdebug_driver_template.proc_name = (char *)sdebug_proc_name;
@ -2585,6 +2609,18 @@ static int __init scsi_debug_init(void)
scsi_debug_add_host);
}
return 0;
del_files:
do_remove_driverfs_files();
driver_unregister(&sdebug_driverfs_driver);
bus_unreg:
bus_unregister(&pseudo_lld_bus);
dev_unreg:
device_unregister(&pseudo_primary);
free_vm:
vfree(fake_storep);
return ret;
}
static void __exit scsi_debug_exit(void)

View File

@ -460,19 +460,67 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
* Return value:
* SUCCESS or FAILED or NEEDS_RETRY
**/
static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout, int copy_sense)
{
struct scsi_device *sdev = scmd->device;
struct Scsi_Host *shost = sdev->host;
int old_result = scmd->result;
DECLARE_COMPLETION(done);
unsigned long timeleft;
unsigned long flags;
unsigned char old_cmnd[MAX_COMMAND_SIZE];
enum dma_data_direction old_data_direction;
unsigned short old_use_sg;
unsigned char old_cmd_len;
unsigned old_bufflen;
void *old_buffer;
int rtn;
/*
* We need saved copies of a number of fields - this is because
* error handling may need to overwrite these with different values
* to run different commands, and once error handling is complete,
* we will need to restore these values prior to running the actual
* command.
*/
old_buffer = scmd->request_buffer;
old_bufflen = scmd->request_bufflen;
memcpy(old_cmnd, scmd->cmnd, sizeof(scmd->cmnd));
old_data_direction = scmd->sc_data_direction;
old_cmd_len = scmd->cmd_len;
old_use_sg = scmd->use_sg;
if (copy_sense) {
int gfp_mask = GFP_ATOMIC;
if (shost->hostt->unchecked_isa_dma)
gfp_mask |= __GFP_DMA;
scmd->sc_data_direction = DMA_FROM_DEVICE;
scmd->request_bufflen = 252;
scmd->request_buffer = kzalloc(scmd->request_bufflen, gfp_mask);
if (!scmd->request_buffer)
return FAILED;
} else {
scmd->request_buffer = NULL;
scmd->request_bufflen = 0;
scmd->sc_data_direction = DMA_NONE;
}
scmd->underflow = 0;
scmd->use_sg = 0;
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
if (sdev->scsi_level <= SCSI_2)
scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
(sdev->lun << 5 & 0xe0);
/*
* Zero the sense buffer. The scsi spec mandates that any
* untransferred sense data should be interpreted as being zero.
*/
memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
shost->eh_action = &done;
spin_lock_irqsave(shost->host_lock, flags);
@ -522,6 +570,29 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
rtn = FAILED;
}
/*
* Last chance to have valid sense data.
*/
if (copy_sense) {
if (!SCSI_SENSE_VALID(scmd)) {
memcpy(scmd->sense_buffer, scmd->request_buffer,
sizeof(scmd->sense_buffer));
}
kfree(scmd->request_buffer);
}
/*
* Restore original data
*/
scmd->request_buffer = old_buffer;
scmd->request_bufflen = old_bufflen;
memcpy(scmd->cmnd, old_cmnd, sizeof(scmd->cmnd));
scmd->sc_data_direction = old_data_direction;
scmd->cmd_len = old_cmd_len;
scmd->use_sg = old_use_sg;
scmd->result = old_result;
return rtn;
}
@ -537,56 +608,10 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
static int scsi_request_sense(struct scsi_cmnd *scmd)
{
static unsigned char generic_sense[6] =
{REQUEST_SENSE, 0, 0, 0, 252, 0};
unsigned char *scsi_result;
int saved_result;
int rtn;
{REQUEST_SENSE, 0, 0, 0, 252, 0};
memcpy(scmd->cmnd, generic_sense, sizeof(generic_sense));
scsi_result = kmalloc(252, GFP_ATOMIC | ((scmd->device->host->hostt->unchecked_isa_dma) ? __GFP_DMA : 0));
if (unlikely(!scsi_result)) {
printk(KERN_ERR "%s: cannot allocate scsi_result.\n",
__FUNCTION__);
return FAILED;
}
/*
* zero the sense buffer. some host adapters automatically always
* request sense, so it is not a good idea that
* scmd->request_buffer and scmd->sense_buffer point to the same
* address (db). 0 is not a valid sense code.
*/
memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
memset(scsi_result, 0, 252);
saved_result = scmd->result;
scmd->request_buffer = scsi_result;
scmd->request_bufflen = 252;
scmd->use_sg = 0;
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
scmd->sc_data_direction = DMA_FROM_DEVICE;
scmd->underflow = 0;
rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT);
/* last chance to have valid sense data */
if(!SCSI_SENSE_VALID(scmd)) {
memcpy(scmd->sense_buffer, scmd->request_buffer,
sizeof(scmd->sense_buffer));
}
kfree(scsi_result);
/*
* when we eventually call scsi_finish, we really wish to complete
* the original request, so let's restore the original data. (db)
*/
scsi_setup_cmd_retry(scmd);
scmd->result = saved_result;
return rtn;
return scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 1);
}
/**
@ -605,12 +630,6 @@ void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)
{
scmd->device->host->host_failed--;
scmd->eh_eflags = 0;
/*
* set this back so that the upper level can correctly free up
* things.
*/
scsi_setup_cmd_retry(scmd);
list_move_tail(&scmd->eh_entry, done_q);
}
EXPORT_SYMBOL(scsi_eh_finish_cmd);
@ -715,47 +734,26 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd)
{
static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
int retry_cnt = 1, rtn;
int saved_result;
retry_tur:
memcpy(scmd->cmnd, tur_command, sizeof(tur_command));
/*
* zero the sense buffer. the scsi spec mandates that any
* untransferred sense data should be interpreted as being zero.
*/
memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
saved_result = scmd->result;
scmd->request_buffer = NULL;
scmd->request_bufflen = 0;
scmd->use_sg = 0;
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
scmd->underflow = 0;
scmd->sc_data_direction = DMA_NONE;
rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 0);
rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT);
/*
* when we eventually call scsi_finish, we really wish to complete
* the original request, so let's restore the original data. (db)
*/
scsi_setup_cmd_retry(scmd);
scmd->result = saved_result;
/*
* hey, we are done. let's look to see what happened.
*/
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n",
__FUNCTION__, scmd, rtn));
if (rtn == SUCCESS)
return 0;
else if (rtn == NEEDS_RETRY) {
switch (rtn) {
case NEEDS_RETRY:
if (retry_cnt--)
goto retry_tur;
/*FALLTHRU*/
case SUCCESS:
return 0;
default:
return 1;
}
return 1;
}
/**
@ -837,44 +835,16 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
{
static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0};
int rtn;
int saved_result;
if (!scmd->device->allow_restart)
return 1;
if (scmd->device->allow_restart) {
int rtn;
memcpy(scmd->cmnd, stu_command, sizeof(stu_command));
memcpy(scmd->cmnd, stu_command, sizeof(stu_command));
rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT, 0);
if (rtn == SUCCESS)
return 0;
}
/*
* zero the sense buffer. the scsi spec mandates that any
* untransferred sense data should be interpreted as being zero.
*/
memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
saved_result = scmd->result;
scmd->request_buffer = NULL;
scmd->request_bufflen = 0;
scmd->use_sg = 0;
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
scmd->underflow = 0;
scmd->sc_data_direction = DMA_NONE;
rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT);
/*
* when we eventually call scsi_finish, we really wish to complete
* the original request, so let's restore the original data. (db)
*/
scsi_setup_cmd_retry(scmd);
scmd->result = saved_result;
/*
* hey, we are done. let's look to see what happened.
*/
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n",
__FUNCTION__, scmd, rtn));
if (rtn == SUCCESS)
return 0;
return 1;
}
@ -1684,8 +1654,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
scmd->scsi_done = scsi_reset_provider_done_command;
scmd->done = NULL;
scmd->buffer = NULL;
scmd->bufflen = 0;
scmd->request_buffer = NULL;
scmd->request_bufflen = 0;

View File

@ -436,60 +436,16 @@ EXPORT_SYMBOL_GPL(scsi_execute_async);
*
* Arguments: cmd - command that is ready to be queued.
*
* Returns: Nothing
*
* Notes: This function has the job of initializing a number of
* fields related to error handling. Typically this will
* be called once for each command, as required.
*/
static int scsi_init_cmd_errh(struct scsi_cmnd *cmd)
static void scsi_init_cmd_errh(struct scsi_cmnd *cmd)
{
cmd->serial_number = 0;
memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer);
if (cmd->cmd_len == 0)
cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]);
/*
* We need saved copies of a number of fields - this is because
* error handling may need to overwrite these with different values
* to run different commands, and once error handling is complete,
* we will need to restore these values prior to running the actual
* command.
*/
cmd->old_use_sg = cmd->use_sg;
cmd->old_cmd_len = cmd->cmd_len;
cmd->sc_old_data_direction = cmd->sc_data_direction;
cmd->old_underflow = cmd->underflow;
memcpy(cmd->data_cmnd, cmd->cmnd, sizeof(cmd->cmnd));
cmd->buffer = cmd->request_buffer;
cmd->bufflen = cmd->request_bufflen;
return 1;
}
/*
* Function: scsi_setup_cmd_retry()
*
* Purpose: Restore the command state for a retry
*
* Arguments: cmd - command to be restored
*
* Returns: Nothing
*
* Notes: Immediately prior to retrying a command, we need
* to restore certain fields that we saved above.
*/
void scsi_setup_cmd_retry(struct scsi_cmnd *cmd)
{
memcpy(cmd->cmnd, cmd->data_cmnd, sizeof(cmd->data_cmnd));
cmd->request_buffer = cmd->buffer;
cmd->request_bufflen = cmd->bufflen;
cmd->use_sg = cmd->old_use_sg;
cmd->cmd_len = cmd->old_cmd_len;
cmd->sc_data_direction = cmd->sc_old_data_direction;
cmd->underflow = cmd->old_underflow;
}
void scsi_device_unbusy(struct scsi_device *sdev)
@ -807,22 +763,13 @@ static void scsi_free_sgtable(struct scatterlist *sgl, int index)
*/
static void scsi_release_buffers(struct scsi_cmnd *cmd)
{
struct request *req = cmd->request;
/*
* Free up any indirection buffers we allocated for DMA purposes.
*/
if (cmd->use_sg)
scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
else if (cmd->request_buffer != req->buffer)
kfree(cmd->request_buffer);
/*
* Zero these out. They now point to freed memory, and it is
* dangerous to hang onto the pointers.
*/
cmd->buffer = NULL;
cmd->bufflen = 0;
cmd->request_buffer = NULL;
cmd->request_bufflen = 0;
}
@ -858,7 +805,7 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd)
void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
{
int result = cmd->result;
int this_count = cmd->bufflen;
int this_count = cmd->request_bufflen;
request_queue_t *q = cmd->device->request_queue;
struct request *req = cmd->request;
int clear_errors = 1;
@ -866,28 +813,14 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
int sense_valid = 0;
int sense_deferred = 0;
/*
* Free up any indirection buffers we allocated for DMA purposes.
* For the case of a READ, we need to copy the data out of the
* bounce buffer and into the real buffer.
*/
if (cmd->use_sg)
scsi_free_sgtable(cmd->buffer, cmd->sglist_len);
else if (cmd->buffer != req->buffer) {
if (rq_data_dir(req) == READ) {
unsigned long flags;
char *to = bio_kmap_irq(req->bio, &flags);
memcpy(to, cmd->buffer, cmd->bufflen);
bio_kunmap_irq(to, &flags);
}
kfree(cmd->buffer);
}
scsi_release_buffers(cmd);
if (result) {
sense_valid = scsi_command_normalize_sense(cmd, &sshdr);
if (sense_valid)
sense_deferred = scsi_sense_is_deferred(&sshdr);
}
if (blk_pc_request(req)) { /* SG_IO ioctl from block level */
req->errors = result;
if (result) {
@ -907,15 +840,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
req->data_len = cmd->resid;
}
/*
* Zero these out. They now point to freed memory, and it is
* dangerous to hang onto the pointers.
*/
cmd->buffer = NULL;
cmd->bufflen = 0;
cmd->request_buffer = NULL;
cmd->request_bufflen = 0;
/*
* Next deal with any sectors which we were able to correctly
* handle.
@ -1012,7 +936,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
if (!(req->flags & REQ_QUIET)) {
scmd_printk(KERN_INFO, cmd,
"Volume overflow, CDB: ");
__scsi_print_command(cmd->data_cmnd);
__scsi_print_command(cmd->cmnd);
scsi_print_sense("", cmd);
}
/* See SSC3rXX or current. */
@ -1143,7 +1067,7 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd)
* successfully. Since this is a REQ_BLOCK_PC command the
* caller should check the request's errors value
*/
scsi_io_completion(cmd, cmd->bufflen);
scsi_io_completion(cmd, cmd->request_bufflen);
}
static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)

View File

@ -57,7 +57,6 @@ extern int scsi_eh_scmd_add(struct scsi_cmnd *, int);
/* scsi_lib.c */
extern int scsi_maybe_unblock_host(struct scsi_device *sdev);
extern void scsi_setup_cmd_retry(struct scsi_cmnd *cmd);
extern void scsi_device_unbusy(struct scsi_device *sdev);
extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason);
extern void scsi_next_command(struct scsi_cmnd *cmd);

View File

@ -41,6 +41,7 @@ struct sas_host_attrs {
struct mutex lock;
u32 next_target_id;
u32 next_expander_id;
int next_port_id;
};
#define to_sas_host_attrs(host) ((struct sas_host_attrs *)(host)->shost_data)
@ -146,6 +147,7 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev,
mutex_init(&sas_host->lock);
sas_host->next_target_id = 0;
sas_host->next_expander_id = 0;
sas_host->next_port_id = 0;
return 0;
}
@ -327,7 +329,7 @@ sas_phy_protocol_attr(identify.target_port_protocols,
sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n",
unsigned long long);
sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8);
//sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8);
//sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", int);
sas_phy_linkspeed_attr(negotiated_linkrate);
sas_phy_linkspeed_attr(minimum_linkrate_hw);
sas_phy_linkspeed_attr(minimum_linkrate);
@ -590,6 +592,38 @@ struct sas_port *sas_port_alloc(struct device *parent, int port_id)
}
EXPORT_SYMBOL(sas_port_alloc);
/** sas_port_alloc_num - allocate and initialize a SAS port structure
*
* @parent: parent device
*
* Allocates a SAS port structure and a number to go with it. This
* interface is really for adapters where the port number has no
* meansing, so the sas class should manage them. It will be added to
* the device tree below the device specified by @parent which must be
* either a Scsi_Host or a sas_expander_device.
*
* Returns %NULL on error
*/
struct sas_port *sas_port_alloc_num(struct device *parent)
{
int index;
struct Scsi_Host *shost = dev_to_shost(parent);
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
/* FIXME: use idr for this eventually */
mutex_lock(&sas_host->lock);
if (scsi_is_sas_expander_device(parent)) {
struct sas_rphy *rphy = dev_to_rphy(parent);
struct sas_expander_device *exp = rphy_to_expander_device(rphy);
index = exp->next_port_id++;
} else
index = sas_host->next_port_id++;
mutex_unlock(&sas_host->lock);
return sas_port_alloc(parent, index);
}
EXPORT_SYMBOL(sas_port_alloc_num);
/**
* sas_port_add - add a SAS port to the device hierarchy
*
@ -658,6 +692,13 @@ void sas_port_delete(struct sas_port *port)
}
mutex_unlock(&port->phy_list_mutex);
if (port->is_backlink) {
struct device *parent = port->dev.parent;
sysfs_remove_link(&port->dev.kobj, parent->bus_id);
port->is_backlink = 0;
}
transport_remove_device(dev);
device_del(dev);
transport_destroy_device(dev);
@ -733,6 +774,19 @@ void sas_port_delete_phy(struct sas_port *port, struct sas_phy *phy)
}
EXPORT_SYMBOL(sas_port_delete_phy);
void sas_port_mark_backlink(struct sas_port *port)
{
struct device *parent = port->dev.parent->parent->parent;
if (port->is_backlink)
return;
port->is_backlink = 1;
sysfs_create_link(&port->dev.kobj, &parent->kobj,
parent->bus_id);
}
EXPORT_SYMBOL(sas_port_mark_backlink);
/*
* SAS remote PHY attributes.
*/
@ -1140,7 +1194,7 @@ int sas_rphy_add(struct sas_rphy *rphy)
if (identify->device_type == SAS_END_DEVICE &&
rphy->scsi_target_id != -1) {
scsi_scan_target(&rphy->dev, parent->port_identifier,
scsi_scan_target(&rphy->dev, 0,
rphy->scsi_target_id, ~0, 0);
}
@ -1242,15 +1296,13 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel,
mutex_lock(&sas_host->lock);
list_for_each_entry(rphy, &sas_host->rphy_list, list) {
struct sas_port *parent = dev_to_sas_port(rphy->dev.parent);
if (rphy->identify.device_type != SAS_END_DEVICE ||
rphy->scsi_target_id == -1)
continue;
if ((channel == SCAN_WILD_CARD || channel == parent->port_identifier) &&
if ((channel == SCAN_WILD_CARD || channel == 0) &&
(id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) {
scsi_scan_target(&rphy->dev, parent->port_identifier,
scsi_scan_target(&rphy->dev, 0,
rphy->scsi_target_id, lun, 1);
}
}

View File

@ -502,8 +502,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
SCpnt->cmnd[4] = (unsigned char) this_count;
SCpnt->cmnd[5] = 0;
}
SCpnt->request_bufflen = SCpnt->bufflen =
this_count * sdp->sector_size;
SCpnt->request_bufflen = this_count * sdp->sector_size;
/*
* We shouldn't disconnect in the middle of a sector, so with a dumb

View File

@ -1002,7 +1002,7 @@ static int internal_command (unsigned char target, unsigned char lun,
}
#endif
buffer = (struct scatterlist *) SCint->buffer;
buffer = (struct scatterlist *) SCint->request_buffer;
len = buffer->length;
data = page_address(buffer->page) + buffer->offset;
} else {

View File

@ -360,7 +360,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
"mismatch count %d, bytes %d\n",
size, SCpnt->request_bufflen);
if (SCpnt->request_bufflen > size)
SCpnt->request_bufflen = SCpnt->bufflen = size;
SCpnt->request_bufflen = size;
}
}
@ -387,8 +387,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
if (this_count > 0xffff) {
this_count = 0xffff;
SCpnt->request_bufflen = SCpnt->bufflen =
this_count * s_size;
SCpnt->request_bufflen = this_count * s_size;
}
SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff;

View File

@ -368,7 +368,7 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
if (cmdstatp->have_sense)
__scsi_print_sense("st", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
__scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
} ) /* end DEB */
if (!debugging) { /* Abnormal conditions for tape */
if (!cmdstatp->have_sense)
@ -384,9 +384,8 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
scode != VOLUME_OVERFLOW &&
SRpnt->cmd[0] != MODE_SENSE &&
SRpnt->cmd[0] != TEST_UNIT_READY) {
printk(KERN_WARNING "%s: Error with sense data: ", name);
__scsi_print_sense("st", SRpnt->sense,
SCSI_SENSE_BUFFERSIZE);
__scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
}
}

View File

@ -517,7 +517,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd *cmd)
*/
if (cmd->use_sg) {
cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
cmd->SCp.buffers_residual = cmd->use_sg - 1;
cmd->SCp.ptr = (char *) SGADDR(cmd->SCp.buffer);
cmd->SCp.this_residual = cmd->SCp.buffer->length;

Some files were not shown because too many files have changed in this diff Show More